From 57d187bc77f5a07fab335cb0949f3f2e77fc7e6c Mon Sep 17 00:00:00 2001 From: Job Snijders Date: Tue, 15 Nov 2016 19:00:39 +0900 Subject: Support for BGP Large Communities BGP Large Communities are a novel way to signal information between networks. An example of a Large Community is: "2914:65400:38016". Large BGP Communities are composed of three 4-byte integers, separated by a colon. This is easy to remember and accommodates advanced routing policies in relation to 4-Byte ASNs. This feature was developed by: Keyur Patel (Arrcus, Inc.), Job Snijders (NTT Communications), David Lamparter and Donald Sharp Signed-off-by: Job Snijders Signed-off-by: David Lamparter Signed-off-by: Donald Sharp --- bgpd/bgp_routemap.c | 409 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 409 insertions(+) (limited to 'bgpd/bgp_routemap.c') diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 4f7f51fbb..c4b3ddee3 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -52,6 +52,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "bgpd/bgp_filter.h" #include "bgpd/bgp_mplsvpn.h" #include "bgpd/bgp_ecommunity.h" +#include "bgpd/bgp_lcommunity.h" #include "bgpd/bgp_vty.h" #include "bgpd/bgp_debug.h" @@ -84,6 +85,8 @@ o Cisco route-map as-path tag : Not yet automatic-tag : (This will not be implemented by bgpd) community : Done + large-community : Done + large-comm-list : Done comm-list : Not yet dampning : Not yet default : (This will not be implemented by bgpd) @@ -847,6 +850,78 @@ struct route_map_rule_cmd route_match_community_cmd = route_match_community_free }; +/* Match function for lcommunity match. */ +static route_map_result_t +route_match_lcommunity (void *rule, struct prefix *prefix, + route_map_object_t type, void *object) +{ + struct community_list *list; + struct bgp_info *bgp_info; + struct rmap_community *rcom; + + if (type == RMAP_BGP) + { + bgp_info = object; + rcom = rule; + + list = community_list_lookup (bgp_clist, rcom->name, + LARGE_COMMUNITY_LIST_MASTER); + if (! list) + return RMAP_NOMATCH; + + if (bgp_info->attr->extra && + lcommunity_list_match (bgp_info->attr->extra->lcommunity, list)) + return RMAP_MATCH; + + } + return RMAP_NOMATCH; +} + +/* Compile function for community match. */ +static void * +route_match_lcommunity_compile (const char *arg) +{ + struct rmap_community *rcom; + int len; + char *p; + + rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community)); + + p = strchr (arg, ' '); + if (p) + { + len = p - arg; + rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1); + memcpy (rcom->name, arg, len); + } + else + { + rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); + rcom->exact = 0; + } + return rcom; +} + +/* Compile function for community match. */ +static void +route_match_lcommunity_free (void *rule) +{ + struct rmap_community *rcom = rule; + + XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name); + XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom); +} + +/* Route map commands for community matching. */ +struct route_map_rule_cmd route_match_lcommunity_cmd = +{ + "large-community", + route_match_lcommunity, + route_match_lcommunity_compile, + route_match_lcommunity_free +}; + + /* Match function for extcommunity match. */ static route_map_result_t route_match_ecommunity (void *rule, struct prefix *prefix, @@ -1544,6 +1619,225 @@ struct route_map_rule_cmd route_set_community_cmd = route_set_community_free, }; +/* `set community COMMUNITY' */ +struct rmap_lcom_set +{ + struct lcommunity *lcom; + int additive; + int none; +}; + + +/* For lcommunity set mechanism. */ +static route_map_result_t +route_set_lcommunity (void *rule, struct prefix *prefix, + route_map_object_t type, void *object) +{ + struct rmap_lcom_set *rcs; + struct bgp_info *binfo; + struct attr *attr; + struct lcommunity *new = NULL; + struct lcommunity *old; + struct lcommunity *merge; + + if (type == RMAP_BGP) + { + rcs = rule; + binfo = object; + attr = binfo->attr; + old = (attr->extra) ? attr->extra->lcommunity : NULL; + + /* "none" case. */ + if (rcs->none) + { + attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES)); + if (attr->extra) { + attr->extra->lcommunity = NULL; + } + /* See the longer comment down below. */ + if (old && old->refcnt == 0) + lcommunity_free(&old); + return RMAP_OKAY; + } + + if (rcs->additive && old) + { + merge = lcommunity_merge (lcommunity_dup (old), rcs->lcom); + + /* HACK: if the old large-community is not intern'd, + * we should free it here, or all reference to it may be lost. + * Really need to cleanup attribute caching sometime. + */ + if (old->refcnt == 0) + lcommunity_free (&old); + new = lcommunity_uniq_sort (merge); + lcommunity_free (&merge); + } + else + new = lcommunity_dup (rcs->lcom); + + /* will be interned by caller if required */ + if (attr->extra) { + attr->extra->lcommunity = new; + } + attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES); + } + + return RMAP_OKAY; +} + +/* Compile function for set community. */ +static void * +route_set_lcommunity_compile (const char *arg) +{ + struct rmap_lcom_set *rcs; + struct lcommunity *lcom = NULL; + char *sp; + int additive = 0; + int none = 0; + + if (strcmp (arg, "none") == 0) + none = 1; + else + { + sp = strstr (arg, "additive"); + + if (sp && sp > arg) + { + /* "additive" keyworkd is included. */ + additive = 1; + *(sp - 1) = '\0'; + } + + lcom = lcommunity_str2com (arg); + + if (additive) + *(sp - 1) = ' '; + + if (! lcom) + return NULL; + } + + rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set)); + rcs->lcom = lcom; + rcs->additive = additive; + rcs->none = none; + + return rcs; +} + +/* Free function for set lcommunity. */ +static void +route_set_lcommunity_free (void *rule) +{ + struct rmap_lcom_set *rcs = rule; + + if (rcs->lcom) { + lcommunity_free (&rcs->lcom); + } + XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs); +} + +/* Set community rule structure. */ +struct route_map_rule_cmd route_set_lcommunity_cmd = +{ + "large-community", + route_set_lcommunity, + route_set_lcommunity_compile, + route_set_lcommunity_free, +}; + +/* `set large-comm-list (<1-99>|<100-500>|WORD) delete' */ + +/* For large community set mechanism. */ +static route_map_result_t +route_set_lcommunity_delete (void *rule, struct prefix *prefix, + route_map_object_t type, void *object) +{ + struct community_list *list; + struct lcommunity *merge; + struct lcommunity *new; + struct lcommunity *old; + struct bgp_info *binfo; + + if (type == RMAP_BGP) + { + if (! rule) + return RMAP_OKAY; + + binfo = object; + list = community_list_lookup (bgp_clist, rule, + LARGE_COMMUNITY_LIST_MASTER); + old = ((binfo->attr->extra) ? binfo->attr->extra->lcommunity : NULL); + + if (list && old) + { + merge = lcommunity_list_match_delete (lcommunity_dup (old), list); + new = lcommunity_uniq_sort (merge); + lcommunity_free (&merge); + + /* HACK: if the old community is not intern'd, + * we should free it here, or all reference to it may be lost. + * Really need to cleanup attribute caching sometime. + */ + if (old->refcnt == 0) + lcommunity_free (&old); + + if (new->size == 0) + { + binfo->attr->extra->lcommunity = NULL; + binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES); + lcommunity_free (&new); + } + else + { + binfo->attr->extra->lcommunity = new; + binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES); + } + } + } + + return RMAP_OKAY; +} + +/* Compile function for set lcommunity. */ +static void * +route_set_lcommunity_delete_compile (const char *arg) +{ + char *p; + char *str; + int len; + + p = strchr (arg, ' '); + if (p) + { + len = p - arg; + str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1); + memcpy (str, arg, len); + } + else + str = NULL; + + return str; +} + +/* Free function for set lcommunity. */ +static void +route_set_lcommunity_delete_free (void *rule) +{ + XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +} + +/* Set lcommunity rule structure. */ +struct route_map_rule_cmd route_set_lcommunity_delete_cmd = +{ + "large-comm-list", + route_set_lcommunity_delete, + route_set_lcommunity_delete_compile, + route_set_lcommunity_delete_free, +}; + + /* `set comm-list (<1-99>|<100-500>|WORD) delete' */ /* For community set mechanism. */ @@ -3114,7 +3408,32 @@ DEFUN (no_match_community, RMAP_EVENT_CLIST_DELETED); } +DEFUN (match_lcommunity, + match_lcommunity_cmd, + "match large-community [(1-99)|(100-500)|WORD]", + MATCH_STR + "Match BGP large community list\n" + "Large Community-list number (standard)\n" + "Large Community-list number (expanded)\n" + "Large Community-list name\n") +{ + return bgp_route_match_add (vty, "large-community", argv[2]->arg, + RMAP_EVENT_LLIST_ADDED); +} +DEFUN (no_match_lcommunity, + no_match_lcommunity_cmd, + "no match large-community [(1-99)|(100-500)|WORD]", + NO_STR + MATCH_STR + "Match BGP large community list\n" + "Large Community-list number (standard)\n" + "Large Community-list number (expanded)\n" + "Large Community-list name\n") +{ + return bgp_route_match_delete (vty, "large-community", NULL, + RMAP_EVENT_LLIST_DELETED); +} DEFUN (match_ecommunity, match_ecommunity_cmd, @@ -3547,6 +3866,86 @@ DEFUN (no_set_community_delete, "comm-list", NULL); } +DEFUN (set_lcommunity, + set_lcommunity_cmd, + "set large-community AA:BB:CC...", + SET_STR + "BGP large community attribute\n" + "Large Community number in aa:bb:cc format or additive\n") +{ + int ret; + char *str; + + str = argv_concat (argv, argc, 2); + ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "large-community", str); + XFREE (MTYPE_TMP, str); + + return ret; +} + +DEFUN (set_lcommunity_none, + set_lcommunity_none_cmd, + "set large-community none", + SET_STR + "BGP large community attribute\n" + "No large community attribute\n") +{ + return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), + "large-community", "none"); +} + +DEFUN (no_set_lcommunity, + no_set_lcommunity_cmd, + "no set large-community ", + NO_STR + SET_STR + "BGP large community attribute\n" + "No community attribute\n" + "Large community\n" + "Large community in AA:BB:CC... format or additive\n") +{ + return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), + "large-community", NULL); +} + + +DEFUN (set_lcommunity_delete, + set_lcommunity_delete_cmd, + "set large-comm-list <(1-99)|(100-500)|WORD> delete", + SET_STR + "set BGP large community list (for deletion)\n" + "Large Community-list number (standard)\n" + "Large Communitly-list number (expanded)\n" + "Large Community-list name\n" + "Delete matching large communities\n") +{ + char *str; + + str = XCALLOC (MTYPE_TMP, strlen (argv[2]->arg) + strlen (" delete") + 1); + strcpy (str, argv[2]->arg); + strcpy (str + strlen (argv[2]->arg), " delete"); + + generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), + "large-comm-list", str); + + XFREE (MTYPE_TMP, str); + return CMD_SUCCESS; +} + +DEFUN (no_set_lcommunity_delete, + no_set_lcommunity_delete_cmd, + "no set large-comm-list [<(1-99|(100-500)|word)> delete]", + NO_STR + SET_STR + "set BGP large community list (for deletion)\n" + "Large Community-list number (standard)\n" + "Large Communitly-list number (expanded)\n" + "Large Community-list name\n" + "Delete matching large communities\n") +{ + return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), + "large-comm-list", NULL); +} DEFUN (set_ecommunity_rt, set_ecommunity_rt_cmd, @@ -4002,6 +4401,7 @@ bgp_route_map_init (void) route_map_install_match (&route_match_ip_route_source_prefix_list_cmd); route_map_install_match (&route_match_aspath_cmd); route_map_install_match (&route_match_community_cmd); + route_map_install_match (&route_match_lcommunity_cmd); route_map_install_match (&route_match_ecommunity_cmd); route_map_install_match (&route_match_local_pref_cmd); route_map_install_match (&route_match_metric_cmd); @@ -4021,6 +4421,8 @@ bgp_route_map_init (void) route_map_install_set (&route_set_aggregator_as_cmd); route_map_install_set (&route_set_community_cmd); route_map_install_set (&route_set_community_delete_cmd); + route_map_install_set (&route_set_lcommunity_cmd); + route_map_install_set (&route_set_lcommunity_delete_cmd); route_map_install_set (&route_set_vpnv4_nexthop_cmd); route_map_install_set (&route_set_originator_id_cmd); route_map_install_set (&route_set_ecommunity_rt_cmd); @@ -4042,6 +4444,8 @@ bgp_route_map_init (void) install_element (RMAP_NODE, &match_community_cmd); install_element (RMAP_NODE, &match_community_exact_cmd); install_element (RMAP_NODE, &no_match_community_cmd); + install_element (RMAP_NODE, &match_lcommunity_cmd); + install_element (RMAP_NODE, &no_match_lcommunity_cmd); install_element (RMAP_NODE, &match_ecommunity_cmd); install_element (RMAP_NODE, &no_match_ecommunity_cmd); install_element (RMAP_NODE, &match_origin_cmd); @@ -4071,6 +4475,11 @@ bgp_route_map_init (void) install_element (RMAP_NODE, &no_set_community_cmd); install_element (RMAP_NODE, &set_community_delete_cmd); install_element (RMAP_NODE, &no_set_community_delete_cmd); + install_element (RMAP_NODE, &set_lcommunity_cmd); + install_element (RMAP_NODE, &set_lcommunity_none_cmd); + install_element (RMAP_NODE, &no_set_lcommunity_cmd); + install_element (RMAP_NODE, &set_lcommunity_delete_cmd); + install_element (RMAP_NODE, &no_set_lcommunity_delete_cmd); install_element (RMAP_NODE, &set_ecommunity_rt_cmd); install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd); install_element (RMAP_NODE, &set_ecommunity_soo_cmd); -- cgit v1.2.3 From 52951b630a4f85db81f598d2bc759c6387ff2801 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 20 Jan 2017 10:43:08 -0500 Subject: bgpd: Fix cli for large-communities The original commit for large communities broke 'show ip bgp' and 'show bgp ipv4 unicast' and their ilk. This commit fixes this as well as some vtysh parse errors identified. Signed-off-by: Donald Sharp --- bgpd/bgp_route.c | 120 +++++++++++++++++++++++++++++++++++++++++++--------- bgpd/bgp_routemap.c | 24 ++++++++--- bgpd/bgp_vty.c | 32 +++++++++++++- 3 files changed, 146 insertions(+), 30 deletions(-) (limited to 'bgpd/bgp_routemap.c') diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 33b7bc125..330e7ed52 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -7925,6 +7925,101 @@ bgp_show_lcommunity_list (struct vty *vty, struct bgp *bgp, const char *lcom, return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity_list, list, uj); } +DEFUN (show_ip_bgp_large_community_list, + show_ip_bgp_large_community_list_cmd, + "show [ip] bgp [ WORD] [ []] large-community-list <(1-500)|WORD> [json]", + SHOW_STR + IP_STR + BGP_STR + BGP_INSTANCE_HELP_STR + "Address Family\n" + "Address Family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Display routes matching the large-community-list\n" + "large-community-list number\n" + "large-community-list name\n" + JSON_STR) +{ + char *vrf = NULL; + afi_t afi = AFI_IP6; + safi_t safi = SAFI_UNICAST; + int idx = 0; + + if (argv_find (argv, argc, "ip", &idx)) + afi = AFI_IP; + if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx)) + vrf = argv[++idx]->arg; + if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx)) + { + afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP; + if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx)) + safi = bgp_vty_safi_from_arg (argv[idx]->text); + } + + int uj = use_json (argc, argv); + + struct bgp *bgp = bgp_lookup_by_name (vrf); + if (bgp == NULL) + { + vty_out (vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE); + return CMD_WARNING; + } + + argv_find (argv, argc, "large-community-list", &idx); + return bgp_show_lcommunity_list (vty, bgp, argv[idx+1]->arg, afi, safi, uj); +} +DEFUN (show_ip_bgp_large_community, + show_ip_bgp_large_community_cmd, + "show [ip] bgp [ WORD] [ []] large-community [AA:BB:CC] [json]", + SHOW_STR + IP_STR + BGP_STR + BGP_INSTANCE_HELP_STR + "Address Family\n" + "Address Family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Display routes matching the large-communities\n" + "List of large-community numbers\n" + JSON_STR) +{ + char *vrf = NULL; + afi_t afi = AFI_IP6; + safi_t safi = SAFI_UNICAST; + int idx = 0; + + if (argv_find (argv, argc, "ip", &idx)) + afi = AFI_IP; + if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx)) + vrf = argv[++idx]->arg; + if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx)) + { + afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP; + if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx)) + safi = bgp_vty_safi_from_arg (argv[idx]->text); + } + + int uj = use_json (argc, argv); + + struct bgp *bgp = bgp_lookup_by_name (vrf); + if (bgp == NULL) + { + vty_out (vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE); + return CMD_WARNING; + } + + argv_find (argv, argc, "large-community", &idx); + if (strmatch(argv[idx+1]->text, "AA:BB:CC")) + return bgp_show_lcommunity (vty, bgp, argc, argv, afi, safi, uj); + else + return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity_all, NULL, uj); +} + /* BGP route print out function. */ DEFUN (show_ip_bgp_ipv4, show_ip_bgp_ipv4_cmd, @@ -7937,8 +8032,6 @@ DEFUN (show_ip_bgp_ipv4, |filter-list WORD\ |community [ [exact-match]]\ |community-list <(1-500)|WORD> [exact-match]\ - |large-community [...]\ - |large-community-list <(1-500)|WORD>\ |A.B.C.D/M longer-prefixes\ |X:X::X:X/M longer-prefixes>\ ] [json]", @@ -7973,14 +8066,6 @@ DEFUN (show_ip_bgp_ipv4, "community-list number\n" "community-list name\n" "Exact match of the communities\n" - "Display routes matching the large-communities\n" - "large-community number\n" - "large-community number\n" - "large-community number\n" - "large-community number\n" - "Display routes matching the large-community-list\n" - "large-community-list number\n" - "large-community-list name\n" "IPv4 prefix\n" "Display route and more specific routes\n" "IPv6 prefix\n" @@ -8070,17 +8155,6 @@ DEFUN (show_ip_bgp_ipv4, exact_match = 1; return bgp_show_community_list (vty, vrf, clist_number_or_name, exact_match, afi, safi); } - else if (strmatch(argv[idx]->text, "large-community")) - { - if (strmatch(argv[idx+1]->text, "")) - return bgp_show_lcommunity (vty, bgp, argc, argv, afi, safi, uj); - else - return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity_all, NULL, uj); - } - else if (strmatch(argv[idx]->text, "large-community-list")) - { - return bgp_show_lcommunity_list (vty, bgp, argv[idx+1]->arg, afi, safi, uj); - } /* prefix-longer */ else if (argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV6_TKN) return bgp_show_prefix_longer (vty, vrf, argv[idx + 1]->arg, afi, safi, bgp_show_type_prefix_longer); @@ -10720,6 +10794,10 @@ bgp_route_init (void) /* IPv4 Multicast Mode */ install_element (BGP_IPV4M_NODE, &bgp_damp_set_cmd); install_element (BGP_IPV4M_NODE, &bgp_damp_unset_cmd); + + /* Large Communities */ + install_element (VIEW_NODE, &show_ip_bgp_large_community_list_cmd); + install_element (VIEW_NODE, &show_ip_bgp_large_community_cmd); } void diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index c4b3ddee3..693a807c8 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -3410,7 +3410,7 @@ DEFUN (no_match_community, DEFUN (match_lcommunity, match_lcommunity_cmd, - "match large-community [(1-99)|(100-500)|WORD]", + "match large-community [<(1-99)|(100-500)|WORD>]", MATCH_STR "Match BGP large community list\n" "Large Community-list number (standard)\n" @@ -3423,7 +3423,7 @@ DEFUN (match_lcommunity, DEFUN (no_match_lcommunity, no_match_lcommunity_cmd, - "no match large-community [(1-99)|(100-500)|WORD]", + "no match large-community [<(1-99)|(100-500)|WORD>]", NO_STR MATCH_STR "Match BGP large community list\n" @@ -3896,18 +3896,27 @@ DEFUN (set_lcommunity_none, DEFUN (no_set_lcommunity, no_set_lcommunity_cmd, - "no set large-community ", + "no set large-community none", NO_STR SET_STR "BGP large community attribute\n" - "No community attribute\n" - "Large community\n" - "Large community in AA:BB:CC... format or additive\n") + "No community attribute\n") { return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), "large-community", NULL); } +DEFUN (no_set_lcommunity1, + no_set_lcommunity1_cmd, + "no set large-community AA:BB:CC...", + NO_STR + SET_STR + "BGP large community attribute\n" + "Large community in AA:BB:CC... format or additive\n") +{ + return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), + "large-community", NULL); +} DEFUN (set_lcommunity_delete, set_lcommunity_delete_cmd, @@ -3934,7 +3943,7 @@ DEFUN (set_lcommunity_delete, DEFUN (no_set_lcommunity_delete, no_set_lcommunity_delete_cmd, - "no set large-comm-list [<(1-99|(100-500)|word)> delete]", + "no set large-comm-list <(1-99|(100-500)|WORD)> [delete]", NO_STR SET_STR "set BGP large community list (for deletion)\n" @@ -4478,6 +4487,7 @@ bgp_route_map_init (void) install_element (RMAP_NODE, &set_lcommunity_cmd); install_element (RMAP_NODE, &set_lcommunity_none_cmd); install_element (RMAP_NODE, &no_set_lcommunity_cmd); + install_element (RMAP_NODE, &no_set_lcommunity1_cmd); install_element (RMAP_NODE, &set_lcommunity_delete_cmd); install_element (RMAP_NODE, &no_set_lcommunity_delete_cmd); install_element (RMAP_NODE, &set_ecommunity_rt_cmd); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 0797756f6..b3eaaaf11 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -11240,7 +11240,20 @@ lcommunity_list_unset_vty (struct vty *vty, int argc, struct cmd_token **argv, DEFUN (ip_lcommunity_list_standard, ip_lcommunity_list_standard_cmd, - "ip large-community-list (1-99) [AA:BB:CC...]", + "ip large-community-list (1-99) ", + IP_STR + LCOMMUNITY_LIST_STR + "Large Community list number (standard)\n" + "Specify large community to reject\n" + "Specify large community to accept\n" + LCOMMUNITY_VAL_STR) +{ + return lcommunity_list_set_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_STANDARD, 0); +} + +DEFUN (ip_lcommunity_list_standard1, + ip_lcommunity_list_standard1_cmd, + "ip large-community-list (1-99) AA:BB:CC...", IP_STR LCOMMUNITY_LIST_STR "Large Community list number (standard)\n" @@ -11266,7 +11279,20 @@ DEFUN (ip_lcommunity_list_expanded, DEFUN (ip_lcommunity_list_name_standard, ip_lcommunity_list_name_standard_cmd, - "ip large-community-list standard WORD [AA:BB.CC...]", + "ip large-community-list standard WORD ", + IP_STR + LCOMMUNITY_LIST_STR + "Specify standard large-community-list\n" + "Large Community list name\n" + "Specify large community to reject\n" + "Specify large community to accept\n") +{ + return lcommunity_list_set_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_STANDARD, 1); +} + +DEFUN (ip_lcommunity_list_name_standard1, + ip_lcommunity_list_name_standard1_cmd, + "ip large-community-list standard WORD AA:BB:CC...", IP_STR LCOMMUNITY_LIST_STR "Specify standard large-community-list\n" @@ -11819,8 +11845,10 @@ community_list_vty (void) /* Large Community List */ install_element (CONFIG_NODE, &ip_lcommunity_list_standard_cmd); + install_element (CONFIG_NODE, &ip_lcommunity_list_standard1_cmd); install_element (CONFIG_NODE, &ip_lcommunity_list_expanded_cmd); install_element (CONFIG_NODE, &ip_lcommunity_list_name_standard_cmd); + install_element (CONFIG_NODE, &ip_lcommunity_list_name_standard1_cmd); install_element (CONFIG_NODE, &ip_lcommunity_list_name_expanded_cmd); install_element (CONFIG_NODE, &no_ip_lcommunity_list_standard_all_cmd); install_element (CONFIG_NODE, &no_ip_lcommunity_list_name_expanded_all_cmd); -- cgit v1.2.3 From 2acb4ac250c9c7363a8ee4455677c69764f9f97c Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 25 Jan 2017 22:29:31 +0100 Subject: bgpd: lcommunity: fix whitespace & copyright (to match surrounding code) "git diff -w" should be almost empty. Copyright edited to say FRR, this is not GNU Zebra :) Signed-off-by: David Lamparter --- bgpd/bgp_attr.c | 48 ++++++++--------- bgpd/bgp_attr.h | 2 +- bgpd/bgp_clist.c | 42 ++++++++------- bgpd/bgp_lcommunity.c | 37 +++++++------ bgpd/bgp_lcommunity.h | 37 +++++++------ bgpd/bgp_route.c | 72 +++++++++++++------------- bgpd/bgp_routemap.c | 140 +++++++++++++++++++++++++------------------------- bgpd/bgp_vty.c | 76 +++++++++++++-------------- 8 files changed, 225 insertions(+), 229 deletions(-) (limited to 'bgpd/bgp_routemap.c') diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index fc9440ddd..3a5854667 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -673,7 +673,7 @@ attrhash_key_make (void *p) if (extra) { if (extra->lcommunity) - MIX(lcommunity_hash_make (extra->lcommunity)); + MIX(lcommunity_hash_make (extra->lcommunity)); if (extra->ecommunity) MIX(ecommunity_hash_make (extra->ecommunity)); if (extra->cluster) @@ -1042,7 +1042,7 @@ bgp_attr_unintern_sub (struct attr *attr) if (attr->extra->lcommunity) lcommunity_unintern (&attr->extra->lcommunity); UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES)); - + if (attr->extra->cluster) cluster_unintern (attr->extra->cluster); UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST)); @@ -1113,7 +1113,7 @@ bgp_attr_flush (struct attr *attr) if (attre->ecommunity && ! attre->ecommunity->refcnt) ecommunity_free (&attre->ecommunity); if (attre->lcommunity && ! attre->lcommunity->refcnt) - lcommunity_free (&attre->lcommunity); + lcommunity_free (&attre->lcommunity); if (attre->cluster && ! attre->cluster->refcnt) { cluster_free (attre->cluster); @@ -1272,7 +1272,7 @@ const u_int8_t attr_flags_values [] = { [BGP_ATTR_EXT_COMMUNITIES] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS, [BGP_ATTR_AS4_PATH] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS, [BGP_ATTR_AS4_AGGREGATOR] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS, - [BGP_ATTR_LARGE_COMMUNITIES] = BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL + [BGP_ATTR_LARGE_COMMUNITIES]= BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS, }; static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1; @@ -3165,17 +3165,17 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer, && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES))) { if (attr->extra->lcommunity->size * 12 > 255) - { - stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN); - stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES); - stream_putw (s, attr->extra->lcommunity->size * 12); - } + { + stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN); + stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES); + stream_putw (s, attr->extra->lcommunity->size * 12); + } else - { - stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); - stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES); - stream_putc (s, attr->extra->lcommunity->size * 12); - } + { + stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); + stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES); + stream_putc (s, attr->extra->lcommunity->size * 12); + } stream_put (s, attr->extra->lcommunity->val, attr->extra->lcommunity->size * 12); } @@ -3532,17 +3532,17 @@ bgp_dump_routes_attr (struct stream *s, struct attr *attr, if (attr->extra && attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES)) { if (attr->extra->lcommunity->size * 12 > 255) - { - stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN); - stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES); - stream_putw (s, attr->extra->lcommunity->size * 12); - } + { + stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN); + stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES); + stream_putw (s, attr->extra->lcommunity->size * 12); + } else - { - stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); - stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES); - stream_putc (s, attr->extra->lcommunity->size * 12); - } + { + stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); + stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES); + stream_putc (s, attr->extra->lcommunity->size * 12); + } stream_put (s, attr->extra->lcommunity->val, attr->extra->lcommunity->size * 12); } diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index 9c931051d..c5799ccd0 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -95,7 +95,7 @@ struct attr_extra /* Large Communities attribute. */ struct lcommunity *lcommunity; - + /* Route-Reflector Cluster attribute */ struct cluster_list *cluster; diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index 47192f0f0..b37034bf2 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -43,11 +43,11 @@ community_list_master_lookup (struct community_list_handler *ch, int master) switch (master) { case COMMUNITY_LIST_MASTER: - return &ch->community_list; + return &ch->community_list; case EXTCOMMUNITY_LIST_MASTER: - return &ch->extcommunity_list; + return &ch->extcommunity_list; case LARGE_COMMUNITY_LIST_MASTER: - return &ch->lcommunity_list; + return &ch->lcommunity_list; } return NULL; } @@ -412,15 +412,14 @@ community_str_get (struct community *com, int i) } /* Internal function to perform regular expression match for - * * a single community. */ + * a single community. */ static int community_regexp_include (regex_t * reg, struct community *com, int i) { char *str; int rv; - /* When there is no communities attribute it is treated as empty - * string. */ + /* When there is no communities attribute it is treated as empty string. */ if (com == NULL || com->size == 0) str = XSTRDUP(MTYPE_COMMUNITY_STR, ""); else @@ -503,14 +502,13 @@ lcommunity_str_get (struct lcommunity *lcom, int i) } /* Internal function to perform regular expression match for - * * a single community. */ + * a single community. */ static int lcommunity_regexp_include (regex_t * reg, struct lcommunity *lcom, int i) { const char *str; - /* When there is no communities attribute it is treated as empty - * string. */ + /* When there is no communities attribute it is treated as empty string. */ if (lcom == NULL || lcom->size == 0) str = ""; else @@ -826,7 +824,7 @@ community_list_dup_check (struct community_list *list, break; case COMMUNITY_LIST_EXPANDED: case EXTCOMMUNITY_LIST_EXPANDED: - case LARGE_COMMUNITY_LIST_EXPANDED: + case LARGE_COMMUNITY_LIST_EXPANDED: if (strcmp (entry->config, new->config) == 0) return 1; break; @@ -947,7 +945,7 @@ community_list_unset (struct community_list_handler *ch, /* Delete all permitted large communities in the list from com. */ struct lcommunity * lcommunity_list_match_delete (struct lcommunity *lcom, - struct community_list *list) + struct community_list *list) { struct community_entry *entry; u_int32_t com_index_to_delete[lcom->size]; @@ -1013,7 +1011,7 @@ lcommunity_list_match_delete (struct lcommunity *lcom, /* Set lcommunity-list. */ int lcommunity_list_set (struct community_list_handler *ch, - const char *name, const char *str, int direct, int style) + const char *name, const char *str, int direct, int style) { struct community_entry *entry = NULL; struct community_list *list; @@ -1033,22 +1031,22 @@ lcommunity_list_set (struct community_list_handler *ch, first = list->head; if (style != first->style) - { - return (first->style == COMMUNITY_LIST_STANDARD - ? COMMUNITY_LIST_ERR_STANDARD_CONFLICT - : COMMUNITY_LIST_ERR_EXPANDED_CONFLICT); - } + { + return (first->style == COMMUNITY_LIST_STANDARD + ? COMMUNITY_LIST_ERR_STANDARD_CONFLICT + : COMMUNITY_LIST_ERR_EXPANDED_CONFLICT); + } } if (str) { if (style == LARGE_COMMUNITY_LIST_STANDARD) - lcom = lcommunity_str2com (str); + lcom = lcommunity_str2com (str); else - regex = bgp_regcomp (str); + regex = bgp_regcomp (str); if (! lcom && ! regex) - return COMMUNITY_LIST_ERR_MALFORMED_VAL; + return COMMUNITY_LIST_ERR_MALFORMED_VAL; } entry = community_entry_new (); @@ -1077,8 +1075,8 @@ lcommunity_list_set (struct community_list_handler *ch, community-list entry belongs to the specified name. */ int lcommunity_list_unset (struct community_list_handler *ch, - const char *name, const char *str, - int direct, int style) + const char *name, const char *str, + int direct, int style) { struct community_entry *entry = NULL; struct community_list *list; diff --git a/bgpd/bgp_lcommunity.c b/bgpd/bgp_lcommunity.c index dc98809f6..549a2ebad 100644 --- a/bgpd/bgp_lcommunity.c +++ b/bgpd/bgp_lcommunity.c @@ -1,23 +1,22 @@ /* BGP Large Communities Attribute - -Copyright (C) 2016 Keyur Patel - -This file is part of GNU Zebra. - -GNU Zebra is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -GNU Zebra is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Zebra; see the file COPYING. If not, write to the Free -Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ + * + * Copyright (C) 2016 Keyur Patel + * + * This file is part of FreeRangeRouting (FRR). + * + * FRR is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2, or (at your option) any later version. + * + * FRR is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along + * with FRR; see the file COPYING. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #include diff --git a/bgpd/bgp_lcommunity.h b/bgpd/bgp_lcommunity.h index 7841b4b9a..de3697f47 100644 --- a/bgpd/bgp_lcommunity.h +++ b/bgpd/bgp_lcommunity.h @@ -1,23 +1,22 @@ /* BGP Large Communities Attribute. - -Copyright (C) 2016 Keyur Patel - -This file is part of GNU Zebra. - -GNU Zebra is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -GNU Zebra is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Zebra; see the file COPYING. If not, write to the Free -Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ + * + * Copyright (C) 2016 Keyur Patel + * + * This file is part of FreeRangeRouting (FRR). + * + * FRR is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2, or (at your option) any later version. + * + * FRR is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along + * with FRR; see the file COPYING. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #ifndef _QUAGGA_BGP_LCOMMUNITY_H #define _QUAGGA_BGP_LCOMMUNITY_H diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 330e7ed52..afcf05d2b 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -7063,8 +7063,8 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p, /* Line 6 display Large community */ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) - vty_out (vty, " Large Community: %s%s", - attr->extra->lcommunity->str, VTY_NEWLINE); + vty_out (vty, " Large Community: %s%s", + attr->extra->lcommunity->str, VTY_NEWLINE); /* Line 7 display Originator, Cluster-id */ if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) || @@ -7426,32 +7426,32 @@ bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table, if (! community_list_exact_match (ri->attr->community, list)) continue; } - if (type == bgp_show_type_community_all) - { - if (! ri->attr->community) - continue; - } - if (type == bgp_show_type_lcommunity) - { - struct lcommunity *lcom = output_arg; + if (type == bgp_show_type_community_all) + { + if (! ri->attr->community) + continue; + } + if (type == bgp_show_type_lcommunity) + { + struct lcommunity *lcom = output_arg; - if (! ri->attr->extra || ! ri->attr->extra->lcommunity || - ! lcommunity_match (ri->attr->extra->lcommunity, lcom)) - continue; - } - if (type == bgp_show_type_lcommunity_list) - { - struct community_list *list = output_arg; + if (! ri->attr->extra || ! ri->attr->extra->lcommunity || + ! lcommunity_match (ri->attr->extra->lcommunity, lcom)) + continue; + } + if (type == bgp_show_type_lcommunity_list) + { + struct community_list *list = output_arg; - if (! ri->attr->extra || - ! lcommunity_list_match (ri->attr->extra->lcommunity, list)) - continue; - } - if (type == bgp_show_type_lcommunity_all) - { - if (! ri->attr->extra || ! ri->attr->extra->lcommunity) - continue; - } + if (! ri->attr->extra || + ! lcommunity_list_match (ri->attr->extra->lcommunity, list)) + continue; + } + if (type == bgp_show_type_lcommunity_all) + { + if (! ri->attr->extra || ! ri->attr->extra->lcommunity) + continue; + } if (type == bgp_show_type_dampend_paths || type == bgp_show_type_damp_neighbor) { @@ -7870,7 +7870,7 @@ bgp_show_route (struct vty *vty, const char *view_name, const char *ip_str, static int bgp_show_lcommunity (struct vty *vty, struct bgp *bgp, int argc, - struct cmd_token **argv, afi_t afi, safi_t safi, u_char uj) + struct cmd_token **argv, afi_t afi, safi_t safi, u_char uj) { struct lcommunity *lcom; struct buffer *b; @@ -7884,13 +7884,13 @@ bgp_show_lcommunity (struct vty *vty, struct bgp *bgp, int argc, if (first) buffer_putc (b, ' '); else - { - if (strmatch (argv[i]->text, "")) - { - first = 1; - buffer_putstr (b, argv[i]->arg); - } - } + { + if (strmatch (argv[i]->text, "")) + { + first = 1; + buffer_putstr (b, argv[i]->arg); + } + } } buffer_putc (b, '\0'); @@ -7910,7 +7910,7 @@ bgp_show_lcommunity (struct vty *vty, struct bgp *bgp, int argc, static int bgp_show_lcommunity_list (struct vty *vty, struct bgp *bgp, const char *lcom, - afi_t afi, safi_t safi, u_char uj) + afi_t afi, safi_t safi, u_char uj) { struct community_list *list; @@ -7918,7 +7918,7 @@ bgp_show_lcommunity_list (struct vty *vty, struct bgp *bgp, const char *lcom, if (list == NULL) { vty_out (vty, "%% %s is not a valid large-community-list name%s", lcom, - VTY_NEWLINE); + VTY_NEWLINE); return CMD_WARNING; } diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 693a807c8..58d9b20f9 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -853,7 +853,7 @@ struct route_map_rule_cmd route_match_community_cmd = /* Match function for lcommunity match. */ static route_map_result_t route_match_lcommunity (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) + route_map_object_t type, void *object) { struct community_list *list; struct bgp_info *bgp_info; @@ -865,13 +865,13 @@ route_match_lcommunity (void *rule, struct prefix *prefix, rcom = rule; list = community_list_lookup (bgp_clist, rcom->name, - LARGE_COMMUNITY_LIST_MASTER); + LARGE_COMMUNITY_LIST_MASTER); if (! list) - return RMAP_NOMATCH; + return RMAP_NOMATCH; if (bgp_info->attr->extra && - lcommunity_list_match (bgp_info->attr->extra->lcommunity, list)) - return RMAP_MATCH; + lcommunity_list_match (bgp_info->attr->extra->lcommunity, list)) + return RMAP_MATCH; } return RMAP_NOMATCH; @@ -1631,7 +1631,7 @@ struct rmap_lcom_set /* For lcommunity set mechanism. */ static route_map_result_t route_set_lcommunity (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) + route_map_object_t type, void *object) { struct rmap_lcom_set *rcs; struct bgp_info *binfo; @@ -1649,37 +1649,37 @@ route_set_lcommunity (void *rule, struct prefix *prefix, /* "none" case. */ if (rcs->none) - { - attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES)); - if (attr->extra) { - attr->extra->lcommunity = NULL; - } - /* See the longer comment down below. */ - if (old && old->refcnt == 0) - lcommunity_free(&old); - return RMAP_OKAY; - } + { + attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES)); + if (attr->extra) + attr->extra->lcommunity = NULL; + + /* See the longer comment down below. */ + if (old && old->refcnt == 0) + lcommunity_free(&old); + return RMAP_OKAY; + } if (rcs->additive && old) - { - merge = lcommunity_merge (lcommunity_dup (old), rcs->lcom); + { + merge = lcommunity_merge (lcommunity_dup (old), rcs->lcom); - /* HACK: if the old large-community is not intern'd, + /* HACK: if the old large-community is not intern'd, * we should free it here, or all reference to it may be lost. * Really need to cleanup attribute caching sometime. */ - if (old->refcnt == 0) - lcommunity_free (&old); - new = lcommunity_uniq_sort (merge); - lcommunity_free (&merge); - } + if (old->refcnt == 0) + lcommunity_free (&old); + new = lcommunity_uniq_sort (merge); + lcommunity_free (&merge); + } else - new = lcommunity_dup (rcs->lcom); + new = lcommunity_dup (rcs->lcom); + + /* will be interned by caller if required */ + if (attr->extra) + attr->extra->lcommunity = new; - /* will be interned by caller if required */ - if (attr->extra) { - attr->extra->lcommunity = new; - } attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES); } @@ -1703,19 +1703,19 @@ route_set_lcommunity_compile (const char *arg) sp = strstr (arg, "additive"); if (sp && sp > arg) - { - /* "additive" keyworkd is included. */ - additive = 1; - *(sp - 1) = '\0'; - } + { + /* "additive" keyworkd is included. */ + additive = 1; + *(sp - 1) = '\0'; + } lcom = lcommunity_str2com (arg); - if (additive) - *(sp - 1) = ' '; + if (additive) + *(sp - 1) = ' '; - if (! lcom) - return NULL; + if (! lcom) + return NULL; } rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set)); @@ -1752,7 +1752,7 @@ struct route_map_rule_cmd route_set_lcommunity_cmd = /* For large community set mechanism. */ static route_map_result_t route_set_lcommunity_delete (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) + route_map_object_t type, void *object) { struct community_list *list; struct lcommunity *merge; @@ -1763,38 +1763,38 @@ route_set_lcommunity_delete (void *rule, struct prefix *prefix, if (type == RMAP_BGP) { if (! rule) - return RMAP_OKAY; + return RMAP_OKAY; binfo = object; list = community_list_lookup (bgp_clist, rule, - LARGE_COMMUNITY_LIST_MASTER); + LARGE_COMMUNITY_LIST_MASTER); old = ((binfo->attr->extra) ? binfo->attr->extra->lcommunity : NULL); if (list && old) - { - merge = lcommunity_list_match_delete (lcommunity_dup (old), list); - new = lcommunity_uniq_sort (merge); - lcommunity_free (&merge); + { + merge = lcommunity_list_match_delete (lcommunity_dup (old), list); + new = lcommunity_uniq_sort (merge); + lcommunity_free (&merge); - /* HACK: if the old community is not intern'd, - * we should free it here, or all reference to it may be lost. - * Really need to cleanup attribute caching sometime. - */ - if (old->refcnt == 0) - lcommunity_free (&old); + /* HACK: if the old community is not intern'd, + * we should free it here, or all reference to it may be lost. + * Really need to cleanup attribute caching sometime. + */ + if (old->refcnt == 0) + lcommunity_free (&old); - if (new->size == 0) - { - binfo->attr->extra->lcommunity = NULL; - binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES); - lcommunity_free (&new); - } - else - { - binfo->attr->extra->lcommunity = new; - binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES); - } - } + if (new->size == 0) + { + binfo->attr->extra->lcommunity = NULL; + binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES); + lcommunity_free (&new); + } + else + { + binfo->attr->extra->lcommunity = new; + binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES); + } + } } return RMAP_OKAY; @@ -3418,7 +3418,7 @@ DEFUN (match_lcommunity, "Large Community-list name\n") { return bgp_route_match_add (vty, "large-community", argv[2]->arg, - RMAP_EVENT_LLIST_ADDED); + RMAP_EVENT_LLIST_ADDED); } DEFUN (no_match_lcommunity, @@ -3432,7 +3432,7 @@ DEFUN (no_match_lcommunity, "Large Community-list name\n") { return bgp_route_match_delete (vty, "large-community", NULL, - RMAP_EVENT_LLIST_DELETED); + RMAP_EVENT_LLIST_DELETED); } DEFUN (match_ecommunity, @@ -3891,7 +3891,7 @@ DEFUN (set_lcommunity_none, "No large community attribute\n") { return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), - "large-community", "none"); + "large-community", "none"); } DEFUN (no_set_lcommunity, @@ -3903,7 +3903,7 @@ DEFUN (no_set_lcommunity, "No community attribute\n") { return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), - "large-community", NULL); + "large-community", NULL); } DEFUN (no_set_lcommunity1, @@ -3915,7 +3915,7 @@ DEFUN (no_set_lcommunity1, "Large community in AA:BB:CC... format or additive\n") { return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), - "large-community", NULL); + "large-community", NULL); } DEFUN (set_lcommunity_delete, @@ -3935,7 +3935,7 @@ DEFUN (set_lcommunity_delete, strcpy (str + strlen (argv[2]->arg), " delete"); generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), - "large-comm-list", str); + "large-comm-list", str); XFREE (MTYPE_TMP, str); return CMD_SUCCESS; @@ -3953,7 +3953,7 @@ DEFUN (no_set_lcommunity_delete, "Delete matching large communities\n") { return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), - "large-comm-list", NULL); + "large-comm-list", NULL); } DEFUN (set_ecommunity_rt, diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index b3eaaaf11..aa9758663 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -6157,7 +6157,7 @@ DEFUN (show_bgp_memory, VTY_NEWLINE); if ((count = mtype_stats_alloc (MTYPE_LCOMMUNITY))) vty_out (vty, "%ld BGP large-community entries, using %s of memory%s", - count, + count, mtype_memstr (memstrbuf, sizeof (memstrbuf), count * sizeof (struct lcommunity)), VTY_NEWLINE); @@ -8677,7 +8677,7 @@ lcommunity_show_all_iterator (struct hash_backet *backet, struct vty *vty) lcom = (struct lcommunity *) backet->data; vty_out (vty, "[%p] (%ld) %s%s", (void *)backet, lcom->refcnt, - lcommunity_str (lcom), VTY_NEWLINE); + lcommunity_str (lcom), VTY_NEWLINE); } /* Show BGP's community internal data. */ @@ -8692,9 +8692,9 @@ DEFUN (show_ip_bgp_lcommunity_info, vty_out (vty, "Address Refcnt Large-community%s", VTY_NEWLINE); hash_iterate (lcommunity_hash (), - (void (*) (struct hash_backet *, void *)) - lcommunity_show_all_iterator, - vty); + (void (*) (struct hash_backet *, void *)) + lcommunity_show_all_iterator, + vty); return CMD_SUCCESS; } @@ -11140,7 +11140,7 @@ DEFUN (show_ip_community_list_arg, */ static int lcommunity_list_set_vty (struct vty *vty, int argc, struct cmd_token **argv, - int style, int reject_all_digit_name) + int style, int reject_all_digit_name) { int ret; int direct; @@ -11187,7 +11187,7 @@ lcommunity_list_set_vty (struct vty *vty, int argc, struct cmd_token **argv, static int lcommunity_list_unset_vty (struct vty *vty, int argc, struct cmd_token **argv, - int style) + int style) { int ret; int direct = 0; @@ -11201,9 +11201,9 @@ lcommunity_list_unset_vty (struct vty *vty, int argc, struct cmd_token **argv, { /* Check the list direct. */ if (strncmp (argv[idx]->arg, "p", 1) == 0) - direct = COMMUNITY_PERMIT; + direct = COMMUNITY_PERMIT; else - direct = COMMUNITY_DENY; + direct = COMMUNITY_DENY; idx = 0; argv_find (argv, argc, "LINE", &idx); @@ -11409,27 +11409,27 @@ lcommunity_list_show (struct vty *vty, struct community_list *list) for (entry = list->head; entry; entry = entry->next) { if (entry == list->head) - { - if (all_digit (list->name)) - vty_out (vty, "Large community %s list %s%s", - entry->style == EXTCOMMUNITY_LIST_STANDARD ? - "standard" : "(expanded) access", - list->name, VTY_NEWLINE); - else - vty_out (vty, "Named large community %s list %s%s", - entry->style == EXTCOMMUNITY_LIST_STANDARD ? - "standard" : "expanded", - list->name, VTY_NEWLINE); - } + { + if (all_digit (list->name)) + vty_out (vty, "Large community %s list %s%s", + entry->style == EXTCOMMUNITY_LIST_STANDARD ? + "standard" : "(expanded) access", + list->name, VTY_NEWLINE); + else + vty_out (vty, "Named large community %s list %s%s", + entry->style == EXTCOMMUNITY_LIST_STANDARD ? + "standard" : "expanded", + list->name, VTY_NEWLINE); + } if (entry->any) - vty_out (vty, " %s%s", - community_direct_str (entry->direct), VTY_NEWLINE); + vty_out (vty, " %s%s", + community_direct_str (entry->direct), VTY_NEWLINE); else - vty_out (vty, " %s %s%s", - community_direct_str (entry->direct), - entry->style == EXTCOMMUNITY_LIST_STANDARD ? - entry->u.ecom->str : entry->config, - VTY_NEWLINE); + vty_out (vty, " %s %s%s", + community_direct_str (entry->direct), + entry->style == EXTCOMMUNITY_LIST_STANDARD ? + entry->u.ecom->str : entry->config, + VTY_NEWLINE); } } @@ -11796,20 +11796,20 @@ community_list_config_write (struct vty *vty) for (list = cm->num.head; list; list = list->next) for (entry = list->head; entry; entry = entry->next) { - vty_out (vty, "ip large-community-list %s %s %s%s", - list->name, community_direct_str (entry->direct), - community_list_config_str (entry), VTY_NEWLINE); - write++; + vty_out (vty, "ip large-community-list %s %s %s%s", + list->name, community_direct_str (entry->direct), + community_list_config_str (entry), VTY_NEWLINE); + write++; } for (list = cm->str.head; list; list = list->next) for (entry = list->head; entry; entry = entry->next) { - vty_out (vty, "ip large-community-list %s %s %s %s%s", - entry->style == LARGE_COMMUNITY_LIST_STANDARD - ? "standard" : "expanded", - list->name, community_direct_str (entry->direct), - community_list_config_str (entry), VTY_NEWLINE); - write++; + vty_out (vty, "ip large-community-list %s %s %s %s%s", + entry->style == LARGE_COMMUNITY_LIST_STANDARD + ? "standard" : "expanded", + list->name, community_direct_str (entry->direct), + community_list_config_str (entry), VTY_NEWLINE); + write++; } return write; -- cgit v1.2.3 From ed165abf905e10b7d8b9b9989c52d9a405c513f1 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 25 Jan 2017 22:33:29 +0100 Subject: bgpd: lcommunity: fix minor issues - route_set_lcommunity would do nothing (and leak memory) if attr->extra wasn't up yet - an if() arch in bgp_show_table() was duplicated (with no effect) Signed-off-by: David Lamparter --- bgpd/bgp_route.c | 5 ----- bgpd/bgp_routemap.c | 5 ++--- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'bgpd/bgp_routemap.c') diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index afcf05d2b..06584cf68 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -7426,11 +7426,6 @@ bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table, if (! community_list_exact_match (ri->attr->community, list)) continue; } - if (type == bgp_show_type_community_all) - { - if (! ri->attr->community) - continue; - } if (type == bgp_show_type_lcommunity) { struct lcommunity *lcom = output_arg; diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 58d9b20f9..a3c61e215 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -1676,9 +1676,8 @@ route_set_lcommunity (void *rule, struct prefix *prefix, else new = lcommunity_dup (rcs->lcom); - /* will be interned by caller if required */ - if (attr->extra) - attr->extra->lcommunity = new; + /* will be intern()'d or attr_flush()'d by bgp_update_main() */ + (bgp_attr_extra_get (attr))->lcommunity = new; attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES); } -- cgit v1.2.3