📄 plist.c
字号:
point->prev = pentry; } else { if (plist->tail) plist->tail->next = pentry; else plist->head = pentry; pentry->prev = plist->tail; plist->tail = pentry; } /* Increment count. */ plist->count++; /* Run hook function. */ if (plist->master->add_hook) (*plist->master->add_hook) (plist); plist->master->recent = plist;}/* Return string of prefix_list_type. */static char *prefix_list_type_str (struct prefix_list_entry *pentry){ switch (pentry->type) { case PREFIX_PERMIT: return "permit"; break; case PREFIX_DENY: return "deny"; break; default: return ""; break; }}intprefix_list_entry_match (struct prefix_list_entry *pentry, struct prefix *p){ int ret; ret = prefix_match (&pentry->prefix, p); if (! ret) return 0; /* In case of le nor ge is specified, exact match is performed. */ if (! pentry->le && ! pentry->ge) { if (pentry->prefix.prefixlen != p->prefixlen) return 0; } else { if (pentry->le) if (p->prefixlen > pentry->le) return 0; if (pentry->ge) if (p->prefixlen < pentry->ge) return 0; } return 1;}enum prefix_list_typeprefix_list_apply (struct prefix_list *plist, void *object){ struct prefix_list_entry *pentry; struct prefix *p; p = (struct prefix *) object; if (plist == NULL) return PREFIX_DENY; if (plist->count == 0) return PREFIX_PERMIT; for (pentry = plist->head; pentry; pentry = pentry->next) { pentry->refcnt++; if (prefix_list_entry_match (pentry, p)) { pentry->hitcnt++; return pentry->type; } } return PREFIX_DENY;}voidprefix_list_print (struct prefix_list *plist){ struct prefix_list_entry *pentry; if (plist == NULL) return; printf ("ip prefix-list %s: %d entries\n", plist->name, plist->count); for (pentry = plist->head; pentry; pentry = pentry->next) { if (pentry->any) printf ("any %s\n", prefix_list_type_str (pentry)); else { struct prefix *p; char buf[BUFSIZ]; p = &pentry->prefix; printf (" seq %d %s %s/%d", pentry->seq, prefix_list_type_str (pentry), inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); if (pentry->ge) printf (" ge %d", pentry->ge); if (pentry->le) printf (" le %d", pentry->le); printf ("\n"); } }}/* Retrun 1 when plist already include pentry policy. */struct prefix_list_entry *prefix_entry_dup_check (struct prefix_list *plist, struct prefix_list_entry *new){ struct prefix_list_entry *pentry; int seq = 0; if (new->seq == -1) seq = prefix_new_seq_get (plist); else seq = new->seq; for (pentry = plist->head; pentry; pentry = pentry->next) { if (prefix_same (&pentry->prefix, &new->prefix) && pentry->type == new->type && pentry->le == new->le && pentry->ge == new->ge && pentry->seq != seq) return pentry; } return NULL;}intvty_invalid_prefix_range (struct vty *vty, char *prefix){ vty_out (vty, "%% Invalid prefix range for %s, make sure: len < ge-value <= le-value%s", prefix, VTY_NEWLINE); return CMD_WARNING;}intvty_prefix_list_install (struct vty *vty, afi_t afi, char *name, char *seq, char *typestr, char *prefix, char *ge, char *le){ int ret; enum prefix_list_type type; struct prefix_list *plist; struct prefix_list_entry *pentry; struct prefix_list_entry *dup; struct prefix p; int any = 0; int seqnum = -1; int lenum = 0; int genum = 0; /* Sequential number. */ if (seq) seqnum = atoi (seq); /* ge and le number */ if (ge) genum = atoi (ge); if (le) lenum = atoi (le); /* Check filter type. */ if (strncmp ("permit", typestr, 1) == 0) type = PREFIX_PERMIT; else if (strncmp ("deny", typestr, 1) == 0) type = PREFIX_DENY; else { vty_out (vty, "%% prefix type must be permit or deny%s", VTY_NEWLINE); return CMD_WARNING; } /* "any" is special token for matching any IPv4 addresses. */ if (afi == AFI_IP) { if (strncmp ("any", prefix, strlen (prefix)) == 0) { ret = str2prefix_ipv4 ("0.0.0.0/0", (struct prefix_ipv4 *) &p); genum = 0; lenum = IPV4_MAX_BITLEN; any = 1; } else ret = str2prefix_ipv4 (prefix, (struct prefix_ipv4 *) &p); if (ret <= 0) { vty_out (vty, "%% Malformed IPv4 prefix%s", VTY_NEWLINE); return CMD_WARNING; } }#ifdef HAVE_IPV6 else if (afi == AFI_IP6) { if (strncmp ("any", prefix, strlen (prefix)) == 0) { ret = str2prefix_ipv6 ("::/0", (struct prefix_ipv6 *) &p); genum = 0; lenum = IPV6_MAX_BITLEN; any = 1; } else ret = str2prefix_ipv6 (prefix, (struct prefix_ipv6 *) &p); if (ret <= 0) { vty_out (vty, "%% Malformed IPv6 prefix%s", VTY_NEWLINE); return CMD_WARNING; } }#endif /* HAVE_IPV6 */ /* ge and le check. */ if (genum && genum <= p.prefixlen) return vty_invalid_prefix_range (vty, prefix); if (lenum && lenum <= p.prefixlen) return vty_invalid_prefix_range (vty, prefix); if (lenum && genum > lenum) return vty_invalid_prefix_range (vty, prefix); if (genum && lenum == (afi == AFI_IP ? 32 : 128)) lenum = 0; /* Get prefix_list with name. */ plist = prefix_list_get (afi, name); /* Make prefix entry. */ pentry = prefix_list_entry_make (&p, type, seqnum, lenum, genum, any); /* Check same policy. */ dup = prefix_entry_dup_check (plist, pentry); if (dup) { prefix_list_entry_free (pentry); vty_out (vty, "%% Insertion failed - prefix-list entry exists:%s", VTY_NEWLINE); vty_out (vty, " seq %d %s %s", dup->seq, typestr, prefix); if (! any && genum) vty_out (vty, " ge %d", genum); if (! any && lenum) vty_out (vty, " le %d", lenum); vty_out (vty, "%s", VTY_NEWLINE); return CMD_WARNING; } /* Install new filter to the access_list. */ prefix_list_entry_add (plist, pentry); return CMD_SUCCESS;}intvty_prefix_list_uninstall (struct vty *vty, afi_t afi, char *name, char *seq, char *typestr, char *prefix, char *ge, char *le){ int ret; enum prefix_list_type type; struct prefix_list *plist; struct prefix_list_entry *pentry; struct prefix p; int seqnum = -1; int lenum = 0; int genum = 0; /* Check prefix list name. */ plist = prefix_list_lookup (afi, name); if (! plist) { vty_out (vty, "%% Can't find specified prefix-list%s", VTY_NEWLINE); return CMD_WARNING; } /* Only prefix-list name specified, delete the entire prefix-list. */ if (seq == NULL && typestr == NULL && prefix == NULL && ge == NULL && le == NULL) { prefix_list_delete (plist); return CMD_SUCCESS; } /* Check sequence number. */ if (seq) seqnum = atoi (seq); /* ge and le number */ if (ge) genum = atoi (ge); if (le) lenum = atoi (le); /* Check of filter type. */ if (strncmp ("permit", typestr, 1) == 0) type = PREFIX_PERMIT; else if (strncmp ("deny", typestr, 1) == 0) type = PREFIX_DENY; else { vty_out (vty, "%% prefix type must be permit or deny%s", VTY_NEWLINE); return CMD_WARNING; } /* "any" is special token for matching any IPv4 addresses. */ if (afi == AFI_IP) { if (strncmp ("any", prefix, strlen (prefix)) == 0) { ret = str2prefix_ipv4 ("0.0.0.0/0", (struct prefix_ipv4 *) &p); genum = 0; lenum = IPV4_MAX_BITLEN; } else ret = str2prefix_ipv4 (prefix, (struct prefix_ipv4 *) &p); if (ret <= 0) { vty_out (vty, "%% Malformed IPv4 prefix%s", VTY_NEWLINE); return CMD_WARNING; } }#ifdef HAVE_IPV6 else if (afi == AFI_IP6) { if (strncmp ("any", prefix, strlen (prefix)) == 0) { ret = str2prefix_ipv6 ("::/0", (struct prefix_ipv6 *) &p); genum = 0; lenum = IPV6_MAX_BITLEN; } else ret = str2prefix_ipv6 (prefix, (struct prefix_ipv6 *) &p); if (ret <= 0) { vty_out (vty, "%% Malformed IPv6 prefix%s", VTY_NEWLINE); return CMD_WARNING; } }#endif /* HAVE_IPV6 */ /* Lookup prefix entry. */ pentry = prefix_list_entry_lookup(plist, &p, type, seqnum, lenum, genum); if (pentry == NULL) { vty_out (vty, "%% Can't find specified prefix-list%s", VTY_NEWLINE); return CMD_WARNING; } /* Install new filter to the access_list. */ prefix_list_entry_delete (plist, pentry, 1); return CMD_SUCCESS;}intvty_prefix_list_desc_unset (struct vty *vty, afi_t afi, char *name){ struct prefix_list *plist; plist = prefix_list_lookup (afi, name); if (! plist) { vty_out (vty, "%% Can't find specified prefix-list%s", VTY_NEWLINE); return CMD_WARNING; } if (plist->desc) { XFREE (MTYPE_TMP, plist->desc); plist->desc = NULL; } if (plist->head == NULL && plist->tail == NULL && plist->desc == NULL) prefix_list_delete (plist); return CMD_SUCCESS;}enum display_type{ normal_display, summary_display, detail_display, sequential_display, longer_display, first_match_display};voidvty_show_prefix_entry (struct vty *vty, afi_t afi, struct prefix_list *plist, struct prefix_master *master, enum display_type dtype, int seqnum){ struct prefix_list_entry *pentry; if (dtype == normal_display) { vty_out (vty, "ip%s prefix-list %s: %d entries%s", afi == AFI_IP ? "" : "v6", plist->name, plist->count, VTY_NEWLINE); if (plist->desc) vty_out (vty, " Description: %s%s", plist->desc, VTY_NEWLINE); } else if (dtype == summary_display || dtype == detail_display) { vty_out (vty, "ip%s prefix-list %s:%s", afi == AFI_IP ? "" : "v6", plist->name, VTY_NEWLINE); if (plist->desc) vty_out (vty, " Description: %s%s", plist->desc, VTY_NEWLINE); vty_out (vty, " count: %d, range entries: %d, sequences: %d - %d%s", plist->count, plist->rangecount, plist->head ? plist->head->seq : 0, plist->tail ? plist->tail->seq : 0, VTY_NEWLINE); } if (dtype != summary_display) { for (pentry = plist->head; pentry; pentry = pentry->next) { if (dtype == sequential_display && pentry->seq != seqnum) continue; vty_out (vty, " "); if (master->seqnum) vty_out (vty, "seq %d ", pentry->seq); vty_out (vty, "%s ", prefix_list_type_str (pentry)); if (pentry->any) vty_out (vty, "any"); else { struct prefix *p = &pentry->prefix; char buf[BUFSIZ]; vty_out (vty, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); if (pentry->ge) vty_out (vty, " ge %d", pentry->ge); if (pentry->le) vty_out (vty, " le %d", pentry->le); } if (dtype == detail_display || dtype == sequential_display) vty_out (vty, " (hit count: %ld, refcount: %ld)", pentry->hitcnt, pentry->refcnt); vty_out (vty, "%s", VTY_NEWLINE); } }}intvty_show_prefix_list (struct vty *vty, afi_t afi, char *name, char *seq, enum display_type dtype)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -