From 643215ce4cd1a38d15fdce8ea44e48b325c63272 Mon Sep 17 00:00:00 2001 From: mitesh Date: Wed, 24 Jan 2018 15:25:03 -0800 Subject: [PATCH 01/45] zebra: optimize l3vni lookup in certain callflows Currently, while processing kernel messages related to VNIs we first check if VNI is L3 - this is a hash lookup later, we do the lookup again to find the L3-VNI. This is non-optimal. Made changed to make sure we only do the lookup once. Signed-off-by: Mitesh Kanjariya --- zebra/zebra_vxlan.c | 119 ++++++++++---------------------------------- 1 file changed, 25 insertions(+), 94 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 1690079f68..0054555e5a 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -126,7 +126,6 @@ static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac); /* l3-vni related APIs*/ -static int is_vni_l3(vni_t); static zebra_l3vni_t *zl3vni_lookup(vni_t vni); static void *zl3vni_alloc(void *p); static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id); @@ -2593,6 +2592,8 @@ static void zvni_build_hash_table() zns = zebra_ns_lookup(NS_DEFAULT); for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { vni_t vni; + zebra_vni_t *zvni = NULL; + zebra_l3vni_t *zl3vni = NULL; struct zebra_if *zif; struct zebra_l2info_vxlan *vxl; @@ -2606,21 +2607,14 @@ static void zvni_build_hash_table() vxl = &zif->l2info.vxl; vni = vxl->vni; - if (is_vni_l3(vni)) { - zebra_l3vni_t *zl3vni = NULL; + /* L3-VNI and L2-VNI are handled seperately */ + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("create L3-VNI hash for Intf %s(%u) L3-VNI %u", ifp->name, ifp->ifindex, vni); - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - zlog_err( - "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u", - ifp->name, ifp->ifindex, vni); - return; - } - /* associate with vxlan_if */ zl3vni->local_vtep_ip = vxl->vtep_ip; zl3vni->vxlan_if = ifp; @@ -2636,8 +2630,6 @@ static void zvni_build_hash_table() zebra_vxlan_process_l3vni_oper_up(zl3vni); } else { - zebra_vni_t *zvni = NULL; - zebra_l3vni_t *zl3vni = NULL; struct interface *vlan_if = NULL; if (IS_ZEBRA_DEBUG_VXLAN) @@ -3387,16 +3379,6 @@ static int zl3vni_del(zebra_l3vni_t *zl3vni) return 0; } -static int is_vni_l3(vni_t vni) -{ - zebra_l3vni_t *zl3vni = NULL; - - zl3vni = zl3vni_lookup(vni); - if (zl3vni) - return 1; - return 0; -} - static struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni) { struct zebra_ns *zns = NULL; @@ -5815,6 +5797,8 @@ int zebra_vxlan_if_down(struct interface *ifp) vni_t vni; struct zebra_if *zif = NULL; struct zebra_l2info_vxlan *vxl = NULL; + zebra_l3vni_t *zl3vni = NULL; + zebra_vni_t *zvni; /* Check if EVPN is enabled. */ if (!is_evpn_enabled()) @@ -5825,30 +5809,16 @@ int zebra_vxlan_if_down(struct interface *ifp) vxl = &zif->l2info.vxl; vni = vxl->vni; - - if (is_vni_l3(vni)) { - + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { /* process-if-down for l3-vni */ - zebra_l3vni_t *zl3vni = NULL; - if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp->name, ifp->ifindex, vni); - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - zlog_err( - "Failed to locate L3-VNI hash at DOWN, IF %s(%u) VNI %u", - ifp->name, ifp->ifindex, vni); - return -1; - } - zebra_vxlan_process_l3vni_oper_down(zl3vni); - } else { /* process if-down for l2-vni */ - zebra_vni_t *zvni; - if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp->name, ifp->ifindex, vni); @@ -5885,6 +5855,8 @@ int zebra_vxlan_if_up(struct interface *ifp) vni_t vni; struct zebra_if *zif = NULL; struct zebra_l2info_vxlan *vxl = NULL; + zebra_vni_t *zvni = NULL; + zebra_l3vni_t *zl3vni = NULL; /* Check if EVPN is enabled. */ if (!is_evpn_enabled()) @@ -5895,7 +5867,8 @@ int zebra_vxlan_if_up(struct interface *ifp) vxl = &zif->l2info.vxl; vni = vxl->vni; - if (is_vni_l3(vni)) { + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { /* Handle L3-VNI add */ zebra_l3vni_t *zl3vni = NULL; @@ -5904,14 +5877,6 @@ int zebra_vxlan_if_up(struct interface *ifp) zlog_debug("Intf %s(%u) L3-VNI %u is UP", ifp->name, ifp->ifindex, vni); - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - zlog_err( - "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u", - ifp->name, ifp->ifindex, vni); - return -1; - } - /* we need to associate with SVI, if any, we can associate with * svi-if only after association with vxlan-intf is complete */ @@ -5921,9 +5886,6 @@ int zebra_vxlan_if_up(struct interface *ifp) zebra_vxlan_process_l3vni_oper_up(zl3vni); } else { /* Handle L2-VNI add */ - - zebra_vni_t *zvni = NULL; - zebra_l3vni_t *zl3vni = NULL; struct interface *vlan_if = NULL; if (IS_ZEBRA_DEBUG_VXLAN) @@ -5969,6 +5931,8 @@ int zebra_vxlan_if_del(struct interface *ifp) vni_t vni; struct zebra_if *zif = NULL; struct zebra_l2info_vxlan *vxl = NULL; + zebra_vni_t *zvni = NULL; + zebra_l3vni_t *zl3vni = NULL; /* Check if EVPN is enabled. */ if (!is_evpn_enabled()) @@ -5979,7 +5943,8 @@ int zebra_vxlan_if_del(struct interface *ifp) vxl = &zif->l2info.vxl; vni = vxl->vni; - if (is_vni_l3(vni)) { + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { /* process if-del for l3-vni */ zebra_l3vni_t *zl3vni = NULL; @@ -5988,14 +5953,6 @@ int zebra_vxlan_if_del(struct interface *ifp) zlog_debug("Del L3-VNI %u intf %s(%u)", vni, ifp->name, ifp->ifindex); - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - zlog_err( - "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u", - ifp->name, ifp->ifindex, vni); - return 0; - } - /* process oper-down for l3-vni */ zebra_vxlan_process_l3vni_oper_down(zl3vni); @@ -6005,9 +5962,6 @@ int zebra_vxlan_if_del(struct interface *ifp) } else { /* process if-del for l2-vni*/ - zebra_vni_t *zvni = NULL; - zebra_l3vni_t *zl3vni = NULL; - if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("Del L2-VNI %u intf %s(%u)", vni, ifp->name, ifp->ifindex); @@ -6043,7 +5997,6 @@ int zebra_vxlan_if_del(struct interface *ifp) return -1; } } - return 0; } @@ -6055,6 +6008,8 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) vni_t vni; struct zebra_if *zif = NULL; struct zebra_l2info_vxlan *vxl = NULL; + zebra_vni_t *zvni = NULL; + zebra_l3vni_t *zl3vni = NULL; /* Check if EVPN is enabled. */ if (!is_evpn_enabled()) @@ -6065,16 +6020,8 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) vxl = &zif->l2info.vxl; vni = vxl->vni; - if (is_vni_l3(vni)) { - zebra_l3vni_t *zl3vni = NULL; - - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - zlog_err( - "Failed to find L3-VNI hash on update, IF %s(%u) VNI %u", - ifp->name, ifp->ifindex, vni); - return -1; - } + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( @@ -6110,7 +6057,6 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) zebra_vxlan_process_l3vni_oper_up(zl3vni); } } else { - zebra_vni_t *zvni = NULL; /* Update VNI hash. */ zvni = zvni_lookup(vni); @@ -6201,6 +6147,8 @@ int zebra_vxlan_if_add(struct interface *ifp) vni_t vni; struct zebra_if *zif = NULL; struct zebra_l2info_vxlan *vxl = NULL; + zebra_vni_t *zvni = NULL; + zebra_l3vni_t *zl3vni = NULL; /* Check if EVPN is enabled. */ if (!is_evpn_enabled()) @@ -6211,11 +6159,10 @@ int zebra_vxlan_if_add(struct interface *ifp) vxl = &zif->l2info.vxl; vni = vxl->vni; - if (is_vni_l3(vni)) { + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { /* process if-add for l3-vni*/ - zebra_l3vni_t *zl3vni = NULL; - if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u", @@ -6223,20 +6170,6 @@ int zebra_vxlan_if_add(struct interface *ifp) vxl->access_vlan, inet_ntoa(vxl->vtep_ip), zif->brslave_info.bridge_ifindex); - /* - * we expect the l3-vni has entry to be present here. - * The only place l3-vni is created in zebra is vrf-vni mapping - * command. This might change when we have the switchd support - * for l3-vxlan interface. - */ - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - zlog_err( - "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u", - ifp->name, ifp->ifindex, vni); - return 0; - } - /* associate with vxlan_if */ zl3vni->local_vtep_ip = vxl->vtep_ip; zl3vni->vxlan_if = ifp; @@ -6250,8 +6183,6 @@ int zebra_vxlan_if_add(struct interface *ifp) } else { /* process if-add for l2-vni */ - zebra_vni_t *zvni = NULL; - zebra_l3vni_t *zl3vni = NULL; struct interface *vlan_if = NULL; /* Create or update VNI hash. */ From 33c2ff625e0865a65713a81cc25cf8c8cc47d22f Mon Sep 17 00:00:00 2001 From: Mitesh Kanjariya Date: Fri, 26 Jan 2018 17:16:48 -0800 Subject: [PATCH 02/45] bgpd: support for filtering EVPN routes based on route-types. In many situations, it is desirable to only exchange EVPN routes of a particular type. For e.g., a common deployment scenario for large DCs is to sub-divide the DC into multiple PODs with full host mobility within a POD (i.e., all subnets provisioned on all leaf switches within the POD) but only do prefix-based routing across PODs. This can be achieved by only exchanging EVPN type-5 routes across PODs. Implement a policy to filter EVPN routes based on route type. Ticket: CM-19394 Review: CCR-7139 Testing: Manual Signed-off-by: Mitesh Kanjariya --- bgpd/bgp_routemap.c | 85 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 8c9f9f65ca..f5edcf381d 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -696,6 +696,58 @@ struct route_map_rule_cmd route_match_evpn_vni_cmd = { "evpn vni", route_match_vni, route_match_vni_compile, route_match_vni_free}; +/* `match evpn route-type' */ + +/* Match function should return 1 if match is success else return + zero. */ +static route_map_result_t route_match_evpn_route_type(void *rule, + struct prefix *prefix, + route_map_object_t type, + void *object) +{ + u_char route_type = 0; + + if (type == RMAP_BGP) { + route_type = *((u_char *)rule); + + if (route_type == prefix->u.prefix_evpn.route_type) + return RMAP_MATCH; + } + + return RMAP_NOMATCH; +} + +/* Route map `route-type' match statement. */ +static void *route_match_evpn_route_type_compile(const char *arg) +{ + u_char *route_type = NULL; + + route_type = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_char)); + if (!route_type) + return NULL; + + if (strncmp(arg, "ma", 2) == 0) + *route_type = BGP_EVPN_MAC_IP_ROUTE; + else if (strncmp(arg, "mu", 2) == 0) + *route_type = BGP_EVPN_IMET_ROUTE; + else + *route_type = BGP_EVPN_IP_PREFIX_ROUTE; + + return route_type; +} + +/* Free route map's compiled `route-type' value. */ +static void route_match_evpn_route_type_free(void *rule) +{ + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); +} + +/* Route map commands for evpn route-type matching. */ +struct route_map_rule_cmd route_match_evpn_route_type_cmd = { + "evpn route-type", route_match_evpn_route_type, + route_match_evpn_route_type_compile, + route_match_evpn_route_type_free}; + /* `match local-preference LOCAL-PREF' */ /* Match function return 1 if match is success else return zero. */ @@ -3132,6 +3184,36 @@ DEFUN (no_match_mac_address, RMAP_EVENT_FILTER_DELETED); } +DEFUN (match_evpn_route_type, + match_evpn_route_type_cmd, + "match evpn route-type {macip | multicast | prefix}", + MATCH_STR + EVPN_HELP_STR + "Match route-type\n" + "mac-ip route\n" + "IMET route\n" + "prefix route\n") +{ + return bgp_route_match_add(vty, "evpn route-type", argv[3]->arg, + RMAP_EVENT_MATCH_ADDED); +} + +DEFUN (no_match_evpn_route_type, + no_match_evpn_route_type_cmd, + "no match evpn route-type {macip | multicast | prefix}", + NO_STR + MATCH_STR + EVPN_HELP_STR + "Match route-type\n" + "mac-ip route\n" + "IMET route\n" + "prefix route\n") +{ + return bgp_route_match_delete(vty, "evpn route-type", argv[4]->arg, + RMAP_EVENT_MATCH_DELETED); +} + + DEFUN (match_evpn_vni, match_evpn_vni_cmd, "match evpn vni (1-16777215)", @@ -4534,6 +4616,7 @@ void bgp_route_map_init(void) route_map_install_match(&route_match_tag_cmd); route_map_install_match(&route_match_mac_address_cmd); route_map_install_match(&route_match_evpn_vni_cmd); + route_map_install_match(&route_match_evpn_route_type_cmd); route_map_install_set(&route_set_ip_nexthop_cmd); route_map_install_set(&route_set_local_pref_cmd); @@ -4568,6 +4651,8 @@ void bgp_route_map_init(void) install_element(RMAP_NODE, &no_match_mac_address_cmd); install_element(RMAP_NODE, &match_evpn_vni_cmd); install_element(RMAP_NODE, &no_match_evpn_vni_cmd); + install_element(RMAP_NODE, &match_evpn_route_type_cmd); + install_element(RMAP_NODE, &no_match_evpn_route_type_cmd); install_element(RMAP_NODE, &match_aspath_cmd); install_element(RMAP_NODE, &no_match_aspath_cmd); From 38503c09925265dc225cb64a5b3b9c64e2a5cc1a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sat, 27 Jan 2018 02:52:13 -0500 Subject: [PATCH 03/45] doc: Fix Debian 9 build instructions Using /var/run/frr as a localstate directory will allow debian9 to just delete that directory on every reboot. This causes issues for people who are new to the system in that FRR will just stop working on a reboot. Instead just point people at a better spot. Signed-off-by: Donald Sharp --- doc/Building_FRR_on_Debian9.md | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/doc/Building_FRR_on_Debian9.md b/doc/Building_FRR_on_Debian9.md index 1536c25932..e2d424a3ea 100644 --- a/doc/Building_FRR_on_Debian9.md +++ b/doc/Building_FRR_on_Debian9.md @@ -20,7 +20,7 @@ any packages** sudo addgroup --system --gid 92 frr sudo addgroup --system --gid 85 frrvty - sudo adduser --system --ingroup frr --home /var/run/frr/ \ + sudo adduser --system --ingroup frr --home /var/opt/frr/ \ --gecos "FRR suite" --shell /bin/false frr sudo usermod -a -G frrvty frr @@ -34,7 +34,7 @@ an example.) ./bootstrap.sh ./configure \ --enable-exampledir=/usr/share/doc/frr/examples/ \ - --localstatedir=/var/run/frr \ + --localstatedir=/var/opt/frr \ --sbindir=/usr/lib/frr \ --sysconfdir=/etc/frr \ --enable-vtysh \ @@ -61,6 +61,7 @@ an example.) ### Create empty FRR configuration files sudo install -m 755 -o frr -g frr -d /var/log/frr + sudo install -m 755 -o frr -g frr -d /var/opt/frr sudo install -m 775 -o frr -g frrvty -d /etc/frr sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf @@ -91,20 +92,6 @@ other settings) ### Troubleshooting -**Local state directory** - -The local state directory must exist and have the correct permissions applied -for the frrouting daemons to start. In the above ./configure example the -local state directory is set to /var/run/frr (--localstatedir=/var/run/frr) -Debian considers /var/run/frr to be temporary and this is removed after a -reboot. - -When using a different local state directory you need to create the new -directory and change the ownership to the frr user, for example: - - mkdir /var/opt/frr - chown frr /var/opt/frr - **Shared library error** If you try and start any of the frrouting daemons you may see the below error From 2aeb403d3750c1b5f41679a395e592c3371d84fa Mon Sep 17 00:00:00 2001 From: mitesh Date: Mon, 5 Feb 2018 13:51:45 -0800 Subject: [PATCH 04/45] zebra: fix SA issues Signed-off-by: Mitesh Kanjariya --- zebra/zebra_vxlan.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 0054555e5a..7f71f2a809 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -3415,6 +3415,9 @@ static struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni) struct zebra_if *zif = NULL; /* zebra_if for vxlan_if */ struct zebra_l2info_vxlan *vxl = NULL; /* l2 info for vxlan_if */ + if (!zl3vni) + return NULL; + if (!zl3vni->vxlan_if) return NULL; @@ -3587,6 +3590,9 @@ static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni) static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni) { + if (!zl3vni) + return; + if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("L3-VNI %u is UP - send add to BGP", zl3vni->vni); @@ -3597,6 +3603,9 @@ static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni) static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni) { + if (!zl3vni) + return; + if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("L3-VNI %u is Down - Send del to BGP", zl3vni->vni); @@ -5946,9 +5955,6 @@ int zebra_vxlan_if_del(struct interface *ifp) zl3vni = zl3vni_lookup(vni); if (zl3vni) { - /* process if-del for l3-vni */ - zebra_l3vni_t *zl3vni = NULL; - if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("Del L3-VNI %u intf %s(%u)", vni, ifp->name, ifp->ifindex); From d4ef18b6a797c568fc2d1de07b6984e497c4f0b5 Mon Sep 17 00:00:00 2001 From: mitesh Date: Mon, 5 Feb 2018 13:56:12 -0800 Subject: [PATCH 05/45] bgpd: match evpn route type command should use '<>' instead of '{}' Signed-off-by: Mitesh Kanjariya --- bgpd/bgp_routemap.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index f5edcf381d..597a01842e 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -723,8 +723,6 @@ static void *route_match_evpn_route_type_compile(const char *arg) u_char *route_type = NULL; route_type = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_char)); - if (!route_type) - return NULL; if (strncmp(arg, "ma", 2) == 0) *route_type = BGP_EVPN_MAC_IP_ROUTE; @@ -3186,7 +3184,7 @@ DEFUN (no_match_mac_address, DEFUN (match_evpn_route_type, match_evpn_route_type_cmd, - "match evpn route-type {macip | multicast | prefix}", + "match evpn route-type ", MATCH_STR EVPN_HELP_STR "Match route-type\n" @@ -3200,7 +3198,7 @@ DEFUN (match_evpn_route_type, DEFUN (no_match_evpn_route_type, no_match_evpn_route_type_cmd, - "no match evpn route-type {macip | multicast | prefix}", + "no match evpn route-type ", NO_STR MATCH_STR EVPN_HELP_STR From eb474e7313f4a6cb990dd13559718d57ac3b8aba Mon Sep 17 00:00:00 2001 From: mitesh Date: Mon, 5 Feb 2018 16:21:00 -0800 Subject: [PATCH 06/45] zebra: fix SA issues Signed-off-by: Mitesh Kanjariya --- zebra/zebra_vxlan.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 7f71f2a809..6a08ab8f80 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -5879,9 +5879,6 @@ int zebra_vxlan_if_up(struct interface *ifp) zl3vni = zl3vni_lookup(vni); if (zl3vni) { - /* Handle L3-VNI add */ - zebra_l3vni_t *zl3vni = NULL; - if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("Intf %s(%u) L3-VNI %u is UP", ifp->name, ifp->ifindex, vni); From aea175a8f41090ecd7fd1cf6bf1952e8ad8e3bc5 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 6 Feb 2018 18:48:09 -0500 Subject: [PATCH 07/45] ripd: Fix crash when ip rip split-horizon poisoned-reverse is configed The code was attempting to access a variable that would always be NULL. In fact this code has been broken since the rip ECMP changes were put into place a few years back. I'm going to come straight out and say that I don't fully understand this code. rinfo is the first item in the ecmp list and tmp_rinfo is used to iterate over all the items in the ecmp list. It sure looks like that the changes made here were just hacked together. So I modified the tmp_rinfo loop to just work on tmp_rinfo and the check that was crashing I modified to just use the rinfo since that what was checked originally in code before the ECMP was added. So consider this a hack job to stop the crashing. I think worse case is that we might be sending some routes back out interfaces it shouldn't be if you have ip rip split-horizon poisoned-reverse configured but that is less bad(tm) than crashing. Fixes: #1717 Signed-off-by: Donald Sharp --- ripd/ripd.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ripd/ripd.c b/ripd/ripd.c index b5cbc96bc3..9a13250428 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -2319,13 +2319,15 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to, tmp_rinfo)) if (tmp_rinfo->type == ZEBRA_ROUTE_RIP && tmp_rinfo->nh.ifindex - == ifc->ifp->ifindex) - rinfo->metric_out = + == ifc->ifp->ifindex) + tmp_rinfo->metric_out = RIP_METRIC_INFINITY; - if (tmp_rinfo->type == ZEBRA_ROUTE_CONNECT + + if (rinfo->type == ZEBRA_ROUTE_CONNECT && prefix_match((struct prefix *)p, ifc->address)) - rinfo->metric_out = RIP_METRIC_INFINITY; + rinfo->metric_out = + RIP_METRIC_INFINITY; } /* Prepare preamble, auth headers, if needs be */ From dfce9b257dcc915c5385b56fc52f20fcb4f57bc1 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 7 Feb 2018 18:22:15 -0500 Subject: [PATCH 08/45] zebra: Fix vrf routes from assuming their nh's were in the default Fix the read in of vrf routes on a start or restart that caused the nexthop_vrf to be assumed to be the default vrf. Signed-off-by: Donald Sharp --- zebra/zebra_vty.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 62869b7eec..5a5c455440 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -535,7 +535,11 @@ DEFPY(ip_route_address_interface_vrf, ifname = NULL; } - nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + if (nexthop_vrf) + nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + else + nh_zvrf = zvrf; + if (!nh_zvrf) { vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); @@ -642,7 +646,11 @@ DEFPY(ip_route_vrf, ifname = NULL; } - nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + if (nexthop_vrf) + nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + else + nh_zvrf = zvrf; + if (!nh_zvrf) { vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); @@ -2066,7 +2074,11 @@ DEFPY(ipv6_route_address_interface_vrf, struct zebra_vrf *zvrf = vrf->info; struct zebra_vrf *nh_zvrf; - nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + if (nexthop_vrf) + nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + else + nh_zvrf = zvrf; + if (!nh_zvrf) { vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); @@ -2160,7 +2172,11 @@ DEFPY(ipv6_route_vrf, struct zebra_vrf *zvrf = vrf->info; struct zebra_vrf *nh_zvrf; - nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + if (nexthop_vrf) + nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + else + nh_zvrf = zvrf; + if (!nh_zvrf) { vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); From f631926724417bc0b1ccb79a9344195950c3723d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 8 Feb 2018 13:51:04 -0500 Subject: [PATCH 09/45] debianpkg: Update build dependencies to say we don't co-exist with quagga The control files for all build platforms are not consistent. Signed-off-by: Donald Sharp --- debianpkg/backports/ubuntu12.04/debian/control | 2 +- debianpkg/backports/ubuntu14.04/debian/control | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/debianpkg/backports/ubuntu12.04/debian/control b/debianpkg/backports/ubuntu12.04/debian/control index 17ceeb0381..9bae348840 100644 --- a/debianpkg/backports/ubuntu12.04/debian/control +++ b/debianpkg/backports/ubuntu12.04/debian/control @@ -13,7 +13,7 @@ Package: frr Architecture: any Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), ${misc:Depends} Pre-Depends: adduser -Conflicts: zebra, zebra-pj +Conflicts: zebra, zebra-pj, quagga Replaces: zebra, zebra-pj Suggests: snmpd Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga diff --git a/debianpkg/backports/ubuntu14.04/debian/control b/debianpkg/backports/ubuntu14.04/debian/control index c22bd3bd58..3f31f18462 100644 --- a/debianpkg/backports/ubuntu14.04/debian/control +++ b/debianpkg/backports/ubuntu14.04/debian/control @@ -13,7 +13,7 @@ Package: frr Architecture: any Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), ${misc:Depends} Pre-Depends: adduser -Conflicts: zebra, zebra-pj +Conflicts: zebra, zebra-pj, quagga Replaces: zebra, zebra-pj Suggests: snmpd Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga From 400a663bf2d8003bc2d721a21c1355865b982d88 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 8 Feb 2018 19:30:34 -0500 Subject: [PATCH 10/45] zebra: sharp protocol needs a default admin distance. Signed-off-by: Donald Sharp --- zebra/zebra_rib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index b7b4a159da..39c3d0fadc 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -86,6 +86,7 @@ static const struct { [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20}, [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20}, [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100}, + [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150}, /* no entry/default: 150 */ }; From 4a7371e9e21569eee0e728f64ea06870d1aafa5e Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 8 Feb 2018 09:12:12 -0500 Subject: [PATCH 11/45] *: Track vrfs per nexthop not per route entry Track the vfrs on a per nexthop basis instead of on a per route entry basis. Signed-off-by: Donald Sharp --- babeld/kernel.c | 5 ++--- bgpd/bgp_zebra.c | 4 +--- bgpd/rfapi/vnc_zebra.c | 2 +- eigrpd/eigrp_zebra.c | 3 +-- isisd/isis_zebra.c | 4 ++-- lib/nexthop.c | 1 + lib/nexthop.h | 5 +++++ lib/zclient.c | 8 +++---- lib/zclient.h | 3 ++- nhrpd/nhrp_route.c | 2 +- ospf6d/ospf6_route.c | 1 + ospf6d/ospf6_zebra.c | 3 --- ospfd/ospf_zebra.c | 5 +---- ripd/rip_zebra.c | 2 +- ripngd/ripng_zebra.c | 2 +- sharpd/sharp_zebra.c | 3 +-- zebra/connected.c | 18 ++++++++------- zebra/kernel_socket.c | 6 +++-- zebra/rib.h | 20 ++++++++++------- zebra/rt_netlink.c | 38 ++++++++++++++++++++----------- zebra/rtread_getmsg.c | 6 ++--- zebra/zebra_mpls.c | 20 ++++++++++------- zebra/zebra_rib.c | 48 +++++++++++++++++++++++---------------- zebra/zebra_rnh.c | 1 - zebra/zebra_routemap.c | 2 +- zebra/zebra_static.c | 31 ++++++++++++------------- zebra/zebra_vty.c | 43 ++++++++++++++++++----------------- zebra/zserv.c | 51 +++++++++++++++++++++--------------------- 28 files changed, 185 insertions(+), 152 deletions(-) diff --git a/babeld/kernel.c b/babeld/kernel.c index 6b673c487c..8b1b80665c 100644 --- a/babeld/kernel.c +++ b/babeld/kernel.c @@ -166,7 +166,6 @@ zebra_route(int add, int family, const unsigned char *pref, unsigned short plen, api.type = ZEBRA_ROUTE_BABEL; api.safi = SAFI_UNICAST; api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.prefix = quagga_prefix; if(metric >= KERNEL_INFINITY) { @@ -175,8 +174,8 @@ zebra_route(int add, int family, const unsigned char *pref, unsigned short plen, SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api_nh->ifindex = ifindex; - - switch (family) { + api_nh->vrf_id = VRF_DEFAULT; + switch (family) { case AF_INET: uchar_to_inaddr(&api_nh->gate.ipv4, gate); if (IPV4_ADDR_SAME (&api_nh->gate.ipv4, &quagga_prefix.u.prefix4) && diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index e0bd74a206..acc66d0465 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1001,7 +1001,6 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, memset(&api, 0, sizeof(api)); memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr)); api.vrf_id = bgp->vrf_id; - api.nh_vrf_id = bgp->vrf_id; api.type = ZEBRA_ROUTE_BGP; api.safi = safi; api.prefix = *p; @@ -1081,7 +1080,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, api_nh = &api.nexthops[valid_nh_count]; api_nh->gate.ipv4 = *nexthop; - + api_nh->vrf_id = bgp->vrf_id; /* EVPN type-2 routes are programmed as onlink on l3-vni SVI */ @@ -1255,7 +1254,6 @@ void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info, safi_t safi) memset(&api, 0, sizeof(api)); memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr)); api.vrf_id = peer->bgp->vrf_id; - api.nh_vrf_id = peer->bgp->vrf_id; api.type = ZEBRA_ROUTE_BGP; api.safi = safi; api.prefix = *p; diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index 92d7e6fc76..6afcd21a10 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -396,7 +396,6 @@ static void vnc_zebra_route_msg(struct prefix *p, unsigned int nhp_count, memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_VNC; api.safi = SAFI_UNICAST; api.prefix = *p; @@ -407,6 +406,7 @@ static void vnc_zebra_route_msg(struct prefix *p, unsigned int nhp_count, for (i = 0; i < api.nexthop_num; i++) { api_nh = &api.nexthops[i]; + api_nh->vrf_id = VRF_DEFAULT; switch (p->family) { case AF_INET: memcpy(&api_nh->gate.ipv4, nhp_ary4[i], diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index f18d39d575..3759c64148 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -366,7 +366,6 @@ void eigrp_zebra_route_add(struct prefix *p, struct list *successors) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_EIGRP; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); @@ -378,6 +377,7 @@ void eigrp_zebra_route_add(struct prefix *p, struct list *successors) if (count >= MULTIPATH_NUM) break; api_nh = &api.nexthops[count]; + api_nh->vrf_id = VRF_DEFAULT; if (te->adv_router->src.s_addr) { api_nh->gate.ipv4 = te->adv_router->src; api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; @@ -408,7 +408,6 @@ void eigrp_zebra_route_delete(struct prefix *p) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_EIGRP; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 0512a18a2a..ac640c5e49 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -261,7 +261,6 @@ static void isis_zebra_route_add_route(struct prefix *prefix, memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_ISIS; api.safi = SAFI_UNICAST; api.prefix = *prefix; @@ -281,6 +280,7 @@ static void isis_zebra_route_add_route(struct prefix *prefix, if (count >= MULTIPATH_NUM) break; api_nh = &api.nexthops[count]; + api_nh->vrf_id = VRF_DEFAULT; /* FIXME: can it be ? */ if (nexthop->ip.s_addr != INADDR_ANY) { api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; @@ -303,6 +303,7 @@ static void isis_zebra_route_add_route(struct prefix *prefix, } api_nh = &api.nexthops[count]; + api_nh->vrf_id = VRF_DEFAULT; api_nh->gate.ipv6 = nexthop6->ip6; api_nh->ifindex = nexthop6->ifindex; api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; @@ -330,7 +331,6 @@ static void isis_zebra_route_del_route(struct prefix *prefix, memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_ISIS; api.safi = SAFI_UNICAST; api.prefix = *prefix; diff --git a/lib/nexthop.c b/lib/nexthop.c index f531f27302..a094c0e38d 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -167,6 +167,7 @@ void copy_nexthops(struct nexthop **tnh, struct nexthop *nh, for (nh1 = nh; nh1; nh1 = nh1->next) { nexthop = nexthop_new(); + nexthop->vrf_id = nh1->vrf_id; nexthop->ifindex = nh1->ifindex; nexthop->type = nh1->type; nexthop->flags = nh1->flags; diff --git a/lib/nexthop.h b/lib/nexthop.h index 753e66643d..ee4f569e83 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -60,6 +60,11 @@ struct nexthop { struct nexthop *next; struct nexthop *prev; + /* + * What vrf is this nexthop associated with? + */ + vrf_id_t vrf_id; + /* Interface index. */ ifindex_t ifindex; diff --git a/lib/zclient.c b/lib/zclient.c index 0c29b523bf..6882a7ecc5 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -975,12 +975,11 @@ int zapi_route_encode(u_char cmd, struct stream *s, struct zapi_route *api) } stream_putw(s, api->nexthop_num); - if (api->nexthop_num) - stream_putl(s, api->nh_vrf_id); for (i = 0; i < api->nexthop_num; i++) { api_nh = &api->nexthops[i]; + stream_putl(s, api_nh->vrf_id); stream_putc(s, api_nh->type); switch (api_nh->type) { case NEXTHOP_TYPE_BLACKHOLE: @@ -1126,12 +1125,10 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) return -1; } - if (api->nexthop_num) - STREAM_GETL(s, api->nh_vrf_id); - for (i = 0; i < api->nexthop_num; i++) { api_nh = &api->nexthops[i]; + STREAM_GETL(s, api_nh->vrf_id); STREAM_GETC(s, api_nh->type); switch (api_nh->type) { case NEXTHOP_TYPE_BLACKHOLE: @@ -1217,6 +1214,7 @@ struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh) struct nexthop *n = nexthop_new(); n->type = znh->type; + n->vrf_id = znh->vrf_id; n->ifindex = znh->ifindex; n->gate = znh->gate; diff --git a/lib/zclient.h b/lib/zclient.h index 5c7c5d6d5b..910d25aa2f 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -239,6 +239,7 @@ struct zserv_header { struct zapi_nexthop { enum nexthop_types_t type; + vrf_id_t vrf_id; ifindex_t ifindex; union { union g_addr gate; @@ -286,7 +287,6 @@ struct zapi_route { u_int32_t mtu; vrf_id_t vrf_id; - vrf_id_t nh_vrf_id; struct ethaddr rmac; }; @@ -505,6 +505,7 @@ static inline void zapi_route_set_blackhole(struct zapi_route *api, { api->nexthop_num = 1; api->nexthops[0].type = NEXTHOP_TYPE_BLACKHOLE; + api->nexthops[0].vrf_id = VRF_DEFAULT; api->nexthops[0].bh_type = bh_type; SET_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP); }; diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index 2f084f8422..d43aa4929e 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -96,7 +96,6 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix api.type = ZEBRA_ROUTE_NHRP; api.safi = SAFI_UNICAST; api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.prefix = *p; switch (type) { @@ -120,6 +119,7 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api_nh = &api.nexthops[0]; + api_nh->vrf_id = VRF_DEFAULT; switch (api.prefix.family) { case AF_INET: diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 735b28a693..19eb9a3fe6 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -315,6 +315,7 @@ void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route, if (i >= entries) return; + nexthops[i].vrf_id = VRF_DEFAULT; nexthops[i].ifindex = nh->ifindex; if (!IN6_IS_ADDR_UNSPECIFIED(&nh->address)) { nexthops[i].gate.ipv6 = nh->address; diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 2a419ddfc6..cc87c499ee 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -337,7 +337,6 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF6; api.safi = SAFI_UNICAST; api.prefix = *dest; @@ -388,7 +387,6 @@ void ospf6_zebra_add_discard(struct ospf6_route *request) if (!CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF6; api.safi = SAFI_UNICAST; api.prefix = *dest; @@ -422,7 +420,6 @@ void ospf6_zebra_delete_discard(struct ospf6_route *request) if (CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF6; api.safi = SAFI_UNICAST; api.prefix = *dest; diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 58e8a921d5..93aa603908 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -389,7 +389,6 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p, memset(&api, 0, sizeof(api)); api.vrf_id = ospf->vrf_id; - api.nh_vrf_id = ospf->vrf_id; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.safi = SAFI_UNICAST; @@ -442,6 +441,7 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p, api_nh->ifindex = path->ifindex; api_nh->type = NEXTHOP_TYPE_IFINDEX; } + api_nh->vrf_id = ospf->vrf_id; count++; if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { @@ -467,7 +467,6 @@ void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p, memset(&api, 0, sizeof(api)); api.vrf_id = ospf->vrf_id; - api.nh_vrf_id = ospf->vrf_id; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.safi = SAFI_UNICAST; @@ -489,7 +488,6 @@ void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p) memset(&api, 0, sizeof(api)); api.vrf_id = ospf->vrf_id; - api.nh_vrf_id = ospf->vrf_id; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.safi = SAFI_UNICAST; @@ -509,7 +507,6 @@ void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p) memset(&api, 0, sizeof(api)); api.vrf_id = ospf->vrf_id; - api.nh_vrf_id = ospf->vrf_id; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.safi = SAFI_UNICAST; diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index 52a5d93c4f..4f02daed42 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -48,7 +48,6 @@ static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_RIP; api.safi = SAFI_UNICAST; @@ -57,6 +56,7 @@ static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd) if (count >= MULTIPATH_NUM) break; api_nh = &api.nexthops[count]; + api_nh->vrf_id = VRF_DEFAULT; api_nh->gate = rinfo->nh.gate; api_nh->type = NEXTHOP_TYPE_IPV4; if (cmd == ZEBRA_ROUTE_ADD) diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index ea069d877f..6c9d911a6a 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -48,7 +48,6 @@ static void ripng_zebra_ipv6_send(struct route_node *rp, u_char cmd) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_RIPNG; api.safi = SAFI_UNICAST; api.prefix = rp->p; @@ -58,6 +57,7 @@ static void ripng_zebra_ipv6_send(struct route_node *rp, u_char cmd) if (count >= MULTIPATH_NUM) break; api_nh = &api.nexthops[count]; + api_nh->vrf_id = VRF_DEFAULT; api_nh->gate.ipv6 = rinfo->nexthop; api_nh->ifindex = rinfo->ifindex; api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index 25bb512a8b..10e48ac628 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -159,7 +159,6 @@ void route_add(struct prefix *p, struct nexthop *nh) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_SHARP; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); @@ -167,6 +166,7 @@ void route_add(struct prefix *p, struct nexthop *nh) SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api_nh = &api.nexthops[0]; + api_nh->vrf_id = VRF_DEFAULT; api_nh->gate.ipv4 = nh->gate.ipv4; api_nh->type = nh->type; api_nh->ifindex = nh->ifindex; @@ -181,7 +181,6 @@ void route_delete(struct prefix *p) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_SHARP; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); diff --git a/zebra/connected.c b/zebra/connected.c index d34fd9021a..e28ec8d09b 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -203,7 +203,9 @@ void connected_up(struct interface *ifp, struct connected *ifc) afi_t afi; struct prefix p; struct nexthop nh = { - .type = NEXTHOP_TYPE_IFINDEX, .ifindex = ifp->ifindex, + .type = NEXTHOP_TYPE_IFINDEX, + .ifindex = ifp->ifindex, + .vrf_id = ifp->vrf_id, }; if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) @@ -238,13 +240,11 @@ void connected_up(struct interface *ifp, struct connected *ifc) break; } - rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ifp->vrf_id, - ZEBRA_ROUTE_CONNECT, 0, 0, - &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); + rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p, + NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); - rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ifp->vrf_id, - ZEBRA_ROUTE_CONNECT, 0, 0, - &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); + rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p, + NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) { char buf[PREFIX_STRLEN]; @@ -362,7 +362,9 @@ void connected_down(struct interface *ifp, struct connected *ifc) afi_t afi; struct prefix p; struct nexthop nh = { - .type = NEXTHOP_TYPE_IFINDEX, .ifindex = ifp->ifindex, + .type = NEXTHOP_TYPE_IFINDEX, + .ifindex = ifp->ifindex, + .vrf_id = ifp->vrf_id, }; if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 2a3b95058e..7a64b48964 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -907,6 +907,8 @@ void rtm_read(struct rt_msghdr *rtm) SET_FLAG(zebra_flags, ZEBRA_FLAG_STATIC); memset(&nh, 0, sizeof(nh)); + + nh.vrf_id = VRF_DEFAULT; /* This is a reject or blackhole route */ if (flags & RTF_REJECT) { nh.type = NEXTHOP_TYPE_BLACKHOLE; @@ -1049,7 +1051,7 @@ void rtm_read(struct rt_msghdr *rtm) if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) - rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT, + rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, &nh, 0, 0, 0, 0, 0); else @@ -1097,7 +1099,7 @@ void rtm_read(struct rt_msghdr *rtm) if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) - rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT, + rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, &nh, 0, 0, 0, 0, 0); else diff --git a/zebra/rib.h b/zebra/rib.h index 664afd01b8..9a5d88ed15 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -59,7 +59,6 @@ struct route_entry { /* VRF identifier. */ vrf_id_t vrf_id; - vrf_id_t nh_vrf_id; /* Which routing table */ uint32_t table; @@ -231,22 +230,27 @@ typedef enum { } rib_update_event_t; extern struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *, - ifindex_t); + ifindex_t, + vrf_id_t nh_vrf_id); extern struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *, enum blackhole_type); extern struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *, struct in_addr *, - struct in_addr *); + struct in_addr *, + vrf_id_t nh_vrf_id); extern struct nexthop * route_entry_nexthop_ipv4_ifindex_add(struct route_entry *, struct in_addr *, - struct in_addr *, ifindex_t); + struct in_addr *, ifindex_t, + vrf_id_t nh_vrf_id); extern void route_entry_nexthop_delete(struct route_entry *re, struct nexthop *nexthop); extern struct nexthop *route_entry_nexthop_ipv6_add(struct route_entry *, - struct in6_addr *); + struct in6_addr *, + vrf_id_t nh_vrf_id); extern struct nexthop * route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re, - struct in6_addr *ipv6, ifindex_t ifindex); + struct in6_addr *ipv6, ifindex_t ifindex, + vrf_id_t nh_vrf_id); extern void route_entry_nexthop_add(struct route_entry *re, struct nexthop *nexthop); extern void route_entry_copy_nexthops(struct route_entry *re, @@ -294,8 +298,8 @@ extern void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re); /* NOTE: * All rib_add function will not just add prefix into RIB, but * also implicitly withdraw equal prefix of same type. */ -extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, vrf_id_t nh_vrf_id, - int type, u_short instance, int flags, struct prefix *p, +extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, + u_short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, u_int32_t table_id, u_int32_t metric, u_int32_t mtu, uint8_t distance, route_tag_t tag); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 20cc292e11..b8011c2a76 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -443,10 +443,10 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, if (ifp) nh_vrf_id = ifp->vrf_id; } + nh.vrf_id = nh_vrf_id; - rib_add(afi, SAFI_UNICAST, vrf_id, nh_vrf_id, proto, - 0, flags, &p, NULL, &nh, table, metric, - mtu, distance, tag); + rib_add(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p, + NULL, &nh, table, metric, mtu, distance, tag); } else { /* This is a multipath route */ @@ -463,13 +463,13 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, re->metric = metric; re->mtu = mtu; re->vrf_id = vrf_id; - re->nh_vrf_id = vrf_id; re->table = table; re->nexthop_num = 0; re->uptime = time(NULL); re->tag = tag; for (;;) { + vrf_id_t nh_vrf_id; if (len < (int)sizeof(*rtnh) || rtnh->rtnh_len > len) break; @@ -485,8 +485,17 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, ifp = if_lookup_by_index(index, VRF_UNKNOWN); if (ifp) - re->nh_vrf_id = ifp->vrf_id; - } + nh_vrf_id = ifp->vrf_id; + else { + zlog_warn( + "%s: Unknown interface %u specified, defaulting to VRF_DEFAULT", + __PRETTY_FUNCTION__, + index); + nh_vrf_id = VRF_DEFAULT; + } + } else + nh_vrf_id = vrf_id; + gate = 0; if (rtnh->rtnh_len > sizeof(*rtnh)) { memset(tb, 0, sizeof(tb)); @@ -503,24 +512,27 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, if (index) route_entry_nexthop_ipv4_ifindex_add( re, gate, - prefsrc, index); + prefsrc, index, + nh_vrf_id); else route_entry_nexthop_ipv4_add( re, gate, - prefsrc); + prefsrc, + nh_vrf_id); } else if (rtm->rtm_family == AF_INET6) { if (index) route_entry_nexthop_ipv6_ifindex_add( - re, gate, - index); + re, gate, index, + nh_vrf_id); else route_entry_nexthop_ipv6_add( - re, gate); + re, gate, + nh_vrf_id); } } else - route_entry_nexthop_ifindex_add(re, - index); + route_entry_nexthop_ifindex_add( + re, index, nh_vrf_id); len -= NLMSG_ALIGN(rtnh->rtnh_len); rtnh = RTNH_NEXT(rtnh); diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c index ba45f54ad2..95bc8db1c9 100644 --- a/zebra/rtread_getmsg.c +++ b/zebra/rtread_getmsg.c @@ -94,12 +94,12 @@ static void handle_route_entry(mib2_ipRouteEntry_t *routeEntry) prefix.prefixlen = ip_masklen(tmpaddr); memset(&nh, 0, sizeof(nh)); + nh.vrf_id = VRF_DEFAULT; nh.type = NEXTHOP_TYPE_IPV4; nh.gate.ipv4.s_addr = routeEntry->ipRouteNextHop; - rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT, - ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &prefix, NULL, - &nh, 0, 0, 0, 0, 0); + rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, + zebra_flags, &prefix, NULL, &nh, 0, 0, 0, 0, 0); } void route_read(struct zebra_ns *zns) diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 22c81b5784..485488d567 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -614,7 +614,7 @@ static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe, struct route_entry *match; struct nexthop *match_nh; - table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, VRF_DEFAULT); + table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, nexthop->vrf_id); if (!table) return 0; @@ -663,7 +663,7 @@ static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe, struct route_node *rn; struct route_entry *match; - table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT); + table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, nexthop->vrf_id); if (!table) return 0; @@ -728,7 +728,8 @@ static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe) case NEXTHOP_TYPE_IPV6_IFINDEX: if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) { - ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT); + ifp = if_lookup_by_index(nexthop->ifindex, + nexthop->vrf_id); if (ifp && if_is_operative(ifp)) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); else @@ -1149,6 +1150,7 @@ static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type, } nexthop_add_labels(nexthop, lsp_type, 1, &out_label); + nexthop->vrf_id = VRF_DEFAULT; nexthop->type = gtype; switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: @@ -1324,9 +1326,9 @@ static json_object *nhlfe_json(zebra_nhlfe_t *nhlfe) inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); if (nexthop->ifindex) - json_object_string_add( - json_nhlfe, "interface", - ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); + json_object_string_add(json_nhlfe, "interface", + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); break; default: break; @@ -1356,7 +1358,8 @@ static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty) vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4)); if (nexthop->ifindex) vty_out(vty, " dev %s", - ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -1364,7 +1367,8 @@ static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty) inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); if (nexthop->ifindex) vty_out(vty, " dev %s", - ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); break; default: break; diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index b7b4a159da..81244db9bf 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -212,13 +212,15 @@ void route_entry_nexthop_delete(struct route_entry *re, struct nexthop *nexthop) struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *re, - ifindex_t ifindex) + ifindex_t ifindex, + vrf_id_t nh_vrf_id) { struct nexthop *nexthop; nexthop = nexthop_new(); nexthop->type = NEXTHOP_TYPE_IFINDEX; nexthop->ifindex = ifindex; + nexthop->vrf_id = nh_vrf_id; route_entry_nexthop_add(re, nexthop); @@ -227,12 +229,14 @@ struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *re, struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *re, struct in_addr *ipv4, - struct in_addr *src) + struct in_addr *src, + vrf_id_t nh_vrf_id) { struct nexthop *nexthop; nexthop = nexthop_new(); nexthop->type = NEXTHOP_TYPE_IPV4; + nexthop->vrf_id = nh_vrf_id; nexthop->gate.ipv4 = *ipv4; if (src) nexthop->src.ipv4 = *src; @@ -245,18 +249,20 @@ struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *re, struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re, struct in_addr *ipv4, struct in_addr *src, - ifindex_t ifindex) + ifindex_t ifindex, + vrf_id_t nh_vrf_id) { struct nexthop *nexthop; struct interface *ifp; nexthop = nexthop_new(); + nexthop->vrf_id = nh_vrf_id; nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX; nexthop->gate.ipv4 = *ipv4; if (src) nexthop->src.ipv4 = *src; nexthop->ifindex = ifindex; - ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id); + ifp = if_lookup_by_index(nexthop->ifindex, nh_vrf_id); /*Pending: need to think if null ifp here is ok during bootup? There was a crash because ifp here was coming to be NULL */ if (ifp) @@ -271,11 +277,13 @@ struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re, } struct nexthop *route_entry_nexthop_ipv6_add(struct route_entry *re, - struct in6_addr *ipv6) + struct in6_addr *ipv6, + vrf_id_t nh_vrf_id) { struct nexthop *nexthop; nexthop = nexthop_new(); + nexthop->vrf_id = nh_vrf_id; nexthop->type = NEXTHOP_TYPE_IPV6; nexthop->gate.ipv6 = *ipv6; @@ -286,11 +294,13 @@ struct nexthop *route_entry_nexthop_ipv6_add(struct route_entry *re, struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re, struct in6_addr *ipv6, - ifindex_t ifindex) + ifindex_t ifindex, + vrf_id_t nh_vrf_id) { struct nexthop *nexthop; nexthop = nexthop_new(); + nexthop->vrf_id = nh_vrf_id; nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX; nexthop->gate.ipv6 = *ipv6; nexthop->ifindex = ifindex; @@ -306,6 +316,7 @@ struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *re, struct nexthop *nexthop; nexthop = nexthop_new(); + nexthop->vrf_id = VRF_DEFAULT; nexthop->type = NEXTHOP_TYPE_BLACKHOLE; nexthop->bh_type = bh_type; @@ -322,6 +333,7 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop, resolved_hop = nexthop_new(); SET_FLAG(resolved_hop->flags, NEXTHOP_FLAG_ACTIVE); + resolved_hop->vrf_id = nexthop->vrf_id; switch (newhop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: @@ -403,7 +415,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, if (set) { UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - zebra_deregister_rnh_static_nexthops(re->nh_vrf_id, + zebra_deregister_rnh_static_nexthops(nexthop->vrf_id, nexthop->resolved, top); nexthops_free(nexthop->resolved); nexthop->resolved = NULL; @@ -422,7 +434,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, * address in the routing table. */ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) { - ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id); + ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id); if (ifp && connected_is_unnumbered(ifp)) { if (if_is_operative(ifp)) return 1; @@ -450,7 +462,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, break; } /* Lookup table. */ - table = zebra_vrf_table(afi, SAFI_UNICAST, re->nh_vrf_id); + table = zebra_vrf_table(afi, SAFI_UNICAST, nexthop->vrf_id); if (!table) return 0; @@ -838,7 +850,7 @@ static unsigned nexthop_active_check(struct route_node *rn, family = 0; switch (nexthop->type) { case NEXTHOP_TYPE_IFINDEX: - ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id); + ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id); if (ifp && if_is_operative(ifp)) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); else @@ -867,7 +879,7 @@ static unsigned nexthop_active_check(struct route_node *rn, family = AFI_IP6; if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) { ifp = if_lookup_by_index(nexthop->ifindex, - re->nh_vrf_id); + nexthop->vrf_id); if (ifp && if_is_operative(ifp)) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); else @@ -910,8 +922,8 @@ static unsigned nexthop_active_check(struct route_node *rn, memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr)); /* It'll get set if required inside */ - ret = zebra_route_map_check(family, re->type, p, nexthop, re->nh_vrf_id, - re->tag); + ret = zebra_route_map_check(family, re->type, p, nexthop, + nexthop->vrf_id, re->tag); if (ret == RMAP_DENYMATCH) { if (IS_ZEBRA_DEBUG_RIB) { srcdest_rnode2str(rn, buf, sizeof(buf)); @@ -919,7 +931,7 @@ static unsigned nexthop_active_check(struct route_node *rn, "%u:%s: Filtering out with NH out %s due to route map", re->vrf_id, buf, ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + nexthop->vrf_id)); } UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); } @@ -2554,10 +2566,9 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, } -int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, vrf_id_t nh_vrf_id, - int type, u_short instance, int flags, struct prefix *p, - struct prefix_ipv6 *src_p, const struct nexthop *nh, - u_int32_t table_id, u_int32_t metric, +int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, + int flags, struct prefix *p, struct prefix_ipv6 *src_p, + const struct nexthop *nh, u_int32_t table_id, u_int32_t metric, u_int32_t mtu, uint8_t distance, route_tag_t tag) { struct route_entry *re; @@ -2573,7 +2584,6 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, vrf_id_t nh_vrf_id, re->mtu = mtu; re->table = table_id; re->vrf_id = vrf_id; - re->nh_vrf_id = nh_vrf_id; re->nexthop_num = 0; re->uptime = time(NULL); re->tag = tag; diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index cea46ffc18..dfac8807aa 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -952,7 +952,6 @@ static void copy_state(struct rnh *rnh, struct route_entry *re, state->distance = re->distance; state->metric = re->metric; state->vrf_id = re->vrf_id; - state->nh_vrf_id = re->vrf_id; route_entry_copy_nexthops(state, re->nexthop); rnh->state = state; diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 4c619e5782..882a03f844 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -1329,7 +1329,7 @@ route_map_result_t zebra_nht_route_map_check(int family, int client_proto, struct nh_rmap_obj nh_obj; nh_obj.nexthop = nexthop; - nh_obj.vrf_id = re->nh_vrf_id; + nh_obj.vrf_id = nexthop->vrf_id; nh_obj.source_protocol = re->type; nh_obj.metric = re->metric; nh_obj.tag = re->tag; diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c index 2e8ab11b04..b42bd818af 100644 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@ -87,7 +87,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, switch (si->type) { case STATIC_IPV4_GATEWAY: nexthop = route_entry_nexthop_ipv4_add( - re, &si->addr.ipv4, NULL); + re, &si->addr.ipv4, NULL, si->nh_vrf_id); nh_p.family = AF_INET; nh_p.prefixlen = IPV4_MAX_BITLEN; nh_p.u.prefix4 = si->addr.ipv4; @@ -95,19 +95,20 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, break; case STATIC_IPV4_GATEWAY_IFNAME: nexthop = route_entry_nexthop_ipv4_ifindex_add( - re, &si->addr.ipv4, NULL, si->ifindex); + re, &si->addr.ipv4, NULL, si->ifindex, + si->nh_vrf_id); break; case STATIC_IFNAME: - nexthop = route_entry_nexthop_ifindex_add(re, - si->ifindex); + nexthop = route_entry_nexthop_ifindex_add( + re, si->ifindex, si->nh_vrf_id); break; case STATIC_BLACKHOLE: nexthop = route_entry_nexthop_blackhole_add( re, bh_type); break; case STATIC_IPV6_GATEWAY: - nexthop = route_entry_nexthop_ipv6_add(re, - &si->addr.ipv6); + nexthop = route_entry_nexthop_ipv6_add( + re, &si->addr.ipv6, si->nh_vrf_id); nh_p.family = AF_INET6; nh_p.prefixlen = IPV6_MAX_BITLEN; nh_p.u.prefix6 = si->addr.ipv6; @@ -115,7 +116,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, break; case STATIC_IPV6_GATEWAY_IFNAME: nexthop = route_entry_nexthop_ipv6_ifindex_add( - re, &si->addr.ipv6, si->ifindex); + re, &si->addr.ipv6, si->ifindex, si->nh_vrf_id); break; } /* Update label(s), if present. */ @@ -155,7 +156,6 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, re->metric = 0; re->mtu = 0; re->vrf_id = si->vrf_id; - re->nh_vrf_id = si->nh_vrf_id; re->table = (si->vrf_id != VRF_DEFAULT) ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id @@ -166,7 +166,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, switch (si->type) { case STATIC_IPV4_GATEWAY: nexthop = route_entry_nexthop_ipv4_add( - re, &si->addr.ipv4, NULL); + re, &si->addr.ipv4, NULL, si->nh_vrf_id); nh_p.family = AF_INET; nh_p.prefixlen = IPV4_MAX_BITLEN; nh_p.u.prefix4 = si->addr.ipv4; @@ -174,19 +174,20 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, break; case STATIC_IPV4_GATEWAY_IFNAME: nexthop = route_entry_nexthop_ipv4_ifindex_add( - re, &si->addr.ipv4, NULL, si->ifindex); + re, &si->addr.ipv4, NULL, si->ifindex, + si->nh_vrf_id); break; case STATIC_IFNAME: - nexthop = route_entry_nexthop_ifindex_add(re, - si->ifindex); + nexthop = route_entry_nexthop_ifindex_add( + re, si->ifindex, si->nh_vrf_id); break; case STATIC_BLACKHOLE: nexthop = route_entry_nexthop_blackhole_add( re, bh_type); break; case STATIC_IPV6_GATEWAY: - nexthop = route_entry_nexthop_ipv6_add(re, - &si->addr.ipv6); + nexthop = route_entry_nexthop_ipv6_add( + re, &si->addr.ipv6, si->nh_vrf_id); nh_p.family = AF_INET6; nh_p.prefixlen = IPV6_MAX_BITLEN; nh_p.u.prefix6 = si->addr.ipv6; @@ -194,7 +195,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, break; case STATIC_IPV6_GATEWAY_IFNAME: nexthop = route_entry_nexthop_ipv6_ifindex_add( - re, &si->addr.ipv6, si->ifindex); + re, &si->addr.ipv6, si->ifindex, si->nh_vrf_id); break; } /* Update label(s), if present. */ diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 93397afa79..3f6db5986f 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -770,8 +770,9 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, inet_ntoa(nexthop->gate.ipv4)); if (nexthop->ifindex) vty_out(vty, ", via %s", - ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + ifindex2ifname( + nexthop->ifindex, + nexthop->vrf_id)); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -780,13 +781,14 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, buf, sizeof buf)); if (nexthop->ifindex) vty_out(vty, ", via %s", - ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + ifindex2ifname( + nexthop->ifindex, + nexthop->vrf_id)); break; case NEXTHOP_TYPE_IFINDEX: vty_out(vty, " directly connected, %s", ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + nexthop->vrf_id)); break; case NEXTHOP_TYPE_BLACKHOLE: vty_out(vty, " unreachable"); @@ -809,9 +811,9 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, break; } - if (re->vrf_id != re->nh_vrf_id) { + if (re->vrf_id != nexthop->vrf_id) { struct vrf *vrf = - vrf_lookup_by_id(re->nh_vrf_id); + vrf_lookup_by_id(nexthop->vrf_id); vty_out(vty, "(vrf %s)", vrf->name); } @@ -954,8 +956,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, nexthop->ifindex); json_object_string_add( json_nexthop, "interfaceName", - ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + ifindex2ifname( + nexthop->ifindex, + nexthop->vrf_id)); } break; case NEXTHOP_TYPE_IPV6: @@ -973,8 +976,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, nexthop->ifindex); json_object_string_add( json_nexthop, "interfaceName", - ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + ifindex2ifname( + nexthop->ifindex, + nexthop->vrf_id)); } break; @@ -987,7 +991,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, json_object_string_add( json_nexthop, "interfaceName", ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + nexthop->vrf_id)); break; case NEXTHOP_TYPE_BLACKHOLE: json_object_boolean_true_add(json_nexthop, @@ -1014,9 +1018,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, break; } - if (re->nh_vrf_id != re->vrf_id) { + if (nexthop->vrf_id != re->vrf_id) { struct vrf *vrf = - vrf_lookup_by_id(re->nh_vrf_id); + vrf_lookup_by_id(nexthop->vrf_id); json_object_string_add(json_nexthop, "vrf", @@ -1129,7 +1133,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, if (nexthop->ifindex) vty_out(vty, ", %s", ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + nexthop->vrf_id)); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -1139,13 +1143,13 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, if (nexthop->ifindex) vty_out(vty, ", %s", ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + nexthop->vrf_id)); break; case NEXTHOP_TYPE_IFINDEX: vty_out(vty, " is directly connected, %s", ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + nexthop->vrf_id)); break; case NEXTHOP_TYPE_BLACKHOLE: vty_out(vty, " unreachable"); @@ -1167,9 +1171,8 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, break; } - if (re->nh_vrf_id != re->vrf_id) { - struct vrf *vrf = - vrf_lookup_by_id(re->nh_vrf_id); + if (nexthop->vrf_id != re->vrf_id) { + struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id); vty_out(vty, "(vrf %s)", vrf->name); } diff --git a/zebra/zserv.c b/zebra/zserv.c index 71437bab15..9da8d593e5 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -592,7 +592,6 @@ int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p, memset(&api, 0, sizeof(api)); api.vrf_id = re->vrf_id; - api.nh_vrf_id = re->nh_vrf_id; api.type = re->type; api.instance = re->instance; api.flags = re->flags; @@ -614,6 +613,7 @@ int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p, continue; api_nh = &api.nexthops[count]; + api_nh->vrf_id = nexthop->vrf_id; api_nh->type = nexthop->type; switch (nexthop->type) { case NEXTHOP_TYPE_BLACKHOLE: @@ -1137,7 +1137,6 @@ static int zread_route_add(struct zserv *client, u_short length, re->flags = api.flags; re->uptime = time(NULL); re->vrf_id = vrf_id; - re->nh_vrf_id = api.nh_vrf_id; re->table = zvrf->table_id; if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { @@ -1148,11 +1147,12 @@ static int zread_route_add(struct zserv *client, u_short length, switch (api_nh->type) { case NEXTHOP_TYPE_IFINDEX: nexthop = route_entry_nexthop_ifindex_add( - re, api_nh->ifindex); + re, api_nh->ifindex, re->vrf_id); break; case NEXTHOP_TYPE_IPV4: nexthop = route_entry_nexthop_ipv4_add( - re, &api_nh->gate.ipv4, NULL); + re, &api_nh->gate.ipv4, NULL, + re->vrf_id); break; case NEXTHOP_TYPE_IPV4_IFINDEX: { @@ -1168,8 +1168,8 @@ static int zread_route_add(struct zserv *client, u_short length, } nexthop = route_entry_nexthop_ipv4_ifindex_add( - re, &api_nh->gate.ipv4, NULL, - ifindex); + re, &api_nh->gate.ipv4, NULL, ifindex, + re->vrf_id); /* if this an EVPN route entry, program the nh as neigh @@ -1192,12 +1192,12 @@ static int zread_route_add(struct zserv *client, u_short length, } case NEXTHOP_TYPE_IPV6: nexthop = route_entry_nexthop_ipv6_add( - re, &api_nh->gate.ipv6); + re, &api_nh->gate.ipv6, re->vrf_id); break; case NEXTHOP_TYPE_IPV6_IFINDEX: nexthop = route_entry_nexthop_ipv6_ifindex_add( - re, &api_nh->gate.ipv6, - api_nh->ifindex); + re, &api_nh->gate.ipv6, api_nh->ifindex, + re->vrf_id); break; case NEXTHOP_TYPE_BLACKHOLE: nexthop = route_entry_nexthop_blackhole_add( @@ -1364,7 +1364,6 @@ static int zread_ipv4_add(struct zserv *client, u_short length, /* VRF ID */ re->vrf_id = zvrf_id(zvrf); - re->nh_vrf_id = zvrf_id(zvrf); /* Nexthop parse. */ if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) { @@ -1381,13 +1380,14 @@ static int zread_ipv4_add(struct zserv *client, u_short length, switch (nexthop_type) { case NEXTHOP_TYPE_IFINDEX: STREAM_GETL(s, ifindex); - route_entry_nexthop_ifindex_add(re, ifindex); + route_entry_nexthop_ifindex_add(re, ifindex, + re->vrf_id); break; case NEXTHOP_TYPE_IPV4: STREAM_GET(&nhop_addr.s_addr, s, IPV4_MAX_BYTELEN); nexthop = route_entry_nexthop_ipv4_add( - re, &nhop_addr, NULL); + re, &nhop_addr, NULL, re->vrf_id); /* For labeled-unicast, each nexthop is followed * by label. */ if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) { @@ -1401,7 +1401,8 @@ static int zread_ipv4_add(struct zserv *client, u_short length, IPV4_MAX_BYTELEN); STREAM_GETL(s, ifindex); route_entry_nexthop_ipv4_ifindex_add( - re, &nhop_addr, NULL, ifindex); + re, &nhop_addr, NULL, ifindex, + re->vrf_id); break; case NEXTHOP_TYPE_IPV6: zlog_warn("%s: Please use ZEBRA_ROUTE_ADD if you want to pass v6 nexthops", @@ -1574,7 +1575,6 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, /* VRF ID */ re->vrf_id = zvrf_id(zvrf); - re->nh_vrf_id = zvrf_id(zvrf); /* We need to give nh-addr, nh-ifindex with the same next-hop object * to the re to ensure that IPv6 multipathing works; need to coalesce @@ -1635,10 +1635,11 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, nexthop = route_entry_nexthop_ipv6_ifindex_add( re, &nexthops[i], - ifindices[i]); + ifindices[i], + re->vrf_id); else nexthop = route_entry_nexthop_ipv6_add( - re, &nexthops[i]); + re, &nexthops[i], re->vrf_id); if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) nexthop_add_labels(nexthop, label_type, @@ -1646,7 +1647,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, } else { if ((i < if_count) && ifindices[i]) route_entry_nexthop_ifindex_add( - re, ifindices[i]); + re, ifindices[i], re->vrf_id); } } } @@ -1760,6 +1761,9 @@ static int zread_ipv6_add(struct zserv *client, u_short length, } else src_pp = NULL; + /* VRF ID */ + re->vrf_id = zvrf_id(zvrf); + /* We need to give nh-addr, nh-ifindex with the same next-hop object * to the re to ensure that IPv6 multipathing works; need to coalesce * these. Clients should send the same number of paired set of @@ -1797,7 +1801,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length, STREAM_GET(&nhop_addr, s, 16); STREAM_GETL(s, ifindex); route_entry_nexthop_ipv6_ifindex_add( - re, &nhop_addr, ifindex); + re, &nhop_addr, ifindex, re->vrf_id); break; case NEXTHOP_TYPE_IFINDEX: if (if_count < multipath_num) { @@ -1824,17 +1828,18 @@ static int zread_ipv6_add(struct zserv *client, u_short length, nexthop = route_entry_nexthop_ipv6_ifindex_add( re, &nexthops[i], - ifindices[i]); + ifindices[i], + re->vrf_id); else nexthop = route_entry_nexthop_ipv6_add( - re, &nexthops[i]); + re, &nexthops[i], re->vrf_id); if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) nexthop_add_labels(nexthop, label_type, 1, &labels[i]); } else { if ((i < if_count) && ifindices[i]) route_entry_nexthop_ifindex_add( - re, ifindices[i]); + re, ifindices[i], re->vrf_id); } } } @@ -1858,10 +1863,6 @@ static int zread_ipv6_add(struct zserv *client, u_short length, else re->mtu = 0; - /* VRF ID */ - re->vrf_id = zvrf_id(zvrf); - re->nh_vrf_id = zvrf_id(zvrf); - re->table = zvrf->table_id; ret = rib_add_multipath(AFI_IP6, safi, &p, src_pp, re); From 44bdf1590d4eccb8764f2c6f5de48c59e3eff9c2 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 24 Jan 2018 15:35:37 -0500 Subject: [PATCH 12/45] lib, zebra: Move nh_resolve_via_default to appropriate header The nh_resolve_via_default function is an accessor function for NHT in zebra. Let's move this function to it's proper place. Signed-off-by: Donald Sharp --- lib/nexthop.h | 12 ------------ zebra/zebra_rib.c | 2 +- zebra/zebra_rnh.c | 2 +- zebra/zebra_rnh.h | 9 +++++++++ 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/lib/nexthop.h b/lib/nexthop.h index ee4f569e83..b502f293bc 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -121,18 +121,6 @@ struct nexthop { (nexthop); \ (nexthop) = nexthop_next(nexthop) -extern int zebra_rnh_ip_default_route; -extern int zebra_rnh_ipv6_default_route; - -static inline int nh_resolve_via_default(int family) -{ - if (((family == AF_INET) && zebra_rnh_ip_default_route) - || ((family == AF_INET6) && zebra_rnh_ipv6_default_route)) - return 1; - else - return 0; -} - struct nexthop *nexthop_new(void); void nexthop_add(struct nexthop **target, struct nexthop *nexthop); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 81244db9bf..8ac9d08f29 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -484,7 +484,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, /* However, do not resolve over default route unless explicitly * allowed. */ if (is_default_prefix(&rn->p) - && !nh_resolve_via_default(p.family)) + && !rnh_resolve_via_default(p.family)) return 0; dest = rib_dest_from_rnode(rn); diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index dfac8807aa..9fc5afff0f 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -659,7 +659,7 @@ static struct route_entry *zebra_rnh_resolve_nexthop_entry(vrf_id_t vrfid, * match route to be exact if so specified */ if (is_default_prefix(&rn->p) && - !nh_resolve_via_default(rn->p.family)) + !rnh_resolve_via_default(rn->p.family)) return NULL; /* Identify appropriate route entry. */ diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index 7e183684da..bd121ec83c 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -54,6 +54,15 @@ typedef enum { RNH_NEXTHOP_TYPE, RNH_IMPORT_CHECK_TYPE } rnh_type_t; extern int zebra_rnh_ip_default_route; extern int zebra_rnh_ipv6_default_route; +static inline int rnh_resolve_via_default(int family) +{ + if (((family == AF_INET) && zebra_rnh_ip_default_route) + || ((family == AF_INET6) && zebra_rnh_ipv6_default_route)) + return 1; + else + return 0; +} + extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type); extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, From c83c5e4482580351d20fb45dc643c368866e33d8 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 30 Jan 2018 13:30:36 -0500 Subject: [PATCH 13/45] lib, zebra: Add new api to specify a label associated with the vrf For L3VPN's we need to create a label associated with the specified vrf to be installed into the kernel to allow a pop and lookup operation. The new api is: zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, mpls_label_t label); For the specified vrf_id associate the specified label for a pop and lookup operation for forwarding. To setup a POP and Forward use MPLS_LABEL_IMPLICIT_NULL If the same label is passed in we ignore the call. If the label is different we update entry. If the label is MPLS_LABEL_NONE we remove the entry. This sets up the api. Future commits will have the functionality to actually install into the kernel. Signed-off-by: Donald Sharp --- lib/log.c | 1 + lib/zclient.c | 14 ++++++++++++++ lib/zclient.h | 12 ++++++++++++ zebra/zebra_vrf.h | 3 +++ zebra/zserv.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+) diff --git a/lib/log.c b/lib/log.c index 66be533e84..9fc19ff683 100644 --- a/lib/log.c +++ b/lib/log.c @@ -929,6 +929,7 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_VRF_UNREGISTER), DESC_ENTRY(ZEBRA_VRF_ADD), DESC_ENTRY(ZEBRA_VRF_DELETE), + DESC_ENTRY(ZEBRA_VRF_LABEL), DESC_ENTRY(ZEBRA_INTERFACE_VRF_UPDATE), DESC_ENTRY(ZEBRA_BFD_CLIENT_REGISTER), DESC_ENTRY(ZEBRA_INTERFACE_ENABLE_RADV), diff --git a/lib/zclient.c b/lib/zclient.c index 6882a7ecc5..9327201f73 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -363,6 +363,20 @@ static int zebra_hello_send(struct zclient *zclient) return 0; } +void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, + mpls_label_t label) +{ + struct stream *s; + + s = zclient->obuf; + stream_reset(s); + + zclient_create_header(s, ZEBRA_VRF_LABEL, vrf_id); + stream_putl(s, label); + stream_putw_at(s, 0, stream_get_endp(s)); + zclient_send_message(zclient); +} + /* Send register requests to zebra daemon for the information in a VRF. */ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id) { diff --git a/lib/zclient.h b/lib/zclient.h index 910d25aa2f..6b39a2713a 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -93,6 +93,7 @@ typedef enum { ZEBRA_VRF_UNREGISTER, ZEBRA_VRF_ADD, ZEBRA_VRF_DELETE, + ZEBRA_VRF_LABEL, ZEBRA_INTERFACE_VRF_UPDATE, ZEBRA_BFD_CLIENT_REGISTER, ZEBRA_INTERFACE_ENABLE_RADV, @@ -382,6 +383,17 @@ extern u_short *redist_check_instance(struct redist_proto *, u_short); extern void redist_add_instance(struct redist_proto *, u_short); extern void redist_del_instance(struct redist_proto *, u_short); +/* + * Send to zebra that the specified vrf is using label to resolve + * itself for L3VPN's. Repeated calls of this function with + * different labels will cause an effective update of the + * label for lookup. If you pass in MPLS_V4_EXP_NULL_LABEL + * we will cause a delete action and remove this label pop + * operation. + */ +extern void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, + mpls_label_t label); + extern void zclient_send_reg_requests(struct zclient *, vrf_id_t); extern void zclient_send_dereg_requests(struct zclient *, vrf_id_t); diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index fe7e77e8be..bfeb4b386c 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -79,6 +79,9 @@ struct zebra_vrf { */ struct zebra_ns *zns; + /* MPLS Label to handle L3VPN <-> vrf popping */ + mpls_label_t label; + /* MPLS static LSP config table */ struct hash *slsp_table; diff --git a/zebra/zserv.c b/zebra/zserv.c index 9da8d593e5..5f2757f52c 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2486,6 +2486,51 @@ stream_failure: return 1; } +static void zread_vrf_label(struct zserv *client, + struct zebra_vrf *zvrf) +{ + struct interface *ifp; + mpls_label_t nlabel; + struct stream *s; + struct zebra_vrf *def_zvrf; + + s = client->ibuf; + STREAM_GETL(s, nlabel); + + if (nlabel == zvrf->label) { + /* + * Nothing to do here move along + */ + return; + } + + if (zvrf->vrf->vrf_id != VRF_DEFAULT) + ifp = if_lookup_by_name(zvrf->vrf->name, zvrf->vrf->vrf_id); + else + ifp = if_lookup_by_name("lo", VRF_DEFAULT); + + if (!ifp) { + zlog_debug("Unable to find specified Interface for %s", + zvrf->vrf->name); + return; + } + + def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); + + if (zvrf->label != MPLS_LABEL_IPV4NULL) + mpls_lsp_uninstall(def_zvrf, ZEBRA_LSP_STATIC, + zvrf->label, NEXTHOP_TYPE_IFINDEX, + NULL, ifp->ifindex); + + if (nlabel != MPLS_LABEL_IPV4NULL) + mpls_lsp_install(def_zvrf, ZEBRA_LSP_STATIC, nlabel, + MPLS_LABEL_IMPLICIT_NULL, NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); + + zvrf->label = nlabel; +stream_failure: + return; +} + static inline void zserv_handle_commands(struct zserv *client, uint16_t command, uint16_t length, @@ -2570,6 +2615,9 @@ static inline void zserv_handle_commands(struct zserv *client, case ZEBRA_VRF_UNREGISTER: zread_vrf_unregister(client, length, zvrf); break; + case ZEBRA_VRF_LABEL: + zread_vrf_label(client, zvrf); + break; case ZEBRA_BFD_CLIENT_REGISTER: zebra_ptm_bfd_client_register(client, length); break; From ab18a4954fc892a668e6eb4a39e249135d91bd1b Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 30 Jan 2018 13:54:38 -0500 Subject: [PATCH 14/45] sharpd: Add some infrastructure to allow test of ZEBRA_VRF_LABEL Add some infrastructure to allow the testing of ZEBRA_VRF_LABEL Signed-off-by: Donald Sharp --- sharpd/sharp_vty.c | 27 +++++++++++++++++++++++++++ sharpd/sharp_zebra.c | 5 +++++ sharpd/sharp_zebra.h | 1 + 3 files changed, 33 insertions(+) diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index a35157faa1..efbe989721 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -26,6 +26,8 @@ #include "prefix.h" #include "nexthop.h" #include "log.h" +#include "vrf.h" +#include "zclient.h" #include "sharpd/sharp_zebra.h" #include "sharpd/sharp_vty.h" @@ -76,6 +78,30 @@ DEFPY (install_routes, return CMD_SUCCESS; } +DEFPY(vrf_label, + vrf_label_cmd, + "label vrf NAME$name label (0-100000)$label", + "Give a vrf a label\n" + VRF_CMD_HELP_STR + "The label to use\n" + "Specified range to use\n") +{ + struct vrf *vrf; + + if (strcmp(name, "default") == 0) + vrf = vrf_lookup_by_id(VRF_DEFAULT); + else + vrf = vrf_lookup_by_name(name); + + if (!vrf) { + vty_out(vty, "Unable to find vrf you silly head"); + return CMD_WARNING_CONFIG_FAILED; + } + + vrf_label_add(vrf->vrf_id, label); + return CMD_SUCCESS; +} + DEFPY (remove_routes, remove_routes_cmd, "remove routes A.B.C.D$start (1-1000000)$routes", @@ -112,5 +138,6 @@ void sharp_vty_init(void) { install_element(ENABLE_NODE, &install_routes_cmd); install_element(ENABLE_NODE, &remove_routes_cmd); + install_element(ENABLE_NODE, &vrf_label_cmd); return; } diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index 10e48ac628..5dffd4ab9b 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -152,6 +152,11 @@ static void zebra_connected(struct zclient *zclient) zclient_send_reg_requests(zclient, VRF_DEFAULT); } +void vrf_label_add(vrf_id_t vrf_id, mpls_label_t label) +{ + zclient_send_vrf_label(zclient, vrf_id, label); +} + void route_add(struct prefix *p, struct nexthop *nh) { struct zapi_route api; diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h index 97100f61a6..281c67ff94 100644 --- a/sharpd/sharp_zebra.h +++ b/sharpd/sharp_zebra.h @@ -24,6 +24,7 @@ extern void sharp_zebra_init(void); +extern void vrf_label_add(vrf_id_t vrf_id, mpls_label_t label); extern void route_add(struct prefix *p, struct nexthop *nh); extern void route_delete(struct prefix *p); #endif From 75239f4f28b6b75fbc4d8b0f63c4a9193513989d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 30 Jan 2018 13:59:51 -0500 Subject: [PATCH 15/45] sharpd: Consolidate commands under 'sharp' keyword The commands if not careful needed a way to isolate themselves from each other and 'real' system commands so let's put them under the sharp keyword. Signed-off-by: Donald Sharp --- sharpd/sharp_vty.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index efbe989721..786191e6a1 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -41,7 +41,8 @@ extern uint32_t removed_routes; DEFPY (install_routes, install_routes_cmd, - "install routes A.B.C.D$start nexthop A.B.C.D$nexthop (1-1000000)$routes", + "sharp install routes A.B.C.D$start nexthop A.B.C.D$nexthop (1-1000000)$routes", + "Sharp routing Protocol\n" "install some routes\n" "Routes to install\n" "Address to start /32 generation at\n" @@ -80,7 +81,8 @@ DEFPY (install_routes, DEFPY(vrf_label, vrf_label_cmd, - "label vrf NAME$name label (0-100000)$label", + "sharp label vrf NAME$name label (0-100000)$label", + "Sharp Routing Protocol\n" "Give a vrf a label\n" VRF_CMD_HELP_STR "The label to use\n" @@ -104,7 +106,8 @@ DEFPY(vrf_label, DEFPY (remove_routes, remove_routes_cmd, - "remove routes A.B.C.D$start (1-1000000)$routes", + "sharp remove routes A.B.C.D$start (1-1000000)$routes", + "Sharp Routing Protocol\n" "Remove some routes\n" "Routes to remove\n" "Starting spot\n" From b9abd9adac023bdb4927e6f9d095a3234240643a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 31 Jan 2018 16:29:24 -0500 Subject: [PATCH 16/45] zebra: Cleanup mpls handling to allow a NEXTHOP_TYPE_IFINDEX Add the ability for the nexthops to be a NEXTHOP_TYPE_IFINDEX. Since we are using this code for L3vpn pop and forward operations and we know that the lo or vrf device name must exist we trust that it is correct. Update display to show the correct data with a 'show mpls table' Update the mpls install into the kernel to treat NEXTHOP_TYPE_IFINDEX as special and we do not need to pass in the nexthop label. Signed-off-by: Donald Sharp --- zebra/zebra_mpls.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 485488d567..adc893302c 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -711,6 +711,22 @@ static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe) /* Check on nexthop based on type. */ switch (nexthop->type) { + case NEXTHOP_TYPE_IFINDEX: + /* + * Lookup if this type is special. The + * NEXTHOP_TYPE_IFINDEX is a pop and + * forward into a different table for + * processing. As such this ifindex + * passed to us may be a VRF device + * which will not be in the default + * VRF. So let's look in all of them + */ + ifp = if_lookup_by_index(nexthop->ifindex, VRF_UNKNOWN); + if (ifp && if_is_operative(ifp)) + SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); + else + UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); + break; case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: if (nhlfe_nexthop_active_ipv4(nhlfe, nexthop)) @@ -1053,6 +1069,8 @@ static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size) case NEXTHOP_TYPE_IPV6: inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, size); break; + case NEXTHOP_TYPE_IFINDEX: + snprintf(buf, size, "Ifindex: %u", nexthop->ifindex); default: break; } @@ -1091,6 +1109,9 @@ static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype, if (!cmp && nhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) cmp = !(nhop->ifindex == ifindex); break; + case NEXTHOP_TYPE_IFINDEX: + cmp = !(nhop->ifindex == ifindex); + break; default: break; } @@ -1165,6 +1186,9 @@ static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type, if (ifindex) nexthop->ifindex = ifindex; break; + case NEXTHOP_TYPE_IFINDEX: + nexthop->ifindex = ifindex; + break; default: nexthop_free(nexthop); XFREE(MTYPE_NHLFE, nhlfe); @@ -2768,6 +2792,15 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, nexthop = nhlfe->nexthop; switch (nexthop->type) { + case NEXTHOP_TYPE_IFINDEX: + { + struct interface *ifp; + + ifp = if_lookup_by_index( + nexthop->ifindex, VRF_UNKNOWN); + vty_out(vty, "%15s", ifp->name); + break; + } case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: vty_out(vty, "%15s", @@ -2784,8 +2817,11 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, break; } - vty_out(vty, " %8d\n", - nexthop->nh_label->label[0]); + if (nexthop->type != NEXTHOP_TYPE_IFINDEX) + vty_out(vty, " %8d\n", + nexthop->nh_label->label[0]); + else + vty_out(vty, "\n"); } } From 70e98a7fe7296a1279c6b7142e57221f71ff3121 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 31 Jan 2018 18:24:06 -0500 Subject: [PATCH 17/45] *: Make code use a consisten definition of labels Turns out we had 3 different ways to define labels all of them overlapping with the same meanings. Consolidate to 1. This one choosen is consistent naming wise with what the *bsd and linux kernels use. Signed-off-by: Donald Sharp --- bgpd/bgp_mplsvpn.h | 24 ----------------- bgpd/bgp_route.c | 2 +- ldpd/labelmapping.c | 10 +++---- ldpd/lde.c | 22 +++++++++------- ldpd/logmsg.c | 6 ++--- lib/mpls.h | 60 ++++++++++++++++++++---------------------- lib/zclient.c | 4 +-- lib/zclient.h | 2 +- ospfd/ospf_sr.c | 20 +++++++------- zebra/kernel_socket.c | 2 +- zebra/label_manager.c | 4 +-- zebra/rt_netlink.c | 4 +-- zebra/zebra_mpls.c | 17 ++++++------ zebra/zebra_mpls_vty.c | 14 +++++----- zebra/zebra_vty.c | 4 +-- zebra/zserv.c | 4 +-- 16 files changed, 89 insertions(+), 110 deletions(-) diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index 3b37aadbf8..5c11f7526c 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -24,30 +24,6 @@ #include "bgpd/bgp_route.h" #include "bgpd/bgp_rd.h" -#ifdef MPLS_LABEL_MAX -#undef MPLS_LABEL_MAX -#endif - -typedef enum { - MPLS_LABEL_IPV4_EXPLICIT_NULL = 0, /* [RFC3032] */ - MPLS_LABEL_ROUTER_ALERT = 1, /* [RFC3032] */ - MPLS_LABEL_IPV6_EXPLICIT_NULL = 2, /* [RFC3032] */ - MPLS_LABEL_IMPLICIT_NULL = 3, /* [RFC3032] */ - MPLS_LABEL_UNASSIGNED4 = 4, - MPLS_LABEL_UNASSIGNED5 = 5, - MPLS_LABEL_UNASSIGNED6 = 6, - MPLS_LABEL_ELI = 7, /* Entropy Indicator [RFC6790] */ - MPLS_LABEL_UNASSIGNED8 = 8, - MPLS_LABEL_UNASSIGNED9 = 9, - MPLS_LABEL_UNASSIGNED10 = 10, - MPLS_LABEL_UNASSIGNED11 = 11, - MPLS_LABEL_GAL = 13, /* [RFC5586] */ - MPLS_LABEL_OAM_ALERT = 14, /* [RFC3429] */ - MPLS_LABEL_EXTENSION = 15, /* [RFC7274] */ - MPLS_LABEL_MAX = 1048575, - MPLS_LABEL_ILLEGAL = 0xFFFFFFFF /* for internal use only */ -} mpls_special_label_t; - #define MPLS_LABEL_IS_SPECIAL(label) ((label) <= MPLS_LABEL_EXTENSION) #define MPLS_LABEL_IS_NULL(label) \ ((label) == MPLS_LABEL_IPV4_EXPLICIT_NULL \ diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 36e0c92482..a60484fe0a 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2099,7 +2099,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn, rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) bgp_unregister_for_label(rn); - label_ntop(MPLS_IMP_NULL_LABEL, 1, + label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1, &rn->local_label); bgp_set_valid_label(&rn->local_label); } else diff --git a/ldpd/labelmapping.c b/ldpd/labelmapping.c index 5662038a58..944f93331f 100644 --- a/ldpd/labelmapping.c +++ b/ldpd/labelmapping.c @@ -320,9 +320,9 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type) /* do not accept invalid labels */ if (label > MPLS_LABEL_MAX || (label <= MPLS_LABEL_RESERVED_MAX && - label != MPLS_LABEL_IPV4NULL && - label != MPLS_LABEL_IPV6NULL && - label != MPLS_LABEL_IMPLNULL)) { + label != MPLS_LABEL_IPV4_EXPLICIT_NULL && + label != MPLS_LABEL_IPV6_EXPLICIT_NULL && + label != MPLS_LABEL_IMPLICIT_NULL)) { session_shutdown(nbr, S_BAD_TLV_VAL, msg.id, msg.type); goto err; @@ -396,7 +396,7 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type) case MAP_TYPE_PREFIX: switch (me->map.fec.prefix.af) { case AF_INET: - if (label == MPLS_LABEL_IPV6NULL) { + if (label == MPLS_LABEL_IPV6_EXPLICIT_NULL) { session_shutdown(nbr, S_BAD_TLV_VAL, msg.id, msg.type); goto err; @@ -405,7 +405,7 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type) goto next; break; case AF_INET6: - if (label == MPLS_LABEL_IPV4NULL) { + if (label == MPLS_LABEL_IPV4_EXPLICIT_NULL) { session_shutdown(nbr, S_BAD_TLV_VAL, msg.id, msg.type); goto err; diff --git a/ldpd/lde.c b/ldpd/lde.c index 63e1e39946..a70b97d06b 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -702,20 +702,20 @@ lde_update_label(struct fec_node *fn) switch (fn->fec.type) { case FEC_TYPE_IPV4: if (!(ldeconf->ipv4.flags & F_LDPD_AF_EXPNULL)) - return (MPLS_LABEL_IMPLNULL); + return (MPLS_LABEL_IMPLICIT_NULL); if (lde_acl_check(ldeconf->ipv4.acl_label_expnull_for, AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix, fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT) - return (MPLS_LABEL_IMPLNULL); - return (MPLS_LABEL_IPV4NULL); + return (MPLS_LABEL_IMPLICIT_NULL); + return MPLS_LABEL_IPV4_EXPLICIT_NULL; case FEC_TYPE_IPV6: if (!(ldeconf->ipv6.flags & F_LDPD_AF_EXPNULL)) - return (MPLS_LABEL_IMPLNULL); + return (MPLS_LABEL_IMPLICIT_NULL); if (lde_acl_check(ldeconf->ipv6.acl_label_expnull_for, AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix, fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT) - return (MPLS_LABEL_IMPLNULL); - return (MPLS_LABEL_IPV6NULL); + return (MPLS_LABEL_IMPLICIT_NULL); + return MPLS_LABEL_IPV6_EXPLICIT_NULL; default: fatalx("lde_update_label: unexpected fec type"); break; @@ -1522,11 +1522,15 @@ lde_change_egress_label(int af) /* explicitly withdraw all null labels */ RB_FOREACH(ln, nbr_tree, &lde_nbrs) { - lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IMPLNULL); + lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IMPLICIT_NULL); if (ln->v4_enabled) - lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IPV4NULL); + lde_send_labelwithdraw_wcard( + ln, + MPLS_LABEL_IPV4_EXPLICIT_NULL); if (ln->v6_enabled) - lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IPV6NULL); + lde_send_labelwithdraw_wcard( + ln, + MPLS_LABEL_IPV6_EXPLICIT_NULL); } /* update label of connected routes */ diff --git a/ldpd/logmsg.c b/ldpd/logmsg.c index c819b33b43..a9b066a3da 100644 --- a/ldpd/logmsg.c +++ b/ldpd/logmsg.c @@ -115,11 +115,11 @@ log_label(uint32_t label) case NO_LABEL: snprintf(buf, TF_LEN, "-"); break; - case MPLS_LABEL_IMPLNULL: + case MPLS_LABEL_IMPLICIT_NULL: snprintf(buf, TF_LEN, "imp-null"); break; - case MPLS_LABEL_IPV4NULL: - case MPLS_LABEL_IPV6NULL: + case MPLS_LABEL_IPV4_EXPLICIT_NULL: + case MPLS_LABEL_IPV6_EXPLICIT_NULL: snprintf(buf, TF_LEN, "exp-null"); break; default: diff --git a/lib/mpls.h b/lib/mpls.h index 95882c26ec..c6c0297ff0 100644 --- a/lib/mpls.h +++ b/lib/mpls.h @@ -24,21 +24,27 @@ #include +#ifdef MPLS_LABEL_MAX +#undef MPLS_LABEL_MAX +#endif + /* Well-known MPLS label values (RFC 3032 etc). */ -#define MPLS_V4_EXP_NULL_LABEL 0 -#define MPLS_RA_LABEL 1 -#define MPLS_V6_EXP_NULL_LABEL 2 -#define MPLS_IMP_NULL_LABEL 3 -#define MPLS_ENTROPY_LABEL_INDICATOR 7 -#define MPLS_GAL_LABEL 13 -#define MPLS_OAM_ALERT_LABEL 14 -#define MPLS_EXTENSION_LABEL 15 +#define MPLS_LABEL_IPV4_EXPLICIT_NULL 0 /* [RFC3032] */ +#define MPLS_LABEL_ROUTER_ALERT 1 /* [RFC3032] */ +#define MPLS_LABEL_IPV6_EXPLICIT_NULL 2 /* [RFC3032] */ +#define MPLS_LABEL_IMPLICIT_NULL 3 /* [RFC3032] */ +#define MPLS_LABEL_ELI 7 /* [RFC6790] */ +#define MPLS_LABEL_GAL 13 /* [RFC5586] */ +#define MPLS_LABEL_OAM_ALERT 14 /* [RFC3429] */ +#define MPLS_LABEL_EXTENSION 15 /* [RFC7274] */ +#define MPLS_LABEL_MAX 1048575 +#define MPLS_LABEL_ILLEGAL 0xFFFFFFFF /* for internal use only */ /* Minimum and maximum label values */ -#define MPLS_MIN_RESERVED_LABEL 0 -#define MPLS_MAX_RESERVED_LABEL 15 -#define MPLS_MIN_UNRESERVED_LABEL 16 -#define MPLS_MAX_UNRESERVED_LABEL 1048575 +#define MPLS_LABEL_RESERVED_MIN 0 +#define MPLS_LABEL_RESERVED_MAX 15 +#define MPLS_LABEL_UNRESERVED_MIN 16 +#define MPLS_LABEL_UNRESERVED_MAX 1048575 /* Default min and max SRGB label range */ /* Even if the SRGB allows to manage different Label space between routers, @@ -56,11 +62,11 @@ #define MPLS_MAX_LABELS 16 #define IS_MPLS_RESERVED_LABEL(label) \ - (label >= MPLS_MIN_RESERVED_LABEL && label <= MPLS_MAX_RESERVED_LABEL) + (label >= MPLS_LABEL_RESERVED_MIN && label <= MPLS_LABEL_RESERVED_MAX) #define IS_MPLS_UNRESERVED_LABEL(label) \ - (label >= MPLS_MIN_UNRESERVED_LABEL \ - && label <= MPLS_MAX_UNRESERVED_LABEL) + (label >= MPLS_LABEL_UNRESERVED_MIN \ + && label <= MPLS_LABEL_UNRESERVED_MAX) /* Definitions for a MPLS label stack entry (RFC 3032). This encodes the * label, EXP, BOS and TTL fields. @@ -153,28 +159,28 @@ static inline void mpls_lse_decode(mpls_lse_t lse, mpls_label_t *label, static inline char *label2str(mpls_label_t label, char *buf, size_t len) { switch (label) { - case MPLS_V4_EXP_NULL_LABEL: + case MPLS_LABEL_IPV4_EXPLICIT_NULL: strlcpy(buf, "IPv4 Explicit Null", len); return (buf); - case MPLS_RA_LABEL: + case MPLS_LABEL_ROUTER_ALERT: strlcpy(buf, "Router Alert", len); return (buf); - case MPLS_V6_EXP_NULL_LABEL: + case MPLS_LABEL_IPV6_EXPLICIT_NULL: strlcpy(buf, "IPv6 Explict Null", len); return (buf); - case MPLS_IMP_NULL_LABEL: + case MPLS_LABEL_IMPLICIT_NULL: strlcpy(buf, "implicit-null", len); return (buf); - case MPLS_ENTROPY_LABEL_INDICATOR: + case MPLS_LABEL_ELI: strlcpy(buf, "Entropy Label Indicator", len); return (buf); - case MPLS_GAL_LABEL: + case MPLS_LABEL_GAL: strlcpy(buf, "Generic Associated Channel", len); return (buf); - case MPLS_OAM_ALERT_LABEL: + case MPLS_LABEL_OAM_ALERT: strlcpy(buf, "OAM Alert", len); return (buf); - case MPLS_EXTENSION_LABEL: + case MPLS_LABEL_EXTENSION: strlcpy(buf, "Extension", len); return (buf); default: @@ -186,13 +192,5 @@ static inline char *label2str(mpls_label_t label, char *buf, size_t len) } } -/* constants used by ldpd */ -#define MPLS_LABEL_IPV4NULL 0 /* IPv4 Explicit NULL Label */ -#define MPLS_LABEL_RTALERT 1 /* Router Alert Label */ -#define MPLS_LABEL_IPV6NULL 2 /* IPv6 Explicit NULL Label */ -#define MPLS_LABEL_IMPLNULL 3 /* Implicit NULL Label */ - /* MPLS_LABEL_RESERVED 4-15 */ /* Values 4-15 are reserved */ -#define MPLS_LABEL_RESERVED_MAX 15 -#define MPLS_LABEL_MAX ((1 << 20) - 1) #endif diff --git a/lib/zclient.c b/lib/zclient.c index 9327201f73..f8cdc61f7d 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1991,8 +1991,8 @@ int lm_get_label_chunk(struct zclient *zclient, u_char keep, __func__, *start, *end, keep, response_keep); } /* sanity */ - if (*start > *end || *start < MPLS_MIN_UNRESERVED_LABEL - || *end > MPLS_MAX_UNRESERVED_LABEL) { + if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN + || *end > MPLS_LABEL_UNRESERVED_MAX) { zlog_err("%s: Invalid Label chunk: %u - %u", __func__, *start, *end); return -1; diff --git a/lib/zclient.h b/lib/zclient.h index 6b39a2713a..23cedf97bd 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -387,7 +387,7 @@ extern void redist_del_instance(struct redist_proto *, u_short); * Send to zebra that the specified vrf is using label to resolve * itself for L3VPN's. Repeated calls of this function with * different labels will cause an effective update of the - * label for lookup. If you pass in MPLS_V4_EXP_NULL_LABEL + * label for lookup. If you pass in MPLS_LABEL_IPV4_EXPLICIT_NULL * we will cause a delete action and remove this label pop * operation. */ diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index 725bf952e5..c6649a7a04 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -511,8 +511,8 @@ static int compute_link_nhlfe(struct sr_link *srl) srl->nhlfe[1].label_in = index2label(srl->sid[1], srl->srn->srgb); - srl->nhlfe[0].label_out = MPLS_IMP_NULL_LABEL; - srl->nhlfe[1].label_out = MPLS_IMP_NULL_LABEL; + srl->nhlfe[0].label_out = MPLS_LABEL_IMPLICIT_NULL; + srl->nhlfe[1].label_out = MPLS_LABEL_IMPLICIT_NULL; rc = 1; return rc; @@ -599,7 +599,7 @@ static int compute_prefix_nhlfe(struct sr_prefix *srp) */ if ((srp->nexthop == NULL) && (!CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_NPFLG))) - srp->nhlfe.label_out = MPLS_IMP_NULL_LABEL; + srp->nhlfe.label_out = MPLS_LABEL_IMPLICIT_NULL; else if (CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_VFLG)) srp->nhlfe.label_out = srp->sid; else @@ -694,7 +694,7 @@ static inline void add_sid_nhlfe(struct sr_nhlfe nhlfe) { if ((nhlfe.label_in != 0) && (nhlfe.label_out != 0)) { ospf_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_ADD, nhlfe); - if (nhlfe.label_out != MPLS_IMP_NULL_LABEL) + if (nhlfe.label_out != MPLS_LABEL_IMPLICIT_NULL) ospf_zebra_send_mpls_ftn(ZEBRA_ROUTE_ADD, nhlfe); } } @@ -704,7 +704,7 @@ static inline void del_sid_nhlfe(struct sr_nhlfe nhlfe) { if ((nhlfe.label_in != 0) && (nhlfe.label_out != 0)) { ospf_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_DELETE, nhlfe); - if (nhlfe.label_out != MPLS_IMP_NULL_LABEL) + if (nhlfe.label_out != MPLS_LABEL_IMPLICIT_NULL) ospf_zebra_send_mpls_ftn(ZEBRA_ROUTE_DELETE, nhlfe); } } @@ -1535,7 +1535,7 @@ void ospf_sr_update_prefix(struct interface *ifp, struct prefix *p) EXT_SUBTLV_PREFIX_SID_NPFLG)) { srp->nhlfe.label_in = index2label(srp->sid, OspfSR.self->srgb); - srp->nhlfe.label_out = MPLS_IMP_NULL_LABEL; + srp->nhlfe.label_out = MPLS_LABEL_IMPLICIT_NULL; add_sid_nhlfe(srp->nhlfe); } } @@ -1992,7 +1992,7 @@ DEFUN (sr_prefix_sid, if (argv_find(argv, argc, "no-php-flag", &idx)) { SET_FLAG(new->flags, EXT_SUBTLV_PREFIX_SID_NPFLG); new->nhlfe.label_in = index2label(new->sid, OspfSR.self->srgb); - new->nhlfe.label_out = MPLS_IMP_NULL_LABEL; + new->nhlfe.label_out = MPLS_LABEL_IMPLICIT_NULL; } if (IS_DEBUG_OSPF_SR) @@ -2168,7 +2168,7 @@ static void show_vty_sr_node(struct vty *vty, struct sr_node *srn) for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp)) { strncpy(pref, inet_ntoa(srp->nhlfe.prefv4.prefix), 16); snprintf(sid, 22, "SR Pfx (idx %u)", srp->sid); - if (srp->nhlfe.label_out == MPLS_IMP_NULL_LABEL) + if (srp->nhlfe.label_out == MPLS_LABEL_IMPLICIT_NULL) sprintf(label, "pop"); else sprintf(label, "%u", srp->nhlfe.label_out); @@ -2182,7 +2182,7 @@ static void show_vty_sr_node(struct vty *vty, struct sr_node *srn) for (ALL_LIST_ELEMENTS_RO(srn->ext_link, node, srl)) { strncpy(pref, inet_ntoa(srl->nhlfe[0].prefv4.prefix), 16); snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[0]); - if (srl->nhlfe[0].label_out == MPLS_IMP_NULL_LABEL) + if (srl->nhlfe[0].label_out == MPLS_LABEL_IMPLICIT_NULL) sprintf(label, "pop"); else sprintf(label, "%u", srl->nhlfe[0].label_out); @@ -2192,7 +2192,7 @@ static void show_vty_sr_node(struct vty *vty, struct sr_node *srn) label, sid, itf ? itf->name : "-", inet_ntoa(srl->nhlfe[0].nexthop)); snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[1]); - if (srl->nhlfe[1].label_out == MPLS_IMP_NULL_LABEL) + if (srl->nhlfe[1].label_out == MPLS_LABEL_IMPLICIT_NULL) sprintf(label, "pop"); else sprintf(label, "%u", srl->nhlfe[0].label_out); diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 7a64b48964..4d888d8069 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1197,7 +1197,7 @@ int rtm_write(int message, union sockunion *dest, union sockunion *mask, msg.rtm.rtm_flags |= RTF_MPLS; if (mpls->smpls.smpls_label - != htonl(MPLS_IMP_NULL_LABEL << MPLS_LABEL_OFFSET)) + != htonl(MPLS_LABEL_IMPLICIT_NULL << MPLS_LABEL_OFFSET)) msg.rtm.rtm_mpls = MPLS_OP_PUSH; } #endif diff --git a/zebra/label_manager.c b/zebra/label_manager.c index ace13eda71..5bf0fce094 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -283,13 +283,13 @@ struct label_manager_chunk *assign_label_chunk(u_char proto, u_short instance, return NULL; if (list_isempty(lbl_mgr.lc_list)) - lmc->start = MPLS_MIN_UNRESERVED_LABEL; + lmc->start = MPLS_LABEL_UNRESERVED_MIN; else lmc->start = ((struct label_manager_chunk *)listgetdata( listtail(lbl_mgr.lc_list))) ->end + 1; - if (lmc->start > MPLS_MAX_UNRESERVED_LABEL - size + 1) { + if (lmc->start > MPLS_LABEL_UNRESERVED_MAX - size + 1) { zlog_err("Reached max labels. Start: %u, size: %u", lmc->start, size); XFREE(MTYPE_LM_CHUNK, lmc); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index b8011c2a76..d778990141 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -864,7 +864,7 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen, char label_buf1[20]; for (i = 0; i < nh_label->num_labels; i++) { - if (nh_label->label[i] != MPLS_IMP_NULL_LABEL) { + if (nh_label->label[i] != MPLS_LABEL_IMPLICIT_NULL) { bos = ((i == (nh_label->num_labels - 1)) ? 1 : 0); out_lse[i] = mpls_lse_encode(nh_label->label[i], @@ -1074,7 +1074,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen, char label_buf1[20]; for (i = 0; i < nh_label->num_labels; i++) { - if (nh_label->label[i] != MPLS_IMP_NULL_LABEL) { + if (nh_label->label[i] != MPLS_LABEL_IMPLICIT_NULL) { bos = ((i == (nh_label->num_labels - 1)) ? 1 : 0); out_lse[i] = mpls_lse_encode(nh_label->label[i], diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index adc893302c..3ceebf417e 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -411,12 +411,13 @@ static int fec_change_update_lsp(struct zebra_vrf *zvrf, zebra_fec_t *fec, afi_t afi; /* Uninstall label forwarding entry, if previously installed. */ - if (old_label != MPLS_INVALID_LABEL && old_label != MPLS_IMP_NULL_LABEL) + if (old_label != MPLS_INVALID_LABEL && + old_label != MPLS_LABEL_IMPLICIT_NULL) lsp_uninstall(zvrf, old_label); /* Install label forwarding entry corr. to new label, if needed. */ if (fec->label == MPLS_INVALID_LABEL - || fec->label == MPLS_IMP_NULL_LABEL) + || fec->label == MPLS_LABEL_IMPLICIT_NULL) return 0; afi = family2afi(PREFIX_FAMILY(&fec->rn->p)); @@ -1821,7 +1822,7 @@ int zebra_mpls_lsp_install(struct zebra_vrf *zvrf, struct route_node *rn, /* We cannot install a label forwarding entry if local label is the * implicit-null label. */ - if (fec->label == MPLS_IMP_NULL_LABEL) + if (fec->label == MPLS_LABEL_IMPLICIT_NULL) return 0; if (lsp_install(zvrf, fec->label, rn, re)) @@ -2565,8 +2566,8 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf, int cur_op, new_op; cur_op = (slsp->snhlfe_list->out_label - == MPLS_IMP_NULL_LABEL); - new_op = (out_label == MPLS_IMP_NULL_LABEL); + == MPLS_LABEL_IMPLICIT_NULL); + new_op = (out_label == MPLS_LABEL_IMPLICIT_NULL); if (cur_op != new_op) return 0; } @@ -2850,11 +2851,11 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf) snhlfe2str(snhlfe, buf, sizeof(buf)); switch (snhlfe->out_label) { - case MPLS_V4_EXP_NULL_LABEL: - case MPLS_V6_EXP_NULL_LABEL: + case MPLS_LABEL_IPV4_EXPLICIT_NULL: + case MPLS_LABEL_IPV6_EXPLICIT_NULL: strlcpy(lstr, "explicit-null", sizeof(lstr)); break; - case MPLS_IMP_NULL_LABEL: + case MPLS_LABEL_IMPLICIT_NULL: strlcpy(lstr, "implicit-null", sizeof(lstr)); break; default: diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c index 9d100bb7d0..0d922830c7 100644 --- a/zebra/zebra_mpls_vty.c +++ b/zebra/zebra_mpls_vty.c @@ -68,7 +68,7 @@ static int zebra_mpls_transit_lsp(struct vty *vty, int add_cmd, return CMD_WARNING_CONFIG_FAILED; } - out_label = MPLS_IMP_NULL_LABEL; /* as initialization */ + out_label = MPLS_LABEL_IMPLICIT_NULL; /* as initialization */ label = atoi(inlabel_str); if (!IS_MPLS_UNRESERVED_LABEL(label)) { vty_out(vty, "%% Invalid label\n"); @@ -107,11 +107,11 @@ static int zebra_mpls_transit_lsp(struct vty *vty, int add_cmd, if (outlabel_str) { if (outlabel_str[0] == 'i') - out_label = MPLS_IMP_NULL_LABEL; + out_label = MPLS_LABEL_IMPLICIT_NULL; else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV4) - out_label = MPLS_V4_EXP_NULL_LABEL; + out_label = MPLS_LABEL_IPV4_EXPLICIT_NULL; else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV6) - out_label = MPLS_V6_EXP_NULL_LABEL; + out_label = MPLS_LABEL_IPV6_EXPLICIT_NULL; else out_label = atoi(outlabel_str); } @@ -221,12 +221,12 @@ static int zebra_mpls_bind(struct vty *vty, int add_cmd, const char *prefix, } if (!strcmp(label_str, "implicit-null")) - label = MPLS_IMP_NULL_LABEL; + label = MPLS_LABEL_IMPLICIT_NULL; else if (!strcmp(label_str, "explicit-null")) { if (p.family == AF_INET) - label = MPLS_V4_EXP_NULL_LABEL; + label = MPLS_LABEL_IPV4_EXPLICIT_NULL; else - label = MPLS_V6_EXP_NULL_LABEL; + label = MPLS_LABEL_IPV6_EXPLICIT_NULL; } else { label = atoi(label_str); if (!IS_MPLS_UNRESERVED_LABEL(label)) { diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 3f6db5986f..f5ad9c1c8a 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -165,8 +165,8 @@ static int zebra_static_route_leak(struct vty *vty, case -2: vty_out(vty, "%% Cannot use reserved label(s) (%d-%d)\n", - MPLS_MIN_RESERVED_LABEL, - MPLS_MAX_RESERVED_LABEL); + MPLS_LABEL_RESERVED_MIN, + MPLS_LABEL_RESERVED_MAX); break; case -3: vty_out(vty, diff --git a/zebra/zserv.c b/zebra/zserv.c index 5f2757f52c..bf8f66e20f 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2517,12 +2517,12 @@ static void zread_vrf_label(struct zserv *client, def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); - if (zvrf->label != MPLS_LABEL_IPV4NULL) + if (zvrf->label != MPLS_LABEL_IPV4_EXPLICIT_NULL) mpls_lsp_uninstall(def_zvrf, ZEBRA_LSP_STATIC, zvrf->label, NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); - if (nlabel != MPLS_LABEL_IPV4NULL) + if (nlabel != MPLS_LABEL_IPV4_EXPLICIT_NULL) mpls_lsp_install(def_zvrf, ZEBRA_LSP_STATIC, nlabel, MPLS_LABEL_IMPLICIT_NULL, NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); From 339e36d258ad73701d7b9eccc0e56e48cdea1a2d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 8 Feb 2018 09:50:32 -0500 Subject: [PATCH 18/45] lib, sharpd, zebra: Add new enum for lsp type and pass it through. Add the ability to pass the lsp owner type through the zapi and in addition add a new label type for the sharp protocol for testing. Finally modify zebra_mpls.h to not have defaults specified for the enum. That way when we add a new LSP type the compile fails and the person doing the addition knows where he has to touch shit. Signed-off-by: Donald Sharp --- lib/mpls.h | 3 ++- lib/zclient.c | 3 ++- lib/zclient.h | 2 +- sharpd/sharp_zebra.c | 2 +- zebra/zebra_mpls.h | 37 ++++++++++++++++++++++++++++++++++--- zebra/zserv.c | 12 ++++++------ 6 files changed, 46 insertions(+), 13 deletions(-) diff --git a/lib/mpls.h b/lib/mpls.h index c6c0297ff0..b55d4875ae 100644 --- a/lib/mpls.h +++ b/lib/mpls.h @@ -115,7 +115,8 @@ enum lsp_types_t { ZEBRA_LSP_STATIC = 1, /* Static LSP. */ ZEBRA_LSP_LDP = 2, /* LDP LSP. */ ZEBRA_LSP_BGP = 3, /* BGP LSP. */ - ZEBRA_LSP_SR = 4 /* Segment Routing LSP. */ + ZEBRA_LSP_SR = 4, /* Segment Routing LSP. */ + ZEBRA_LSP_SHARP = 5, /* Identifier for test protocol */ }; /* Functions for basic label operations. */ diff --git a/lib/zclient.c b/lib/zclient.c index f8cdc61f7d..8e8b50b15e 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -364,7 +364,7 @@ static int zebra_hello_send(struct zclient *zclient) } void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, - mpls_label_t label) + mpls_label_t label, enum lsp_types_t ltype) { struct stream *s; @@ -373,6 +373,7 @@ void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, zclient_create_header(s, ZEBRA_VRF_LABEL, vrf_id); stream_putl(s, label); + stream_putc(s, ltype); stream_putw_at(s, 0, stream_get_endp(s)); zclient_send_message(zclient); } diff --git a/lib/zclient.h b/lib/zclient.h index 23cedf97bd..ff65838b53 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -392,7 +392,7 @@ extern void redist_del_instance(struct redist_proto *, u_short); * operation. */ extern void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, - mpls_label_t label); + mpls_label_t label, enum lsp_types_t ltype); extern void zclient_send_reg_requests(struct zclient *, vrf_id_t); extern void zclient_send_dereg_requests(struct zclient *, vrf_id_t); diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index 5dffd4ab9b..f771e53f0c 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -154,7 +154,7 @@ static void zebra_connected(struct zclient *zclient) void vrf_label_add(vrf_id_t vrf_id, mpls_label_t label) { - zclient_send_vrf_label(zclient, vrf_id, label); + zclient_send_vrf_label(zclient, vrf_id, label, ZEBRA_LSP_SHARP); } void route_add(struct prefix *p, struct nexthop *nh) diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h index 27a4971691..fd14b29ca9 100644 --- a/zebra/zebra_mpls.h +++ b/zebra/zebra_mpls.h @@ -428,9 +428,19 @@ static inline u_char lsp_distance(enum lsp_types_t type) return (route_distance(ZEBRA_ROUTE_LDP)); case ZEBRA_LSP_BGP: return (route_distance(ZEBRA_ROUTE_BGP)); - default: + case ZEBRA_LSP_NONE: + case ZEBRA_LSP_SHARP: + case ZEBRA_LSP_SR: return 150; } + + /* + * For some reason certain compilers do not believe + * that all the cases have been handled. And + * WTF does this work differently than when I removed + * the default case???? + */ + return 150; } /* @@ -444,6 +454,8 @@ static inline enum lsp_types_t lsp_type_from_re_type(int re_type) return ZEBRA_LSP_STATIC; case ZEBRA_ROUTE_BGP: return ZEBRA_LSP_BGP; + case ZEBRA_ROUTE_SHARP: + return ZEBRA_LSP_SHARP; default: return ZEBRA_LSP_NONE; } @@ -464,9 +476,18 @@ static inline int re_type_from_lsp_type(enum lsp_types_t lsp_type) case ZEBRA_LSP_SR: return ZEBRA_ROUTE_OSPF; case ZEBRA_LSP_NONE: - default: return ZEBRA_ROUTE_KERNEL; + case ZEBRA_LSP_SHARP: + return ZEBRA_ROUTE_SHARP; } + + /* + * For some reason certain compilers do not believe + * that all the cases have been handled. And + * WTF does this work differently than when I removed + * the default case???? + */ + return ZEBRA_ROUTE_KERNEL; } /* NHLFE type as printable string. */ @@ -481,9 +502,19 @@ static inline const char *nhlfe_type2str(enum lsp_types_t lsp_type) return "BGP"; case ZEBRA_LSP_SR: return "SR"; - default: + case ZEBRA_LSP_SHARP: + return "SHARP"; + case ZEBRA_LSP_NONE: return "Unknown"; } + + /* + * For some reason certain compilers do not believe + * that all the cases have been handled. And + * WTF does this work differently than when I removed + * the default case???? + */ + return "Unknown"; } static inline void mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf) diff --git a/zebra/zserv.c b/zebra/zserv.c index bf8f66e20f..3d8be27f3b 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2493,16 +2493,17 @@ static void zread_vrf_label(struct zserv *client, mpls_label_t nlabel; struct stream *s; struct zebra_vrf *def_zvrf; + enum lsp_types_t ltype; s = client->ibuf; STREAM_GETL(s, nlabel); - if (nlabel == zvrf->label) { /* * Nothing to do here move along */ return; } + STREAM_GETC(s, ltype); if (zvrf->vrf->vrf_id != VRF_DEFAULT) ifp = if_lookup_by_name(zvrf->vrf->name, zvrf->vrf->vrf_id); @@ -2518,13 +2519,12 @@ static void zread_vrf_label(struct zserv *client, def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); if (zvrf->label != MPLS_LABEL_IPV4_EXPLICIT_NULL) - mpls_lsp_uninstall(def_zvrf, ZEBRA_LSP_STATIC, - zvrf->label, NEXTHOP_TYPE_IFINDEX, - NULL, ifp->ifindex); + mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label, + NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); if (nlabel != MPLS_LABEL_IPV4_EXPLICIT_NULL) - mpls_lsp_install(def_zvrf, ZEBRA_LSP_STATIC, nlabel, - MPLS_LABEL_IMPLICIT_NULL, NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); + mpls_lsp_install(def_zvrf, ltype, nlabel, MPLS_LABEL_IMPLICIT_NULL, + NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); zvrf->label = nlabel; stream_failure: From 42567e0011491fe799eef6d236ecf1937c59c18f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 8 Feb 2018 10:19:34 -0500 Subject: [PATCH 19/45] bgpd, lib, sharpd, zebra: Use MPLS_LABEL_NONE Modify mpls.h to rename MPLS_LABEL_ILLEGAL to be MPLS_LABEL_NONE. Fix all pre-existing code that used MPLS_LABEL_ILLEGAL. Modify the zapi vrf label message to use MPLS_LABEL_NONE as the signal to remove label associated with a vrf. Signed-off-by: Donald Sharp --- bgpd/rfapi/bgp_rfapi_cfg.c | 4 ++-- lib/mpls.h | 2 +- lib/zclient.h | 2 +- sharpd/sharp_vty.c | 8 +++++--- zebra/zserv.c | 4 ++-- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index e3cb739464..949e04ab0d 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -554,7 +554,7 @@ rfapi_group_new(struct bgp *bgp, rfapi_group_cfg_type_t type, const char *name) /* add to tail of list */ listnode_add(bgp->rfapi_cfg->nve_groups_sequential, rfg); } - rfg->label = MPLS_LABEL_ILLEGAL; + rfg->label = MPLS_LABEL_NONE; QOBJ_REG(rfg, rfapi_nve_group_cfg); return rfg; @@ -3063,7 +3063,7 @@ DEFUN (vnc_vrf_policy_no_label, vnc_redistribute_prechange(bgp); } - rfg->label = MPLS_LABEL_ILLEGAL; + rfg->label = MPLS_LABEL_NONE; if (bgp->rfapi_cfg->rfg_redist == rfg) { vnc_redistribute_postchange(bgp); diff --git a/lib/mpls.h b/lib/mpls.h index b55d4875ae..1a1819c2c0 100644 --- a/lib/mpls.h +++ b/lib/mpls.h @@ -38,7 +38,7 @@ #define MPLS_LABEL_OAM_ALERT 14 /* [RFC3429] */ #define MPLS_LABEL_EXTENSION 15 /* [RFC7274] */ #define MPLS_LABEL_MAX 1048575 -#define MPLS_LABEL_ILLEGAL 0xFFFFFFFF /* for internal use only */ +#define MPLS_LABEL_NONE 0xFFFFFFFF /* for internal use only */ /* Minimum and maximum label values */ #define MPLS_LABEL_RESERVED_MIN 0 diff --git a/lib/zclient.h b/lib/zclient.h index ff65838b53..344b45fb54 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -387,7 +387,7 @@ extern void redist_del_instance(struct redist_proto *, u_short); * Send to zebra that the specified vrf is using label to resolve * itself for L3VPN's. Repeated calls of this function with * different labels will cause an effective update of the - * label for lookup. If you pass in MPLS_LABEL_IPV4_EXPLICIT_NULL + * label for lookup. If you pass in MPLS_LABEL_NONE * we will cause a delete action and remove this label pop * operation. */ diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index 786191e6a1..4f7d61b22f 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -79,13 +79,12 @@ DEFPY (install_routes, return CMD_SUCCESS; } -DEFPY(vrf_label, - vrf_label_cmd, +DEFPY(vrf_label, vrf_label_cmd, "sharp label vrf NAME$name label (0-100000)$label", "Sharp Routing Protocol\n" "Give a vrf a label\n" VRF_CMD_HELP_STR - "The label to use\n" + "The label to use, 0 specifies remove the label installed from previous\n" "Specified range to use\n") { struct vrf *vrf; @@ -100,6 +99,9 @@ DEFPY(vrf_label, return CMD_WARNING_CONFIG_FAILED; } + if (label == 0) + label = MPLS_LABEL_NONE; + vrf_label_add(vrf->vrf_id, label); return CMD_SUCCESS; } diff --git a/zebra/zserv.c b/zebra/zserv.c index 3d8be27f3b..704b861960 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2518,11 +2518,11 @@ static void zread_vrf_label(struct zserv *client, def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); - if (zvrf->label != MPLS_LABEL_IPV4_EXPLICIT_NULL) + if (zvrf->label != MPLS_LABEL_NONE) mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label, NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); - if (nlabel != MPLS_LABEL_IPV4_EXPLICIT_NULL) + if (nlabel != MPLS_LABEL_NONE) mpls_lsp_install(def_zvrf, ltype, nlabel, MPLS_LABEL_IMPLICIT_NULL, NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); From fc5cca9fa41eee79dac29b6d973c2dfb097ad5a2 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 8 Feb 2018 19:51:37 -0500 Subject: [PATCH 20/45] zebra: Use appropriate output function for label printing Signed-off-by: Donald Sharp --- zebra/zebra_mpls.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 3ceebf417e..ec80081a46 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -2819,8 +2819,13 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, } if (nexthop->type != NEXTHOP_TYPE_IFINDEX) - vty_out(vty, " %8d\n", - nexthop->nh_label->label[0]); + vty_out(vty, " %8s\n", + mpls_label2str( + nexthop->nh_label + ->num_labels, + &nexthop->nh_label + ->label[0], + buf, BUFSIZ, 1)); else vty_out(vty, "\n"); } From 19274fe8c7bf0ab80375344826e183b4356c9c7b Mon Sep 17 00:00:00 2001 From: Olivier Dugeon Date: Fri, 9 Feb 2018 12:13:07 +0100 Subject: [PATCH 21/45] ospfd: Fix ospfd crash - ospfd/ospf_opaque.c: Update issue #1652 by introducing a new function 'free_opaque_info_owner()' to clean list of callback owner and call this function in appropriate place where 'listdelete_and_null' is not used. - ospfd/ospf_packet.c: In case of crash, ospfd is not been able to flush LSA. In case of self Opaque LSA, when restarting, ospfd crash during the resynchronisation process with its neighbor due to an empty list of LSA to flood. Just add a control on the list count in 'ospf_ls_upd_queue_send()' to escape the function and avoid the problem. Signed-off-by: Olivier Dugeon --- ospfd/ospf_opaque.c | 36 +++++++++++++++++++++++++++++++++++- ospfd/ospf_packet.c | 4 ++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 1c586d252c..009fd997ea 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -75,6 +75,7 @@ static void ospf_opaque_funclist_init(void); static void ospf_opaque_funclist_term(void); static void free_opaque_info_per_type(void *val); static void free_opaque_info_per_id(void *val); +static void free_opaque_info_owner(void *val); static int ospf_opaque_lsa_install_hook(struct ospf_lsa *lsa); static int ospf_opaque_lsa_delete_hook(struct ospf_lsa *lsa); @@ -439,9 +440,11 @@ void ospf_delete_opaque_functab(u_char lsa_type, u_char opaque_type) if (functab->opaque_type == opaque_type) { /* Cleanup internal control information, if it * still remains. */ - if (functab->oipt != NULL) + if (functab->oipt != NULL) { free_opaque_info_per_type( functab->oipt); + free_opaque_info_owner(functab->oipt); + } /* Dequeue listnode entry from the list. */ listnode_delete(funclist, functab); @@ -572,6 +575,7 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab, top = ospf_lookup_by_vrf_id(new->vrf_id); if (new->area != NULL && (top = new->area->ospf) == NULL) { free_opaque_info_per_type((void *)oipt); + free_opaque_info_owner(oipt); oipt = NULL; goto out; /* This case may not exist. */ } @@ -583,6 +587,7 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab, "register_opaque_info_per_type: Unexpected LSA-type(%u)", new->data->type); free_opaque_info_per_type((void *)oipt); + free_opaque_info_owner(oipt); oipt = NULL; goto out; /* This case may not exist. */ } @@ -600,6 +605,35 @@ out: return oipt; } +/* Remove "oipt" from its owner's self-originated LSA list. */ +static void free_opaque_info_owner(void *val) +{ + struct opaque_info_per_type *oipt = (struct opaque_info_per_type *)val; + + switch (oipt->lsa_type) { + case OSPF_OPAQUE_LINK_LSA: { + struct ospf_interface *oi = + (struct ospf_interface *)(oipt->owner); + listnode_delete(oi->opaque_lsa_self, oipt); + break; + } + case OSPF_OPAQUE_AREA_LSA: { + struct ospf_area *area = (struct ospf_area *)(oipt->owner); + listnode_delete(area->opaque_lsa_self, oipt); + break; + } + case OSPF_OPAQUE_AS_LSA: { + struct ospf *top = (struct ospf *)(oipt->owner); + listnode_delete(top->opaque_lsa_self, oipt); + break; + } + default: + zlog_warn("free_opaque_info_owner: Unexpected LSA-type(%u)", + oipt->lsa_type); + break; /* This case may not exist. */ + } +} + static void free_opaque_info_per_type(void *val) { struct opaque_info_per_type *oipt = (struct opaque_info_per_type *)val; diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 8670359610..881226683c 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -3897,6 +3897,10 @@ static void ospf_ls_upd_queue_send(struct ospf_interface *oi, zlog_debug("listcount = %d, [%s]dst %s", listcount(update), IF_NAME(oi), inet_ntoa(addr)); + /* Check that we have really something to process */ + if (listcount(update) == 0) + return; + op = ospf_ls_upd_packet_new(update, oi); /* Prepare OSPF common header. */ From 7a5e6e46da05a1d65c28ffdb2b6c9ade29887cfe Mon Sep 17 00:00:00 2001 From: dturlupov Date: Fri, 9 Feb 2018 17:10:22 +0300 Subject: [PATCH 22/45] ospfd: OSPF support the +/- in set metric <+/-metric> Signed-off-by: Dmitrii Turlupov --- ospfd/ospf_routemap.c | 47 +++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c index b7a47602d0..f2769c6f38 100644 --- a/ospfd/ospf_routemap.c +++ b/ospfd/ospf_routemap.c @@ -337,6 +337,7 @@ static struct route_map_rule_cmd route_match_tag_cmd = { }; struct ospf_metric { + enum { metric_increment, metric_decrement, metric_absolute } type; bool used; u_int32_t metric; }; @@ -356,8 +357,19 @@ static route_map_result_t route_set_metric(void *rule, struct prefix *prefix, ei = object; /* Set metric out value. */ - if (metric->used) + if (!metric->used) + return RMAP_OKAY; + if (metric->type == metric_increment) + ei->route_map_set.metric += metric->metric; + if (metric->type == metric_decrement) + ei->route_map_set.metric -= metric->metric; + if (metric->type == metric_absolute) ei->route_map_set.metric = metric->metric; + + if ((signed int)ei->route_map_set.metric < 1) + ei->route_map_set.metric = -1; + if (ei->route_map_set.metric > OSPF_LS_INFINITY) + ei->route_map_set.metric = OSPF_LS_INFINITY; } return RMAP_OKAY; } @@ -370,23 +382,28 @@ static void *route_set_metric_compile(const char *arg) metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t)); metric->used = false; - /* OSPF doesn't support the +/- in - set metric <+/-metric> check - Ignore the +/- component */ - if (!all_digit(arg)) { - if ((arg[0] == '+' || arg[0] == '-') && all_digit(arg + 1)) { - zlog_warn("OSPF does not support 'set metric +/-'"); - arg++; - } else { - if (strmatch(arg, "+rtt") || strmatch(arg, "-rtt")) - zlog_warn( - "OSPF does not support 'set metric +rtt / -rtt'"); + if (all_digit(arg)) + metric->type = metric_absolute; - return metric; - } + if (strmatch(arg, "+rtt") || strmatch(arg, "-rtt")) { + zlog_warn("OSPF does not support 'set metric +rtt / -rtt'"); + return metric; } + + if ((arg[0] == '+') && all_digit(arg + 1)) { + metric->type = metric_increment; + arg++; + } + + if ((arg[0] == '-') && all_digit(arg + 1)) { + metric->type = metric_decrement; + arg++; + } + metric->metric = strtoul(arg, NULL, 10); - metric->used = true; + + if (metric->metric) + metric->used = true; return metric; } From 4e5c876fcbaabab958d4f5ceb3a509c9c5c75644 Mon Sep 17 00:00:00 2001 From: "G. Paul Ziemba" Date: Fri, 9 Feb 2018 09:29:39 -0800 Subject: [PATCH 23/45] bgpd: json route table brace counting --- bgpd/bgp_route.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 36e0c92482..ea2c4aea97 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -7872,7 +7872,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, struct bgp_table *table, enum bgp_show_type type, void *output_arg, u_char use_json, char *rd, int is_last, - unsigned long *output_cum, unsigned long *total_cum) + unsigned long *output_cum, unsigned long *total_cum, + unsigned long *json_header_depth) { struct bgp_info *ri; struct bgp_node *rn; @@ -7889,7 +7890,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (output_cum && *output_cum != 0) header = 0; - if (use_json && header) { + if (use_json && !*json_header_depth) { vty_out(vty, "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64 ",\n \"routerId\": \"%s\",\n \"routes\": { ", @@ -7897,8 +7898,11 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default" : bgp->name, table->version, inet_ntoa(bgp->router_id)); - if (rd) + *json_header_depth = 2; + if (rd) { vty_out(vty, " \"routeDistinguishers\" : {"); + ++*json_header_depth; + } json_paths = json_object_new_object(); } @@ -8131,10 +8135,14 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (use_json) { if (json_paths) json_object_free(json_paths); - if (is_last) - vty_out(vty, " } }\n"); - else - vty_out(vty, " }, "); + if (rd) { + vty_out(vty, " }%s ", (is_last? "": ",")); + } + if (is_last) { + unsigned long i; + for (i = 0; i < *json_header_depth; ++i) + vty_out(vty, " } "); + } } else { if (is_last) { /* No route is displayed */ @@ -8161,6 +8169,7 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, struct bgp_node *rn, *next; unsigned long output_cum = 0; unsigned long total_cum = 0; + unsigned long json_header_depth = 0; bool show_msg; show_msg = (!use_json && type == bgp_show_type_normal); @@ -8178,7 +8187,8 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, bgp_show_table(vty, bgp, safi, rn->info, type, output_arg, use_json, rd, next == NULL, - &output_cum, &total_cum); + &output_cum, &total_cum, + &json_header_depth); if (next == NULL) show_msg = false; } @@ -8192,14 +8202,13 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, "\nDisplayed %ld routes and %ld total paths\n", output_cum, total_cum); } - if (use_json) - vty_out(vty, " } }"); return CMD_SUCCESS; } static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, enum bgp_show_type type, void *output_arg, u_char use_json) { struct bgp_table *table; + unsigned long json_header_depth = 0; if (bgp == NULL) { bgp = bgp_get_default(); @@ -8224,7 +8233,7 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, safi = SAFI_UNICAST; return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json, - NULL, 1, NULL, NULL); + NULL, 1, NULL, NULL, &json_header_depth); } static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi, From 9386b58830660dc0c686ed9c7b0026f4fc94a35b Mon Sep 17 00:00:00 2001 From: "G. Paul Ziemba" Date: Fri, 9 Feb 2018 09:29:39 -0800 Subject: [PATCH 24/45] bgpd: json route table brace counting Signed-off-by: G. Paul Ziemba --- bgpd/bgp_route.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 36e0c92482..ea2c4aea97 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -7872,7 +7872,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, struct bgp_table *table, enum bgp_show_type type, void *output_arg, u_char use_json, char *rd, int is_last, - unsigned long *output_cum, unsigned long *total_cum) + unsigned long *output_cum, unsigned long *total_cum, + unsigned long *json_header_depth) { struct bgp_info *ri; struct bgp_node *rn; @@ -7889,7 +7890,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (output_cum && *output_cum != 0) header = 0; - if (use_json && header) { + if (use_json && !*json_header_depth) { vty_out(vty, "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64 ",\n \"routerId\": \"%s\",\n \"routes\": { ", @@ -7897,8 +7898,11 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default" : bgp->name, table->version, inet_ntoa(bgp->router_id)); - if (rd) + *json_header_depth = 2; + if (rd) { vty_out(vty, " \"routeDistinguishers\" : {"); + ++*json_header_depth; + } json_paths = json_object_new_object(); } @@ -8131,10 +8135,14 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (use_json) { if (json_paths) json_object_free(json_paths); - if (is_last) - vty_out(vty, " } }\n"); - else - vty_out(vty, " }, "); + if (rd) { + vty_out(vty, " }%s ", (is_last? "": ",")); + } + if (is_last) { + unsigned long i; + for (i = 0; i < *json_header_depth; ++i) + vty_out(vty, " } "); + } } else { if (is_last) { /* No route is displayed */ @@ -8161,6 +8169,7 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, struct bgp_node *rn, *next; unsigned long output_cum = 0; unsigned long total_cum = 0; + unsigned long json_header_depth = 0; bool show_msg; show_msg = (!use_json && type == bgp_show_type_normal); @@ -8178,7 +8187,8 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, bgp_show_table(vty, bgp, safi, rn->info, type, output_arg, use_json, rd, next == NULL, - &output_cum, &total_cum); + &output_cum, &total_cum, + &json_header_depth); if (next == NULL) show_msg = false; } @@ -8192,14 +8202,13 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, "\nDisplayed %ld routes and %ld total paths\n", output_cum, total_cum); } - if (use_json) - vty_out(vty, " } }"); return CMD_SUCCESS; } static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, enum bgp_show_type type, void *output_arg, u_char use_json) { struct bgp_table *table; + unsigned long json_header_depth = 0; if (bgp == NULL) { bgp = bgp_get_default(); @@ -8224,7 +8233,7 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, safi = SAFI_UNICAST; return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json, - NULL, 1, NULL, NULL); + NULL, 1, NULL, NULL, &json_header_depth); } static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi, From 9611232b4c2ca2d66adc1b6e5b294ea5b8cec714 Mon Sep 17 00:00:00 2001 From: "G. Paul Ziemba" Date: Fri, 9 Feb 2018 10:18:35 -0800 Subject: [PATCH 25/45] also protect ALIAS from indenting Signed-off-by: G. Paul Ziemba --- indent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indent.py b/indent.py index a2c18e556d..560c13c77d 100644 --- a/indent.py +++ b/indent.py @@ -6,7 +6,7 @@ import sys, re, subprocess, os # find all DEFUNs defun_re = re.compile( - r'^(DEF(UN(_NOSH|_HIDDEN)?|PY)\s*\(.*?)^(?=\s*\{)', + r'^((DEF(UN(_NOSH|_HIDDEN)?|PY)|ALIAS)\s*\(.*?)^(?=\s*\{)', re.M | re.S) define_re = re.compile( r'((^#\s*define[^\n]+[^\\]\n)+)', From a4d82a8adcb8c99625cbf5697c242b42c71f06bb Mon Sep 17 00:00:00 2001 From: "G. Paul Ziemba" Date: Fri, 9 Feb 2018 10:22:50 -0800 Subject: [PATCH 26/45] bgpd: ran indent.py on some files prior to bgp vpn-vrf leaking changes Signed-off-by: G. Paul Ziemba --- bgpd/bgp_debug.c | 4 +- bgpd/bgp_debug.h | 6 +- bgpd/bgp_mplsvpn.c | 6 +- bgpd/bgp_route.c | 497 +++++++++++++++++-------------------- bgpd/bgp_routemap.c | 18 +- bgpd/bgp_vty.c | 176 +++++++------ bgpd/bgp_zebra.c | 55 ++-- bgpd/bgpd.c | 89 +++---- bgpd/bgpd.h | 58 +++-- bgpd/rfapi/bgp_rfapi_cfg.c | 106 ++++---- 10 files changed, 502 insertions(+), 513 deletions(-) diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index b08522b68b..e89f399e41 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -385,8 +385,8 @@ int bgp_dump_attr(struct attr *attr, char *buf, size_t size) if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) snprintf(buf + strlen(buf), size - strlen(buf), - ", community %s", community_str(attr->community, - false)); + ", community %s", + community_str(attr->community, false)); if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) snprintf(buf + strlen(buf), size - strlen(buf), diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h index 7c773cfafb..765e43f5b4 100644 --- a/bgpd/bgp_debug.h +++ b/bgpd/bgp_debug.h @@ -153,9 +153,9 @@ extern int bgp_debug_zebra(struct prefix *p); extern int bgp_debug_count(void); extern const char *bgp_debug_rdpfxpath2str(afi_t, safi_t, struct prefix_rd *, - union prefixconstptr, - mpls_label_t *, u_int32_t, - int, u_int32_t, char *, int); + union prefixconstptr, mpls_label_t *, + u_int32_t, int, u_int32_t, char *, + int); const char *bgp_notify_admin_message(char *buf, size_t bufsz, u_char *data, size_t datalen); diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 0e2594ba8a..ec4989de8f 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -366,8 +366,8 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd, return CMD_WARNING; } table = bgp->rib[afi][SAFI_MPLS_VPN]; - return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, - table, prd, type, output_arg, use_json); + return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type, + output_arg, use_json); } DEFUN (show_bgp_ip_vpn_all_rd, @@ -389,7 +389,7 @@ DEFUN (show_bgp_ip_vpn_all_rd, if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) { if (argv_find(argv, argc, "rd", &idx)) { - ret = str2prefix_rd(argv[idx+1]->arg, &prd); + ret = str2prefix_rd(argv[idx + 1]->arg, &prd); if (!ret) { vty_out(vty, "%% Malformed Route Distinguisher\n"); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index ea2c4aea97..2a555aae32 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -771,7 +771,7 @@ static int bgp_info_cmp(struct bgp *bgp, struct bgp_info *new, /* If one path has a label but the other does not, do not treat * them as equals for multipath */ - if ((new->extra && bgp_is_valid_label(&new->extra->label[0])) + if ((new->extra &&bgp_is_valid_label(&new->extra->label[0])) != (exist->extra && bgp_is_valid_label(&exist->extra->label[0]))) { if (debug) @@ -1286,7 +1286,7 @@ void bgp_attr_add_gshut_community(struct attr *attr) if (old) { merge = community_merge(community_dup(old), gshut); - if (old->refcnt== 0) + if (old->refcnt == 0) community_free(old); new = community_uniq_sort(merge); @@ -1662,7 +1662,8 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri, } if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) { - if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED) { + if (peer->sort == BGP_PEER_IBGP + || peer->sort == BGP_PEER_CONFED) { attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); attr->local_pref = BGP_GSHUT_LOCAL_PREF; } else { @@ -1718,8 +1719,8 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri, subgrp)) subgroup_announce_reset_nhop( (peer_cap_enhe(peer, afi, safi) - ? AF_INET6 - : p->family), + ? AF_INET6 + : p->family), attr); } /* If IPv6/MP and nexthop does not have any override and happens @@ -1966,8 +1967,9 @@ int subgroup_process_announce_selected(struct update_subgroup *subgrp, : NULL); /* First update is deferred until ORF or ROUTE-REFRESH is received */ - if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi], - PEER_STATUS_ORF_WAIT_REFRESH)) + if (onlypeer + && CHECK_FLAG(onlypeer->af_sflags[afi][safi], + PEER_STATUS_ORF_WAIT_REFRESH)) return 0; memset(&attr, 0, sizeof(struct attr)); @@ -2043,7 +2045,7 @@ int bgp_zebra_has_route_changed(struct bgp_node *rn, struct bgp_info *selected) struct bgp_process_queue { struct bgp *bgp; - STAILQ_HEAD(, bgp_node)pqueue; + STAILQ_HEAD(, bgp_node) pqueue; #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0) unsigned int flags; unsigned int queued; @@ -2105,7 +2107,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn, } else bgp_register_for_label(rn, new_select); } - } else if (CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) { + } else if (CHECK_FLAG(rn->flags, + BGP_NODE_REGISTERED_FOR_LABEL)) { bgp_unregister_for_label(rn); } } else if (CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) { @@ -2226,9 +2229,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn, /* advertise/withdraw type-5 routes */ if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) { if (new_select) - bgp_evpn_advertise_type5_route(bgp, &rn->p, - new_select->attr, - afi, safi); + bgp_evpn_advertise_type5_route( + bgp, &rn->p, new_select->attr, afi, safi); else if (old_select) bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi); } @@ -2307,7 +2309,8 @@ static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp) { struct bgp_process_queue *pqnode; - pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE, sizeof(struct bgp_process_queue)); + pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE, + sizeof(struct bgp_process_queue)); /* unlocked in bgp_processq_del */ pqnode->bgp = bgp_lock(bgp); @@ -2331,13 +2334,15 @@ void bgp_process(struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi) return; /* Add route nodes to an existing work queue item until reaching the - limit only if is from the same BGP view and it's not an EOIU marker */ + limit only if is from the same BGP view and it's not an EOIU marker + */ if (work_queue_item_count(wq)) { struct work_queue_item *item = work_queue_last_item(wq); pqnode = item->data; - if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER) || - pqnode->bgp != bgp || pqnode->queued >= ARBITRARY_PROCESS_QLEN) + if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER) + || pqnode->bgp != bgp + || pqnode->queued >= ARBITRARY_PROCESS_QLEN) pqnode = bgp_processq_alloc(bgp); else pqnode_reuse = 1; @@ -2673,9 +2678,9 @@ static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, struct attr *attr, afi_t afi, safi_t safi, int type, - int sub_type, struct prefix_rd *prd, - mpls_label_t *label, u_int32_t num_labels, - int soft_reconfig, struct bgp_route_evpn *evpn) + int sub_type, struct prefix_rd *prd, mpls_label_t *label, + u_int32_t num_labels, int soft_reconfig, + struct bgp_route_evpn *evpn) { int ret; int aspath_loop_count = 0; @@ -2726,7 +2731,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, if (peer->change_local_as) { if (peer->allowas_in[afi][safi]) aspath_loop_count = peer->allowas_in[afi][safi]; - else if (!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)) + else if (!CHECK_FLAG(peer->flags, + PEER_FLAG_LOCAL_AS_NO_PREPEND)) aspath_loop_count = 1; if (aspath_loop_check(attr->aspath, peer->change_local_as) @@ -2792,23 +2798,24 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, if (peer->sort == BGP_PEER_EBGP) { - /* If we receive the graceful-shutdown community from an eBGP peer we - * must lower local-preference */ - if (new_attr.community && - community_include(new_attr.community, COMMUNITY_GSHUT)) { + /* If we receive the graceful-shutdown community from an eBGP + * peer we must lower local-preference */ + if (new_attr.community + && community_include(new_attr.community, COMMUNITY_GSHUT)) { new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); new_attr.local_pref = BGP_GSHUT_LOCAL_PREF; - /* If graceful-shutdown is configured then add the GSHUT community to - * all paths received from eBGP peers */ - } else if (bgp_flag_check(peer->bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) { + /* If graceful-shutdown is configured then add the GSHUT + * community to all paths received from eBGP peers */ + } else if (bgp_flag_check(peer->bgp, + BGP_FLAG_GRACEFUL_SHUTDOWN)) { bgp_attr_add_gshut_community(&new_attr); } } /* next hop check. */ - if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) && - bgp_update_martian_nexthop(bgp, afi, safi, &new_attr)) { + if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) + && bgp_update_martian_nexthop(bgp, afi, safi, &new_attr)) { reason = "martian or self next-hop;"; bgp_attr_flush(&new_attr); goto filtered; @@ -2837,10 +2844,10 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, && CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)) { if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str( - afi, safi, prd, p, - label, num_labels, - addpath_id ? 1 : 0, addpath_id, - pfx_buf, sizeof(pfx_buf)); + afi, safi, prd, p, label, + num_labels, addpath_id ? 1 : 0, + addpath_id, pfx_buf, + sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); } @@ -2863,10 +2870,10 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, } bgp_debug_rdpfxpath2str( - afi, safi, prd, p, - label, num_labels, - addpath_id ? 1 : 0, addpath_id, - pfx_buf, sizeof(pfx_buf)); + afi, safi, prd, p, label, + num_labels, addpath_id ? 1 : 0, + addpath_id, pfx_buf, + sizeof(pfx_buf)); zlog_debug( "%s rcvd %s...duplicate ignored", peer->host, pfx_buf); @@ -2890,8 +2897,7 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) { if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str( - afi, safi, prd, p, - label, num_labels, + afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug( @@ -2904,10 +2910,10 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Received Logging. */ if (bgp_debug_update(peer, p, NULL, 1)) { - bgp_debug_rdpfxpath2str(afi, safi, prd, p, - label, num_labels, - addpath_id ? 1 : 0, addpath_id, - pfx_buf, sizeof(pfx_buf)); + bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, + num_labels, addpath_id ? 1 : 0, + addpath_id, pfx_buf, + sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); } @@ -3058,8 +3064,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, connected = 0; if (bgp_find_or_add_nexthop(bgp, afi, ri, NULL, - connected) || - CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) + connected) + || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) bgp_info_set_flag(rn, ri, BGP_INFO_VALID); else { if (BGP_DEBUG(nht, NHT)) { @@ -3138,8 +3144,7 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, peer->rcvd_attr_printed = 1; } - bgp_debug_rdpfxpath2str(afi, safi, prd, p, - label, num_labels, + bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); @@ -3151,8 +3156,7 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Update MPLS label */ if (has_valid_label) { extra = bgp_info_extra_get(new); - memcpy(&extra->label, label, - num_labels * sizeof(mpls_label_t)); + memcpy(&extra->label, label, num_labels * sizeof(mpls_label_t)); extra->num_labels = num_labels; if (!(afi == AFI_L2VPN && safi == SAFI_EVPN)) bgp_set_valid_label(&extra->label[0]); @@ -3175,8 +3179,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, else connected = 0; - if (bgp_find_or_add_nexthop(bgp, afi, new, NULL, connected) || - CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) + if (bgp_find_or_add_nexthop(bgp, afi, new, NULL, connected) + || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) bgp_info_set_flag(rn, new, BGP_INFO_VALID); else { if (BGP_DEBUG(nht, NHT)) { @@ -3257,8 +3261,7 @@ filtered: peer->rcvd_attr_printed = 1; } - bgp_debug_rdpfxpath2str(afi, safi, prd, p, - label, num_labels, + bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s", @@ -3293,9 +3296,8 @@ filtered: int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id, struct attr *attr, afi_t afi, safi_t safi, int type, - int sub_type, struct prefix_rd *prd, - mpls_label_t *label, u_int32_t num_labels, - struct bgp_route_evpn *evpn) + int sub_type, struct prefix_rd *prd, mpls_label_t *label, + u_int32_t num_labels, struct bgp_route_evpn *evpn) { struct bgp *bgp; char pfx_buf[BGP_PRD_PATH_STRLEN]; @@ -3330,8 +3332,7 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id, if (!bgp_adj_in_unset(rn, peer, addpath_id)) { if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str( - afi, safi, prd, p, - label, num_labels, + afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug( @@ -3351,8 +3352,7 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Logging. */ if (bgp_debug_update(peer, p, NULL, 1)) { - bgp_debug_rdpfxpath2str(afi, safi, prd, p, - label, num_labels, + bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host, @@ -3363,8 +3363,7 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id, if (ri && !CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)) bgp_rib_withdraw(rn, ri, peer, afi, safi, prd); else if (bgp_debug_update(peer, p, NULL, 1)) { - bgp_debug_rdpfxpath2str(afi, safi, prd, p, - label, num_labels, + bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s Can't find the route %s", peer->host, pfx_buf); @@ -3500,8 +3499,8 @@ static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi, ret = bgp_update(peer, &rn->p, ain->addpath_rx_id, ain->attr, afi, safi, ZEBRA_ROUTE_BGP, - BGP_ROUTE_NORMAL, prd, - label_pnt, num_labels, 1, NULL); + BGP_ROUTE_NORMAL, prd, label_pnt, + num_labels, 1, NULL); if (ret < 0) { bgp_unlock_node(rn); @@ -4016,7 +4015,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, * an error SHOULD * be logged locally, and the prefix SHOULD be * ignored. - */ + */ zlog_err( "%s: IPv4 unicast NLRI is multicast address %s, ignoring", peer->host, inet_ntoa(p.u.prefix4)); @@ -4058,8 +4057,8 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, else ret = bgp_withdraw(peer, &p, addpath_id, attr, afi, safi, ZEBRA_ROUTE_BGP, - BGP_ROUTE_NORMAL, NULL, - NULL, 0, NULL); + BGP_ROUTE_NORMAL, NULL, NULL, 0, + NULL); /* Address family configuration mismatch or maximum-prefix count overflow. */ @@ -4555,8 +4554,7 @@ static int bgp_static_set(struct vty *vty, const char *negate, rn = bgp_node_lookup(bgp->route[afi][safi], &p); if (!rn) { - vty_out(vty, - "%% Can't find static route specified\n"); + vty_out(vty, "%% Can't find static route specified\n"); return CMD_WARNING_CONFIG_FAILED; } @@ -4601,8 +4599,8 @@ static int bgp_static_set(struct vty *vty, const char *negate, } /* Check previous routes are installed into BGP. */ - if (bgp_static->valid && - bgp_static->backdoor != backdoor) + if (bgp_static->valid + && bgp_static->backdoor != backdoor) need_update = 1; bgp_static->backdoor = backdoor; @@ -4610,7 +4608,7 @@ static int bgp_static_set(struct vty *vty, const char *negate, if (rmap) { if (bgp_static->rmap.name) XFREE(MTYPE_ROUTE_MAP_NAME, - bgp_static->rmap.name); + bgp_static->rmap.name); bgp_static->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap); bgp_static->rmap.map = @@ -4618,7 +4616,7 @@ static int bgp_static_set(struct vty *vty, const char *negate, } else { if (bgp_static->rmap.name) XFREE(MTYPE_ROUTE_MAP_NAME, - bgp_static->rmap.name); + bgp_static->rmap.name); bgp_static->rmap.name = NULL; bgp_static->rmap.map = NULL; bgp_static->valid = 0; @@ -4636,7 +4634,7 @@ static int bgp_static_set(struct vty *vty, const char *negate, if (rmap) { if (bgp_static->rmap.name) XFREE(MTYPE_ROUTE_MAP_NAME, - bgp_static->rmap.name); + bgp_static->rmap.name); bgp_static->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap); bgp_static->rmap.map = @@ -5109,11 +5107,10 @@ DEFPY(bgp_network, } } - return bgp_static_set(vty, no, address_str ? addr_prefix_str:prefix_str, - AFI_IP, bgp_node_safi(vty), - map_name, backdoor?1:0, - label_index ? - (uint32_t)label_index : BGP_INVALID_LABEL_INDEX); + return bgp_static_set( + vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP, + bgp_node_safi(vty), map_name, backdoor ? 1 : 0, + label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX); } DEFPY(ipv6_bgp_network, @@ -5128,10 +5125,9 @@ DEFPY(ipv6_bgp_network, "Label index to associate with the prefix\n" "Label index value\n") { - return bgp_static_set(vty, no, prefix_str, AFI_IP6, - bgp_node_safi(vty), map_name, 0, - label_index ? - (uint32_t)label_index : BGP_INVALID_LABEL_INDEX); + return bgp_static_set( + vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0, + label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX); } /* Aggreagete address: @@ -5856,8 +5852,7 @@ DEFUN (no_ipv6_aggregate_address, void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, const union g_addr *nexthop, ifindex_t ifindex, enum nexthop_types_t nhtype, uint32_t metric, - u_char type, u_short instance, - route_tag_t tag) + u_char type, u_short instance, route_tag_t tag) { struct bgp_info *new; struct bgp_info *bi; @@ -5872,7 +5867,7 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, /* Make default attribute. */ bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE); - switch(nhtype) { + switch (nhtype) { case NEXTHOP_TYPE_IFINDEX: break; case NEXTHOP_TYPE_IPV4: @@ -6253,13 +6248,13 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, switch (af) { case AF_INET: sprintf(nexthop, "%s", - inet_ntop(af, &attr->mp_nexthop_global_in, - buf, BUFSIZ)); + inet_ntop(af, &attr->mp_nexthop_global_in, buf, + BUFSIZ)); break; case AF_INET6: sprintf(nexthop, "%s", - inet_ntop(af, &attr->mp_nexthop_global, - buf, BUFSIZ)); + inet_ntop(af, &attr->mp_nexthop_global, buf, + BUFSIZ)); break; default: sprintf(nexthop, "?"); @@ -6269,13 +6264,10 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, if (json_paths) { json_nexthop_global = json_object_new_object(); + json_object_string_add(json_nexthop_global, "afi", + (af == AF_INET) ? "ip" : "ipv6"); json_object_string_add(json_nexthop_global, - "afi", - (af == AF_INET) ? - "ip" : "ipv6"); - json_object_string_add(json_nexthop_global, - (af == AF_INET) ? - "ip" : "ipv6", + (af == AF_INET) ? "ip" : "ipv6", nexthop); json_object_boolean_true_add(json_nexthop_global, "used"); @@ -6287,92 +6279,80 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, json_object_string_add(json_nexthop_global, "ip", inet_ntoa(attr->nexthop)); - json_object_string_add(json_nexthop_global, - "afi", "ipv4"); + json_object_string_add(json_nexthop_global, "afi", + "ipv4"); json_object_boolean_true_add(json_nexthop_global, "used"); } else vty_out(vty, "%-16s", inet_ntoa(attr->nexthop)); } /* IPv4 Next Hop */ - else if (p->family == AF_INET - && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { + else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { if (json_paths) { json_nexthop_global = json_object_new_object(); - if ((safi == SAFI_MPLS_VPN) - || (safi == SAFI_EVPN)) - json_object_string_add(json_nexthop_global, - "ip", - inet_ntoa(attr->mp_nexthop_global_in)); + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) + json_object_string_add( + json_nexthop_global, "ip", + inet_ntoa(attr->mp_nexthop_global_in)); else - json_object_string_add(json_nexthop_global, - "ip", - inet_ntoa(attr->nexthop)); + json_object_string_add( + json_nexthop_global, "ip", + inet_ntoa(attr->nexthop)); - json_object_string_add(json_nexthop_global, - "afi", "ipv4"); + json_object_string_add(json_nexthop_global, "afi", + "ipv4"); json_object_boolean_true_add(json_nexthop_global, "used"); } else { - if ((safi == SAFI_MPLS_VPN) - || (safi == SAFI_EVPN)) + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) vty_out(vty, "%-16s", - inet_ntoa( - attr->mp_nexthop_global_in)); + inet_ntoa(attr->mp_nexthop_global_in)); else - vty_out(vty, "%-16s", - inet_ntoa(attr->nexthop)); + vty_out(vty, "%-16s", inet_ntoa(attr->nexthop)); } } /* IPv6 Next Hop */ - else if (p->family == AF_INET6 - || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { + else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { int len; char buf[BUFSIZ]; if (json_paths) { json_nexthop_global = json_object_new_object(); - json_object_string_add(json_nexthop_global, "ip", - inet_ntop(AF_INET6, - &attr->mp_nexthop_global, buf, - BUFSIZ)); - json_object_string_add(json_nexthop_global, - "afi", "ipv6"); - json_object_string_add(json_nexthop_global, - "scope", "global"); + json_object_string_add( + json_nexthop_global, "ip", + inet_ntop(AF_INET6, &attr->mp_nexthop_global, + buf, BUFSIZ)); + json_object_string_add(json_nexthop_global, "afi", + "ipv6"); + json_object_string_add(json_nexthop_global, "scope", + "global"); /* We display both LL & GL if both have been * received */ if ((attr->mp_nexthop_len == 32) || (binfo->peer->conf_if)) { - json_nexthop_ll = - json_object_new_object(); + json_nexthop_ll = json_object_new_object(); json_object_string_add( json_nexthop_ll, "ip", - inet_ntop( - AF_INET6, - &attr->mp_nexthop_local, - buf, BUFSIZ)); - json_object_string_add(json_nexthop_ll, - "afi", "ipv6"); - json_object_string_add(json_nexthop_ll, - "scope", + inet_ntop(AF_INET6, + &attr->mp_nexthop_local, buf, + BUFSIZ)); + json_object_string_add(json_nexthop_ll, "afi", + "ipv6"); + json_object_string_add(json_nexthop_ll, "scope", "link-local"); - if ((IPV6_ADDR_CMP( - &attr->mp_nexthop_global, - &attr->mp_nexthop_local) + if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global, + &attr->mp_nexthop_local) != 0) && !attr->mp_nexthop_prefer_global) json_object_boolean_true_add( - json_nexthop_ll, - "used"); + json_nexthop_ll, "used"); else json_object_boolean_true_add( - json_nexthop_global, - "used"); + json_nexthop_global, "used"); } else json_object_boolean_true_add( json_nexthop_global, "used"); @@ -6383,20 +6363,17 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, && !attr->mp_nexthop_prefer_global) || (binfo->peer->conf_if)) { if (binfo->peer->conf_if) { - len = vty_out( - vty, "%s", - binfo->peer->conf_if); + len = vty_out(vty, "%s", + binfo->peer->conf_if); len = 16 - len; /* len of IPv6 addr + max len of def ifname */ if (len < 1) - vty_out(vty, "\n%*s", - 36, " "); + vty_out(vty, "\n%*s", 36, " "); else - vty_out(vty, "%*s", len, - " "); + vty_out(vty, "%*s", len, " "); } else { len = vty_out( vty, "%s", @@ -6407,17 +6384,16 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, len = 16 - len; if (len < 1) - vty_out(vty, "\n%*s", - 36, " "); + vty_out(vty, "\n%*s", 36, " "); else - vty_out(vty, "%*s", len, - " "); + vty_out(vty, "%*s", len, " "); } } else { - len = vty_out(vty, "%s", - inet_ntop(AF_INET6, - &attr->mp_nexthop_global, - buf, BUFSIZ)); + len = vty_out( + vty, "%s", + inet_ntop(AF_INET6, + &attr->mp_nexthop_global, buf, + BUFSIZ)); len = 16 - len; if (len < 1) @@ -6431,8 +6407,7 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, /* MED/Metric */ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) if (json_paths) - json_object_int_add(json_path, "med", - attr->med); + json_object_int_add(json_path, "med", attr->med); else vty_out(vty, "%10u", attr->med); else if (!json_paths) @@ -6455,10 +6430,9 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, if (json_paths) { char buf[BUFSIZ]; - json_object_string_add(json_path, "peerId", - sockunion2str(&binfo->peer->su, - buf, - SU_ADDRSTRLEN)); + json_object_string_add( + json_path, "peerId", + sockunion2str(&binfo->peer->su, buf, SU_ADDRSTRLEN)); } /* Print aspath */ @@ -6472,9 +6446,8 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, /* Print origin */ if (json_paths) - json_object_string_add( - json_path, "origin", - bgp_origin_long_str[attr->origin]); + json_object_string_add(json_path, "origin", + bgp_origin_long_str[attr->origin]); else vty_out(vty, "%s", bgp_origin_str[attr->origin]); @@ -6672,8 +6645,7 @@ void route_vty_out_tag(struct vty *vty, struct prefix *p, if (attr) { if (((p->family == AF_INET) && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) - || (safi == SAFI_EVPN - && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) + || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) { @@ -6867,9 +6839,10 @@ static void damp_route_vty_out(struct vty *vty, struct prefix *p, bgp_damp_reuse_time_vty(vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json); else - vty_out(vty, "%s ", bgp_damp_reuse_time_vty(vty, binfo, timebuf, - BGP_UPTIME_LEN, - use_json, json)); + vty_out(vty, "%s ", + bgp_damp_reuse_time_vty(vty, binfo, timebuf, + BGP_UPTIME_LEN, use_json, + json)); /* Print attribute */ attr = binfo->attr; @@ -6948,8 +6921,9 @@ static void flap_route_vty_out(struct vty *vty, struct prefix *p, peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json, json); else - vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf, - BGP_UPTIME_LEN, 0, NULL)); + vty_out(vty, "%s ", + peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 0, + NULL)); if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED) && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) { @@ -7090,8 +7064,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, tag_buf[0] = '\0'; if (binfo->extra && binfo->extra->num_labels) { bgp_evpn_label2str(binfo->extra->label, - binfo->extra->num_labels, - tag_buf, sizeof(tag_buf)); + binfo->extra->num_labels, tag_buf, + sizeof(tag_buf)); vty_out(vty, " VNI %s", tag_buf); } vty_out(vty, "\n"); @@ -7201,8 +7175,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, /* Line2 display Next-hop, Neighbor, Router-id */ /* Display the nexthop */ - if ((p->family == AF_INET || p->family == AF_ETHERNET || - p->family == AF_EVPN) + if ((p->family == AF_INET || p->family == AF_ETHERNET + || p->family == AF_EVPN) && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { @@ -7610,8 +7584,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, if (attr->community) { if (json_paths) { if (!attr->community->json) - community_str(attr->community, - true); + community_str(attr->community, true); json_object_lock(attr->community->json); json_object_object_add(json_path, "community", attr->community->json); @@ -7731,8 +7704,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, if (binfo->extra && bgp_is_valid_label(&binfo->extra->label[0])) #endif { - mpls_label_t label = label_pton( - &binfo->extra->label[0]); + mpls_label_t label = + label_pton(&binfo->extra->label[0]); if (json_paths) json_object_int_add(json_path, "remoteLabel", label); @@ -7860,9 +7833,8 @@ static int bgp_show_community_list(struct vty *vty, struct bgp *bgp, static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp, const char *prefix, afi_t afi, safi_t safi, enum bgp_show_type type); -static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, - const char *regstr, afi_t afi, - safi_t safi, enum bgp_show_type type); +static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr, + afi_t afi, safi_t safi, enum bgp_show_type type); static int bgp_show_community(struct vty *vty, struct bgp *bgp, const char *comstr, int exact, afi_t afi, safi_t safi); @@ -7870,9 +7842,9 @@ static int bgp_show_community(struct vty *vty, struct bgp *bgp, static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, struct bgp_table *table, enum bgp_show_type type, - void *output_arg, u_char use_json, - char *rd, int is_last, - unsigned long *output_cum, unsigned long *total_cum, + void *output_arg, u_char use_json, char *rd, + int is_last, unsigned long *output_cum, + unsigned long *total_cum, unsigned long *json_header_depth) { struct bgp_info *ri; @@ -7927,8 +7899,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, || type == bgp_show_type_flap_neighbor || type == bgp_show_type_dampend_paths || type == bgp_show_type_damp_neighbor) { - if (!(ri->extra - && ri->extra->damp_info)) + if (!(ri->extra && ri->extra->damp_info)) continue; } if (type == bgp_show_type_regexp) { @@ -7963,8 +7934,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, binfo.peer = ri->peer; binfo.attr = &dummy_attr; - ret = route_map_apply(rmap, &rn->p, - RMAP_BGP, &binfo); + ret = route_map_apply(rmap, &rn->p, RMAP_BGP, + &binfo); if (ret == RMAP_DENYMATCH) continue; } @@ -7975,8 +7946,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (ri->peer == NULL || ri->peer->su_remote == NULL - || !sockunion_same(ri->peer->su_remote, - su)) + || !sockunion_same(ri->peer->su_remote, su)) continue; } if (type == bgp_show_type_cidr_only) { @@ -8015,19 +7985,17 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, struct community *com = output_arg; if (!ri->attr->community - || !community_cmp(ri->attr->community, - com)) + || !community_cmp(ri->attr->community, com)) continue; } if (type == bgp_show_type_community_list) { struct community_list *list = output_arg; - if (!community_list_match( - ri->attr->community, list)) + if (!community_list_match(ri->attr->community, + list)) continue; } - if (type - == bgp_show_type_community_list_exact) { + if (type == bgp_show_type_community_list_exact) { struct community_list *list = output_arg; if (!community_list_exact_match( @@ -8045,8 +8013,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (type == bgp_show_type_lcommunity_list) { struct community_list *list = output_arg; - if (!lcommunity_list_match( - ri->attr->lcommunity, list)) + if (!lcommunity_list_match(ri->attr->lcommunity, + list)) continue; } if (type == bgp_show_type_lcommunity_all) { @@ -8071,9 +8039,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (type == bgp_show_type_dampend_paths || type == bgp_show_type_damp_neighbor) vty_out(vty, BGP_SHOW_DAMP_HEADER); - else if ( - type == bgp_show_type_flap_statistics - || type == bgp_show_type_flap_neighbor) + else if (type == bgp_show_type_flap_statistics + || type == bgp_show_type_flap_neighbor) vty_out(vty, BGP_SHOW_FLAP_HEADER); else vty_out(vty, BGP_SHOW_HEADER); @@ -8088,16 +8055,14 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (type == bgp_show_type_dampend_paths || type == bgp_show_type_damp_neighbor) damp_route_vty_out(vty, &rn->p, ri, display, - safi, use_json, - json_paths); + safi, use_json, json_paths); else if (type == bgp_show_type_flap_statistics || type == bgp_show_type_flap_neighbor) flap_route_vty_out(vty, &rn->p, ri, display, - safi, use_json, - json_paths); + safi, use_json, json_paths); else - route_vty_out(vty, &rn->p, ri, display, - safi, json_paths); + route_vty_out(vty, &rn->p, ri, display, safi, + json_paths); display++; } @@ -8108,8 +8073,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, p = &rn->p; sprintf(buf2, "%s/%d", - inet_ntop(p->family, &p->u.prefix, - buf, BUFSIZ), + inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); if (first) vty_out(vty, "\"%s\": ", buf2); @@ -8136,12 +8100,12 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (json_paths) json_object_free(json_paths); if (rd) { - vty_out(vty, " }%s ", (is_last? "": ",")); + vty_out(vty, " }%s ", (is_last ? "" : ",")); } if (is_last) { - unsigned long i; - for (i = 0; i < *json_header_depth; ++i) - vty_out(vty, " } "); + unsigned long i; + for (i = 0; i < *json_header_depth; ++i) + vty_out(vty, " } "); } } else { if (is_last) { @@ -8185,8 +8149,7 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, memcpy(&prd, &(rn->p), sizeof(struct prefix_rd)); prefix_rd2str(&prd, rd, sizeof(rd)); bgp_show_table(vty, bgp, safi, rn->info, type, - output_arg, use_json, - rd, next == NULL, + output_arg, use_json, rd, next == NULL, &output_cum, &total_cum, &json_header_depth); if (next == NULL) @@ -8338,8 +8301,8 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, vty_out(vty, "BGP routing table entry for %s%s%s/%d\n", ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) - ? prefix_rd2str(prd, buf1, sizeof(buf1)) - : ""), + ? prefix_rd2str(prd, buf1, sizeof(buf1)) + : ""), ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) ? ":" : "", buf2, p->prefixlen); @@ -8550,8 +8513,9 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp, if (display) json_object_object_add(json, "paths", json_paths); - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } else { if (!display) { @@ -8818,14 +8782,17 @@ DEFUN (show_ip_bgp, if (argv_find(argv, argc, "community", &idx)) { /* show a specific community */ if (argv_find(argv, argc, "local-AS", &idx_community_type) - || argv_find(argv, argc, "no-advertise", &idx_community_type) + || argv_find(argv, argc, "no-advertise", + &idx_community_type) || argv_find(argv, argc, "no-export", &idx_community_type) - || argv_find(argv, argc, "graceful-shutdown", &idx_community_type) + || argv_find(argv, argc, "graceful-shutdown", + &idx_community_type) || argv_find(argv, argc, "AA:NN", &idx_community_type)) { if (argv_find(argv, argc, "exact-match", &idx)) exact_match = 1; - return bgp_show_community(vty, bgp, argv[idx_community_type]->arg, + return bgp_show_community(vty, bgp, + argv[idx_community_type]->arg, exact_match, afi, safi); } } @@ -9043,9 +9010,8 @@ DEFUN (show_ip_bgp_instance_all, return CMD_SUCCESS; } -static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, - const char *regstr, afi_t afi, - safi_t safi, enum bgp_show_type type) +static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr, + afi_t afi, safi_t safi, enum bgp_show_type type) { regex_t *regex; int rc; @@ -9192,7 +9158,8 @@ static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, ip_str); vty_out(vty, "%s\n", json_object_to_json_string_ext( - json_no, JSON_C_TO_STRING_PRETTY)); + json_no, + JSON_C_TO_STRING_PRETTY)); json_object_free(json_no); } else vty_out(vty, @@ -9213,8 +9180,8 @@ static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, json_object_string_add(json_no, "warning", "No such neighbor"); vty_out(vty, "%s\n", - json_object_to_json_string_ext(json_no, - JSON_C_TO_STRING_PRETTY)); + json_object_to_json_string_ext( + json_no, JSON_C_TO_STRING_PRETTY)); json_object_free(json_no); } else vty_out(vty, "No such neighbor\n"); @@ -9332,8 +9299,8 @@ static int bgp_table_stats_walker(struct thread *t) ts->counts[BGP_STATS_UNAGGREGATEABLE]++; /* announced address space */ if (space) - ts->total_space += pow(2.0, - space - rn->p.prefixlen); + ts->total_space += + pow(2.0, space - rn->p.prefixlen); } else if (prn->info) ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++; @@ -9448,20 +9415,20 @@ static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi, if (afi == AFI_IP6) { vty_out(vty, "%30s: ", "/32 equivalent "); vty_out(vty, "%12g\n", - ts.total_space * pow(2.0, -128+32)); + ts.total_space * pow(2.0, -128 + 32)); vty_out(vty, "%30s: ", "/48 equivalent "); vty_out(vty, "%12g\n", - ts.total_space * pow(2.0, -128+48)); + ts.total_space * pow(2.0, -128 + 48)); } else { vty_out(vty, "%30s: ", "% announced "); vty_out(vty, "%12.2f\n", ts.total_space * 100. * pow(2.0, -32)); vty_out(vty, "%30s: ", "/8 equivalent "); vty_out(vty, "%12.2f\n", - ts.total_space * pow(2.0, -32+8)); + ts.total_space * pow(2.0, -32 + 8)); vty_out(vty, "%30s: ", "/24 equivalent "); vty_out(vty, "%12.2f\n", - ts.total_space * pow(2.0, -32+24)); + ts.total_space * pow(2.0, -32 + 24)); } break; default: @@ -9598,9 +9565,9 @@ static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi, pcounts.table = peer->bgp->rib[afi][safi]; /* in-place call via thread subsystem so as to record execution time - * * stats for the thread-walk (i.e. ensure this can't be blamed on - * * on just vty_read()). - * */ + * * stats for the thread-walk (i.e. ensure this can't be blamed on + * * on just vty_read()). + * */ thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0); if (use_json) { @@ -9623,8 +9590,9 @@ static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi, json, "recommended", "Please report this bug, with the above command output"); } - vty_out(vty, "%s\n", json_object_to_json_string_ext(json, - JSON_C_TO_STRING_PRETTY)); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } else { @@ -9858,8 +9826,9 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, "bgpOriginatingDefaultNetwork", "0.0.0.0"); } else { - vty_out(vty, "BGP table version is %" PRIu64 - ", local router ID is %s\n", + vty_out(vty, + "BGP table version is %" PRIu64 + ", local router ID is %s\n", table->version, inet_ntoa(bgp->router_id)); vty_out(vty, BGP_SHOW_SCODE_HEADER); vty_out(vty, BGP_SHOW_OCODE_HEADER); @@ -9970,19 +9939,14 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, } if (adj->attr) { - bgp_attr_dup(&attr, - adj->attr); + bgp_attr_dup(&attr, adj->attr); ret = bgp_output_modifier( - peer, &rn->p, - &attr, afi, - safi, - rmap_name); + peer, &rn->p, &attr, + afi, safi, rmap_name); if (ret != RMAP_DENY) { route_vty_out_tmp( - vty, - &rn->p, - &attr, - safi, + vty, &rn->p, + &attr, safi, use_json, json_ar); output_count++; @@ -10007,8 +9971,9 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, output_count); } if (use_json) { - vty_out(vty, "%s\n", json_object_to_json_string_ext(json, - JSON_C_TO_STRING_PRETTY)); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } } @@ -10945,18 +10910,20 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp, prefix_rd2str(prd, rdbuf, sizeof(rdbuf)); if (p->u.prefix_evpn.route_type == 5) { char local_buf[PREFIX_STRLEN]; - uint8_t family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p) - ? AF_INET - : AF_INET6; - inet_ntop(family, &p->u.prefix_evpn.ip.ip.addr, local_buf, - PREFIX_STRLEN); - sprintf(buf, "%s/%u", local_buf,p->u.prefix_evpn.ip_prefix_length); + uint8_t family = IS_EVPN_PREFIX_IPADDR_V4(( + struct prefix_evpn *)p) + ? AF_INET + : AF_INET6; + inet_ntop(family, &p->u.prefix_evpn.ip.ip.addr, + local_buf, PREFIX_STRLEN); + sprintf(buf, "%s/%u", local_buf, + p->u.prefix_evpn.ip_prefix_length); } else { prefix2str(p, buf, sizeof(buf)); } - if (bgp_static->gatewayIp.family == AF_INET || - bgp_static->gatewayIp.family == AF_INET6) + if (bgp_static->gatewayIp.family == AF_INET + || bgp_static->gatewayIp.family == AF_INET6) inet_ntop(bgp_static->gatewayIp.family, &bgp_static->gatewayIp.u.prefix, buf2, sizeof(buf2)); diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index de2410e009..7107c8403b 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -618,8 +618,7 @@ static route_map_result_t route_match_mac_address(void *rule, p.prefixlen = ETH_ALEN * 8; p.u.prefix_eth = prefix->u.prefix_evpn.mac; - return (access_list_apply(alist, &p) - == FILTER_DENY + return (access_list_apply(alist, &p) == FILTER_DENY ? RMAP_NOMATCH : RMAP_MATCH); } @@ -3519,9 +3518,9 @@ DEFUN (set_ip_nexthop_peer, "Use peer address (for BGP only)\n") { int (*func)(struct vty *, struct route_map_index *, const char *, - const char *) = strmatch(argv[0]->text, "no") - ? generic_set_delete - : generic_set_add; + const char *) = strmatch(argv[0]->text, "no") + ? generic_set_delete + : generic_set_add; return func(vty, VTY_GET_CONTEXT(route_map_index), "ip next-hop", "peer-address"); @@ -3537,9 +3536,9 @@ DEFUN (set_ip_nexthop_unchanged, "Don't modify existing Next hop address\n") { int (*func)(struct vty *, struct route_map_index *, const char *, - const char *) = strmatch(argv[0]->text, "no") - ? generic_set_delete - : generic_set_add; + const char *) = strmatch(argv[0]->text, "no") + ? generic_set_delete + : generic_set_add; return func(vty, VTY_GET_CONTEXT(route_map_index), "ip next-hop", "unchanged"); @@ -3780,7 +3779,8 @@ DEFUN (set_community, buffer_putstr(b, "no-export"); continue; } - if (strncmp(argv[i]->arg, "graceful-shutdown", strlen(argv[i]->arg)) + if (strncmp(argv[i]->arg, "graceful-shutdown", + strlen(argv[i]->arg)) == 0) { buffer_putstr(b, "graceful-shutdown"); continue; diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 4a8eeb9121..7ee641d6cf 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1540,7 +1540,8 @@ DEFUN (no_bgp_maxpaths, } ALIAS_HIDDEN(no_bgp_maxpaths, no_bgp_maxpaths_hidden_cmd, - "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM) "]", NO_STR + "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM) "]", + NO_STR "Forward packets over multiple paths\n" "Number of paths\n") @@ -1868,14 +1869,14 @@ static void bgp_redistribute_redo(struct bgp *bgp) struct listnode *node; struct bgp_redist *red; - for (afi = AFI_IP; afi < AFI_MAX; afi++) { - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { + for (afi = AFI_IP; afi < AFI_MAX; afi++) { + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { - red_list = bgp->redist[afi][i]; - if (!red_list) - continue; + red_list = bgp->redist[afi][i]; + if (!red_list) + continue; - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { bgp_redistribute_resend(bgp, afi, i, red->instance); } @@ -4363,23 +4364,23 @@ DEFUN (neighbor_attr_unchanged, SET_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED); SET_FLAG(flags, PEER_FLAG_MED_UNCHANGED); } else { - if (!CHECK_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED) && - peer_af_flag_check(peer, afi, safi, - PEER_FLAG_AS_PATH_UNCHANGED)) { + if (!CHECK_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED) + && peer_af_flag_check(peer, afi, safi, + PEER_FLAG_AS_PATH_UNCHANGED)) { peer_af_flag_unset_vty(vty, peer_str, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED); } - if (!CHECK_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED) && - peer_af_flag_check(peer, afi, safi, - PEER_FLAG_NEXTHOP_UNCHANGED)) { + if (!CHECK_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED) + && peer_af_flag_check(peer, afi, safi, + PEER_FLAG_NEXTHOP_UNCHANGED)) { peer_af_flag_unset_vty(vty, peer_str, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED); } - if (!CHECK_FLAG(flags, PEER_FLAG_MED_UNCHANGED) && - peer_af_flag_check(peer, afi, safi, - PEER_FLAG_MED_UNCHANGED)) { + if (!CHECK_FLAG(flags, PEER_FLAG_MED_UNCHANGED) + && peer_af_flag_check(peer, afi, safi, + PEER_FLAG_MED_UNCHANGED)) { peer_af_flag_unset_vty(vty, peer_str, afi, safi, PEER_FLAG_MED_UNCHANGED); } @@ -6125,8 +6126,8 @@ DEFUN_NOSH (address_family_ipv4_safi, if (argc == 3) { VTY_DECLVAR_CONTEXT(bgp, bgp); safi_t safi = bgp_vty_safi_from_str(argv[2]->text); - if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT && - safi != SAFI_UNICAST && safi != SAFI_MULTICAST + if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT + && safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN) { vty_out(vty, "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n"); @@ -6149,8 +6150,8 @@ DEFUN_NOSH (address_family_ipv6_safi, if (argc == 3) { VTY_DECLVAR_CONTEXT(bgp, bgp); safi_t safi = bgp_vty_safi_from_str(argv[2]->text); - if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT && - safi != SAFI_UNICAST && safi != SAFI_MULTICAST + if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT + && safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN) { vty_out(vty, "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n"); @@ -6511,8 +6512,8 @@ DEFUN (show_bgp_vrfs, if (!uj && count == 1) vty_out(vty, "%4s %-5s %-16s %9s %10s %-37s %-10s %-15s\n", - "Type", "Id", "routerId", "#PeersVfg", - "#PeersEstb", "Name", "L3-VNI", "Rmac"); + "Type", "Id", "routerId", "#PeersVfg", + "#PeersEstb", "Name", "L3-VNI", "Rmac"); peers_cfg = peers_estb = 0; if (uj) @@ -6537,8 +6538,9 @@ DEFUN (show_bgp_vrfs, if (uj) { - int64_t vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN) ? -1 : - (int64_t)bgp->vrf_id; + int64_t vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN) + ? -1 + : (int64_t)bgp->vrf_id; json_object_string_add(json_vrf, "type", type); json_object_int_add(json_vrf, "vrfId", vrf_id_ui); json_object_string_add(json_vrf, "routerId", @@ -6549,17 +6551,18 @@ DEFUN (show_bgp_vrfs, peers_estb); json_object_int_add(json_vrf, "l3vni", bgp->l3vni); - json_object_string_add(json_vrf, "rmac", - prefix_mac2str(&bgp->rmac, buf, - sizeof(buf))); + json_object_string_add( + json_vrf, "rmac", + prefix_mac2str(&bgp->rmac, buf, sizeof(buf))); json_object_object_add(json_vrfs, name, json_vrf); } else vty_out(vty, "%4s %-5d %-16s %9u %10u %-37s %-10u %-15s\n", - type, bgp->vrf_id == VRF_UNKNOWN ? - -1 : (int)bgp->vrf_id, - inet_ntoa(bgp->router_id), - peers_cfg, peers_estb, name, bgp->l3vni, + type, + bgp->vrf_id == VRF_UNKNOWN ? -1 + : (int)bgp->vrf_id, + inet_ntoa(bgp->router_id), peers_cfg, + peers_estb, name, bgp->l3vni, prefix_mac2str(&bgp->rmac, buf, sizeof(buf))); } @@ -6568,8 +6571,9 @@ DEFUN (show_bgp_vrfs, json_object_int_add(json, "totalVrfs", count); - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } else { if (count) @@ -6718,17 +6722,20 @@ DEFUN (show_bgp_memory, /* Other attributes */ if ((count = community_count())) vty_out(vty, "%ld BGP community entries, using %s of memory\n", - count, mtype_memstr(memstrbuf, sizeof(memstrbuf), - count * sizeof(struct community))); + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(struct community))); if ((count = mtype_stats_alloc(MTYPE_ECOMMUNITY))) vty_out(vty, "%ld BGP community entries, using %s of memory\n", - count, mtype_memstr(memstrbuf, sizeof(memstrbuf), - count * sizeof(struct ecommunity))); + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(struct ecommunity))); if ((count = mtype_stats_alloc(MTYPE_LCOMMUNITY))) vty_out(vty, "%ld BGP large-community entries, using %s of memory\n", - count, mtype_memstr(memstrbuf, sizeof(memstrbuf), - count * sizeof(struct lcommunity))); + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(struct lcommunity))); if ((count = mtype_stats_alloc(MTYPE_CLUSTER))) vty_out(vty, "%ld Cluster lists, using %s of memory\n", count, @@ -6757,8 +6764,9 @@ DEFUN (show_bgp_memory, count * sizeof(struct hash_backet))); if ((count = mtype_stats_alloc(MTYPE_BGP_REGEXP))) vty_out(vty, "%ld compiled regexes, using %s of memory\n", - count, mtype_memstr(memstrbuf, sizeof(memstrbuf), - count * sizeof(regex_t))); + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(regex_t))); return CMD_SUCCESS; } @@ -6773,27 +6781,21 @@ static void bgp_show_bestpath_json(struct bgp *bgp, json_object *json) json_object_string_add(bestpath, "asPath", "confed"); if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) { - if (bgp_flag_check(bgp, - BGP_FLAG_MULTIPATH_RELAX_AS_SET)) - json_object_string_add(bestpath, - "multiPathRelax", + if (bgp_flag_check(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET)) + json_object_string_add(bestpath, "multiPathRelax", "as-set"); else - json_object_string_add(bestpath, - "multiPathRelax", + json_object_string_add(bestpath, "multiPathRelax", "true"); } else - json_object_string_add(bestpath, - "multiPathRelax", - "false"); + json_object_string_add(bestpath, "multiPathRelax", "false"); if (bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID)) json_object_string_add(bestpath, "compareRouterId", "true"); if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED) || bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST)) { if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED)) - json_object_string_add(bestpath, "med", - "confed"); + json_object_string_add(bestpath, "med", "confed"); if (bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST)) json_object_string_add(bestpath, "med", "missing-as-worst"); @@ -6884,9 +6886,9 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, char memstrbuf[MTYPE_MEMSTR_LEN]; int64_t vrf_id_ui; - vrf_id_ui = - (bgp->vrf_id == VRF_UNKNOWN) ? -1 : - (int64_t)bgp->vrf_id; + vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN) + ? -1 + : (int64_t)bgp->vrf_id; /* Usage summary and header */ if (use_json) { @@ -6905,8 +6907,9 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, vty_out(vty, "BGP router identifier %s, local AS number %u vrf-id %d", inet_ntoa(bgp->router_id), bgp->as, - bgp->vrf_id == VRF_UNKNOWN ? -1 : - (int)bgp->vrf_id); + bgp->vrf_id == VRF_UNKNOWN + ? -1 + : (int)bgp->vrf_id); vty_out(vty, "\n"); } @@ -7015,8 +7018,9 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, json, "peerGroupCount", ents); json_object_int_add( json, "peerGroupMemory", - ents * sizeof(struct - peer_group)); + ents + * sizeof(struct + peer_group)); } if (CHECK_FLAG(bgp->af_flags[afi][safi], @@ -7039,10 +7043,11 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, vty_out(vty, "RIB entries %ld, using %s of memory\n", ents, - mtype_memstr(memstrbuf, - sizeof(memstrbuf), - ents * sizeof(struct - bgp_node))); + mtype_memstr( + memstrbuf, sizeof(memstrbuf), + ents + * sizeof(struct + bgp_node))); /* Peer related usage */ ents = listcount(bgp->peer); @@ -7059,8 +7064,9 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, mtype_memstr( memstrbuf, sizeof(memstrbuf), - ents * sizeof(struct - peer_group))); + ents + * sizeof(struct + peer_group))); if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) @@ -7165,7 +7171,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, if (peer->status == Established) if (peer->afc_recv[afi][pfx_rcd_safi]) vty_out(vty, " %12ld", - peer->pcount[afi][pfx_rcd_safi]); + peer->pcount[afi] + [pfx_rcd_safi]); else vty_out(vty, " NoNeg"); else { @@ -7192,8 +7199,9 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, bgp_show_bestpath_json(bgp, json); - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } else { if (count) @@ -7829,8 +7837,9 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, paf = peer_af_find(p, afi, safi); if (paf && PAF_SUBGRP(paf)) { - vty_out(vty, " Update group %" PRIu64 - ", subgroup %" PRIu64 "\n", + vty_out(vty, + " Update group %" PRIu64 ", subgroup %" PRIu64 + "\n", PAF_UPDGRP(paf)->id, PAF_SUBGRP(paf)->id); vty_out(vty, " Packet Queue length %d\n", bpacket_queue_virtual_length(paf)); @@ -8300,7 +8309,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json, epoch_tbuf = time(NULL) - uptime; #if CONFDATE > 20200101 - CPP_NOTICE("bgpTimerUp should be deprecated and can be removed now"); + CPP_NOTICE( + "bgpTimerUp should be deprecated and can be removed now"); #endif /* * bgpTimerUp was miliseconds that was accurate @@ -8376,8 +8386,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json, "bgpTimerConfiguredKeepAliveIntervalMsecs", p->keepalive * 1000); } else if ((bgp->default_holdtime != BGP_DEFAULT_HOLDTIME) - || (bgp->default_keepalive != - BGP_DEFAULT_KEEPALIVE)) { + || (bgp->default_keepalive + != BGP_DEFAULT_KEEPALIVE)) { json_object_int_add(json_neigh, "bgpTimerConfiguredHoldTimeMsecs", bgp->default_holdtime); @@ -8437,8 +8447,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json, vty_out(vty, ", keepalive interval is %d seconds\n", p->keepalive); } else if ((bgp->default_holdtime != BGP_DEFAULT_HOLDTIME) - || (bgp->default_keepalive != - BGP_DEFAULT_KEEPALIVE)) { + || (bgp->default_keepalive + != BGP_DEFAULT_KEEPALIVE)) { vty_out(vty, " Configured hold time is %d", bgp->default_holdtime); vty_out(vty, ", keepalive interval is %d seconds\n", @@ -9629,8 +9639,9 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json, } else vty_out(vty, " Reduce the no. of prefix from %s, will restart in %ld seconds\n", - p->host, thread_timer_remain_second( - p->t_pmax_restart)); + p->host, + thread_timer_remain_second( + p->t_pmax_restart)); } else { if (use_json) json_object_boolean_true_add( @@ -9874,8 +9885,9 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp, } if (use_json) { - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } else { vty_out(vty, "\n"); @@ -9910,7 +9922,8 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty, json_object_int_add(json, "vrfId", (bgp->vrf_id == VRF_UNKNOWN) - ? -1 : (int64_t) bgp->vrf_id); + ? -1 + : (int64_t)bgp->vrf_id); json_object_string_add( json, "vrfName", (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) @@ -10645,7 +10658,8 @@ DEFUN (show_ip_bgp_peer_groups, vrf = pg = NULL; int idx = 0; - vrf = argv_find(argv, argc, "VIEWVRFNAME", &idx) ? argv[idx]->arg : NULL; + vrf = argv_find(argv, argc, "VIEWVRFNAME", &idx) ? argv[idx]->arg + : NULL; pg = argv_find(argv, argc, "PGNAME", &idx) ? argv[idx]->arg : NULL; return bgp_show_peer_group_vty(vty, vrf, pg); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index e0bd74a206..b7529c55c1 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -570,8 +570,8 @@ static int zebra_read_route(int command, struct zclient *zclient, /* Now perform the add/update. */ bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex, - nhtype, api.metric, api.type, - api.instance, api.tag); + nhtype, api.metric, api.type, api.instance, + api.tag); } else { bgp_redistribute_delete(bgp, &api.prefix, api.type, api.instance); @@ -1142,8 +1142,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; } - if (mpinfo->extra && - bgp_is_valid_label(&mpinfo->extra->label[0]) + if (mpinfo->extra + && bgp_is_valid_label(&mpinfo->extra->label[0]) && !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) { has_valid_label = 1; label = label_pton(&mpinfo->extra->label[0]); @@ -1155,8 +1155,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, } /* if this is a evpn route we don't have to include the label */ - if (has_valid_label && - !(CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE))) + if (has_valid_label && !(CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE))) SET_FLAG(api.message, ZAPI_MESSAGE_LABEL); if (info->sub_type != BGP_ROUTE_AGGREGATE) @@ -1198,8 +1197,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, sizeof(nh_buf)); label_buf[0] = '\0'; - if (has_valid_label && - !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) + if (has_valid_label + && !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) sprintf(label_buf, "label %u", api_nh->labels[0]); zlog_debug(" nhop [%d]: %s %s", i + 1, nh_buf, @@ -1579,8 +1578,7 @@ void bgp_zebra_instance_register(struct bgp *bgp) /* For default instance, register to learn about VNIs, if appropriate. */ - if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT - && is_evpn_enabled()) + if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT && is_evpn_enabled()) bgp_zebra_advertise_all_vni(bgp, 1); } @@ -1598,8 +1596,7 @@ void bgp_zebra_instance_deregister(struct bgp *bgp) /* For default instance, unregister learning about VNIs, if appropriate. */ - if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT - && is_evpn_enabled()) + if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT && is_evpn_enabled()) bgp_zebra_advertise_all_vni(bgp, 0); /* Deregister for router-id, interfaces, redistributed routes. */ @@ -1749,8 +1746,7 @@ static int bgp_zebra_process_local_l3vni(int cmd, struct zclient *zclient, if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Rx L3-VNI %s VRF %s VNI %u RMAC %s", (cmd == ZEBRA_L3VNI_ADD) ? "add" : "del", - vrf_id_to_name(vrf_id), - l3vni, + vrf_id_to_name(vrf_id), l3vni, prefix_mac2str(&rmac, buf, sizeof(buf))); if (cmd == ZEBRA_L3VNI_ADD) @@ -1767,7 +1763,7 @@ static int bgp_zebra_process_local_vni(int command, struct zclient *zclient, struct stream *s; vni_t vni; struct bgp *bgp; - struct in_addr vtep_ip = { INADDR_ANY }; + struct in_addr vtep_ip = {INADDR_ANY}; vrf_id_t tenant_vrf_id = VRF_DEFAULT; s = zclient->ibuf; @@ -1784,8 +1780,8 @@ static int bgp_zebra_process_local_vni(int command, struct zclient *zclient, if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Rx VNI %s VRF %s VNI %u tenant-vrf %s", (command == ZEBRA_VNI_ADD) ? "add" : "del", - vrf_id_to_name(vrf_id), - vni, vrf_id_to_name(tenant_vrf_id)); + vrf_id_to_name(vrf_id), vni, + vrf_id_to_name(tenant_vrf_id)); if (command == ZEBRA_VNI_ADD) return bgp_evpn_local_vni_add( @@ -1844,8 +1840,7 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient, return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip); } -static void bgp_zebra_process_local_ip_prefix(int cmd, - struct zclient *zclient, +static void bgp_zebra_process_local_ip_prefix(int cmd, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { @@ -1871,25 +1866,19 @@ static void bgp_zebra_process_local_ip_prefix(int cmd, if (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) { if (p.family == AF_INET) - return bgp_evpn_advertise_type5_route(bgp_vrf, &p, - NULL, - AFI_IP, - SAFI_UNICAST); + return bgp_evpn_advertise_type5_route( + bgp_vrf, &p, NULL, AFI_IP, SAFI_UNICAST); else - return bgp_evpn_advertise_type5_route(bgp_vrf, &p, - NULL, - AFI_IP6, - SAFI_UNICAST); + return bgp_evpn_advertise_type5_route( + bgp_vrf, &p, NULL, AFI_IP6, SAFI_UNICAST); } else { if (p.family == AF_INET) - return bgp_evpn_withdraw_type5_route(bgp_vrf, &p, - AFI_IP, - SAFI_UNICAST); + return bgp_evpn_withdraw_type5_route( + bgp_vrf, &p, AFI_IP, SAFI_UNICAST); else - return bgp_evpn_withdraw_type5_route(bgp_vrf, &p, - AFI_IP6, - SAFI_UNICAST); + return bgp_evpn_withdraw_type5_route( + bgp_vrf, &p, AFI_IP6, SAFI_UNICAST); } } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 4ff0ef41e0..78e748fb6c 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1403,16 +1403,12 @@ static void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi, if (rn->info != NULL) { /* Special handling for 2-level routing * tables. */ - if (safi == SAFI_MPLS_VPN - || safi == SAFI_ENCAP + if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) { - for (nrn = bgp_table_top(( - struct bgp_table - *)(rn->info)); - nrn; - nrn = bgp_route_next(nrn)) - bgp_process(bgp, nrn, - afi, safi); + for (nrn = bgp_table_top( + (struct bgp_table *)(rn->info)); + nrn; nrn = bgp_route_next(nrn)) + bgp_process(bgp, nrn, afi, safi); } else bgp_process(bgp, rn, afi, safi); } @@ -1864,8 +1860,7 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) peer->afc[afi][safi] = 1; if (peer->group) - peer_group2peer_config_copy_af(peer->group, peer, - afi, safi); + peer_group2peer_config_copy_af(peer->group, peer, afi, safi); if (!active && peer_active(peer)) { bgp_timer_set(peer); @@ -1933,12 +1928,14 @@ int peer_activate(struct peer *peer, afi_t afi, safi_t safi) ret |= peer_activate_af(peer, afi, safi); } - /* If this is the first peer to be activated for this afi/labeled-unicast - * recalc bestpaths to trigger label allocation */ - if (safi == SAFI_LABELED_UNICAST && !bgp->allocate_mpls_labels[afi][SAFI_UNICAST]) { + /* If this is the first peer to be activated for this + * afi/labeled-unicast recalc bestpaths to trigger label allocation */ + if (safi == SAFI_LABELED_UNICAST + && !bgp->allocate_mpls_labels[afi][SAFI_UNICAST]) { if (BGP_DEBUG(zebra, ZEBRA)) - zlog_info("peer(s) are now active for labeled-unicast, allocate MPLS labels"); + zlog_info( + "peer(s) are now active for labeled-unicast, allocate MPLS labels"); bgp->allocate_mpls_labels[afi][SAFI_UNICAST] = 1; bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST); @@ -2027,14 +2024,15 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi) bgp = peer->bgp; - /* If this is the last peer to be deactivated for this afi/labeled-unicast - * recalc bestpaths to trigger label deallocation */ - if (safi == SAFI_LABELED_UNICAST && - bgp->allocate_mpls_labels[afi][SAFI_UNICAST] && - !bgp_afi_safi_peer_exists(bgp, afi, safi)) { + /* If this is the last peer to be deactivated for this + * afi/labeled-unicast recalc bestpaths to trigger label deallocation */ + if (safi == SAFI_LABELED_UNICAST + && bgp->allocate_mpls_labels[afi][SAFI_UNICAST] + && !bgp_afi_safi_peer_exists(bgp, afi, safi)) { if (BGP_DEBUG(zebra, ZEBRA)) - zlog_info("peer(s) are no longer active for labeled-unicast, deallocate MPLS labels"); + zlog_info( + "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels"); bgp->allocate_mpls_labels[afi][SAFI_UNICAST] = 0; bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST); @@ -2654,7 +2652,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer, } } else if (peer->afc[afi][safi]) peer_deactivate(peer, afi, safi); - } + } if (peer->group) { assert(group && peer->group == group); @@ -2856,8 +2854,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_domainname_get()); bgp->peer = list_new(); bgp->peer->cmp = (int (*)(void *, void *))peer_cmp; - bgp->peerhash = hash_create(peer_hash_key_make, - peer_hash_same, + bgp->peerhash = hash_create(peer_hash_key_make, peer_hash_same, "BGP Peer Hash"); bgp->peerhash->max_size = BGP_PEER_MAX_HASH_SIZE; @@ -3988,8 +3985,9 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi, } /* Track if addpath TX is in use */ - if (flag & (PEER_FLAG_ADDPATH_TX_ALL_PATHS - | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) { + if (flag + & (PEER_FLAG_ADDPATH_TX_ALL_PATHS + | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) { bgp = peer->bgp; addpath_tx_used = 0; @@ -6802,8 +6800,9 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, } else { if (!peer_af_flag_check(peer, afi, safi, PEER_FLAG_SEND_COMMUNITY) - && (!g_peer || peer_af_flag_check(g_peer, afi, safi, - PEER_FLAG_SEND_COMMUNITY)) + && (!g_peer + || peer_af_flag_check(g_peer, afi, safi, + PEER_FLAG_SEND_COMMUNITY)) && !peer_af_flag_check(peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY) && (!g_peer @@ -6811,9 +6810,10 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, PEER_FLAG_SEND_EXT_COMMUNITY)) && !peer_af_flag_check(peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY) - && (!g_peer || peer_af_flag_check( - g_peer, afi, safi, - PEER_FLAG_SEND_LARGE_COMMUNITY))) { + && (!g_peer + || peer_af_flag_check( + g_peer, afi, safi, + PEER_FLAG_SEND_LARGE_COMMUNITY))) { vty_out(vty, " no neighbor %s send-community all\n", addr); } else { @@ -6841,9 +6841,10 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, if (!peer_af_flag_check(peer, afi, safi, PEER_FLAG_SEND_COMMUNITY) - && (!g_peer || peer_af_flag_check( - g_peer, afi, safi, - PEER_FLAG_SEND_COMMUNITY))) { + && (!g_peer + || peer_af_flag_check( + g_peer, afi, safi, + PEER_FLAG_SEND_COMMUNITY))) { vty_out(vty, " no neighbor %s send-community\n", addr); @@ -6954,17 +6955,17 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, bgp_config_write_filter(vty, peer, afi, safi); /* atribute-unchanged. */ - if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED) || - peer_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED) || - peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) { + if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED) + || peer_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED) + || peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) { - if (!peer_group_active(peer) || - peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_AS_PATH_UNCHANGED) || - peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_NEXTHOP_UNCHANGED) || - peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_MED_UNCHANGED)) { + if (!peer_group_active(peer) + || peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_AS_PATH_UNCHANGED) + || peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_NEXTHOP_UNCHANGED) + || peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_MED_UNCHANGED)) { vty_out(vty, " neighbor %s attribute-unchanged%s%s%s\n", diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index c4ac4b0adb..747515a870 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -262,13 +262,14 @@ struct bgp { /* $FRR indent$ */ /* clang-format off */ #define BGP_MAXMED_ADMIN_UNCONFIGURED 0 /* Off by default */ - u_int32_t - maxmed_admin_value; /* Max-med value when administrative in on + u_int32_t maxmed_admin_value; /* Max-med value when administrative in on */ + /* $FRR indent$ */ + /* clang-format off */ #define BGP_MAXMED_VALUE_DEFAULT 4294967294 /* Maximum by default */ - u_char maxmed_active; /* 1/0 if max-med is active or not */ - u_int32_t maxmed_value; /* Max-med value when its active */ + u_char maxmed_active; /* 1/0 if max-med is active or not */ + u_int32_t maxmed_value; /* Max-med value when its active */ /* BGP update delay on startup */ struct thread *t_update_delay; @@ -828,8 +829,8 @@ struct peer { #define PEER_CONFIG_ROUTEADV (1 << 2) /* route advertise */ #define PEER_GROUP_CONFIG_TIMER (1 << 3) /* timers from peer-group */ -#define PEER_OR_GROUP_TIMER_SET(peer) \ - (CHECK_FLAG(peer->config, PEER_CONFIG_TIMER) \ +#define PEER_OR_GROUP_TIMER_SET(peer) \ + (CHECK_FLAG(peer->config, PEER_CONFIG_TIMER) \ || CHECK_FLAG(peer->config, PEER_GROUP_CONFIG_TIMER)) _Atomic uint32_t holdtime; @@ -869,25 +870,33 @@ struct peer { /* workqueues */ struct work_queue *clear_node_queue; -#define PEER_TOTAL_RX(peer) \ - atomic_load_explicit(&peer->open_in, memory_order_relaxed) + \ - atomic_load_explicit(&peer->update_in, memory_order_relaxed) + \ - atomic_load_explicit(&peer->notify_in, memory_order_relaxed) + \ - atomic_load_explicit(&peer->refresh_in, memory_order_relaxed) + \ - atomic_load_explicit(&peer->keepalive_in, memory_order_relaxed) + \ - atomic_load_explicit(&peer->dynamic_cap_in, memory_order_relaxed) +#define PEER_TOTAL_RX(peer) \ + atomic_load_explicit(&peer->open_in, memory_order_relaxed) \ + + atomic_load_explicit(&peer->update_in, memory_order_relaxed) \ + + atomic_load_explicit(&peer->notify_in, memory_order_relaxed) \ + + atomic_load_explicit(&peer->refresh_in, \ + memory_order_relaxed) \ + + atomic_load_explicit(&peer->keepalive_in, \ + memory_order_relaxed) \ + + atomic_load_explicit(&peer->dynamic_cap_in, \ + memory_order_relaxed) -#define PEER_TOTAL_TX(peer) \ - atomic_load_explicit(&peer->open_out, memory_order_relaxed) + \ - atomic_load_explicit(&peer->update_out, memory_order_relaxed) + \ - atomic_load_explicit(&peer->notify_out, memory_order_relaxed) + \ - atomic_load_explicit(&peer->refresh_out, memory_order_relaxed) + \ - atomic_load_explicit(&peer->keepalive_out, memory_order_relaxed) + \ - atomic_load_explicit(&peer->dynamic_cap_out, memory_order_relaxed) +#define PEER_TOTAL_TX(peer) \ + atomic_load_explicit(&peer->open_out, memory_order_relaxed) \ + + atomic_load_explicit(&peer->update_out, \ + memory_order_relaxed) \ + + atomic_load_explicit(&peer->notify_out, \ + memory_order_relaxed) \ + + atomic_load_explicit(&peer->refresh_out, \ + memory_order_relaxed) \ + + atomic_load_explicit(&peer->keepalive_out, \ + memory_order_relaxed) \ + + atomic_load_explicit(&peer->dynamic_cap_out, \ + memory_order_relaxed) /* Statistics field */ - _Atomic uint32_t open_in; /* Open message input count */ - _Atomic uint32_t open_out; /* Open message output count */ + _Atomic uint32_t open_in; /* Open message input count */ + _Atomic uint32_t open_out; /* Open message output count */ _Atomic uint32_t update_in; /* Update message input count */ _Atomic uint32_t update_out; /* Update message ouput count */ _Atomic time_t update_time; /* Update message received time. */ @@ -898,7 +907,7 @@ struct peer { _Atomic uint32_t refresh_in; /* Route Refresh input count */ _Atomic uint32_t refresh_out; /* Route Refresh output count */ _Atomic uint32_t dynamic_cap_in; /* Dynamic Capability input count. */ - _Atomic uint32_t dynamic_cap_out; /* Dynamic Capability output count. */ + _Atomic uint32_t dynamic_cap_out; /* Dynamic Capability output count. */ /* BGP state count */ u_int32_t established; /* Established */ @@ -1480,7 +1489,8 @@ extern int peer_cmp(struct peer *p1, struct peer *p2); extern int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, iana_safi_t pkt_safi, afi_t *afi, safi_t *safi); extern int bgp_map_afi_safi_int2iana(afi_t afi, safi_t safi, - iana_afi_t *pkt_afi, iana_safi_t *pkt_safi); + iana_afi_t *pkt_afi, + iana_safi_t *pkt_safi); extern struct peer_af *peer_af_create(struct peer *, afi_t, safi_t); extern struct peer_af *peer_af_find(struct peer *, afi_t, safi_t); diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index e3cb739464..1fbbac9fc1 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -260,20 +260,21 @@ int bgp_rfapi_is_vnc_configured(struct bgp *bgp) /*********************************************************************** * VNC Configuration/CLI ***********************************************************************/ -#define VNC_VTY_CONFIG_CHECK(bgp) \ - { \ - switch (bgp_rfapi_is_vnc_configured(bgp)) { \ - case EPERM: \ - vty_out(vty, "VNC operations only permitted on default BGP instance.\n"); \ - return CMD_WARNING_CONFIG_FAILED; \ - break; \ - case ENXIO: \ - vty_out(vty, "VNC not configured.\n"); \ - return CMD_WARNING_CONFIG_FAILED; \ - break; \ - default: \ - break; \ - } \ +#define VNC_VTY_CONFIG_CHECK(bgp) \ + { \ + switch (bgp_rfapi_is_vnc_configured(bgp)) { \ + case EPERM: \ + vty_out(vty, \ + "VNC operations only permitted on default BGP instance.\n"); \ + return CMD_WARNING_CONFIG_FAILED; \ + break; \ + case ENXIO: \ + vty_out(vty, "VNC not configured.\n"); \ + return CMD_WARNING_CONFIG_FAILED; \ + break; \ + default: \ + break; \ + } \ } DEFUN (vnc_advertise_un_method, @@ -509,9 +510,8 @@ DEFUN (vnc_defaults_responselifetime, } else { rspint = strtoul(argv[1]->arg, NULL, 10); if (rspint > INT32_MAX) - rspint = - INT32_MAX; /* is really an int, not an unsigned - int */ + rspint = INT32_MAX; /* is really an int, not an unsigned + int */ } bgp->rfapi_cfg->default_response_lifetime = rspint; @@ -1631,14 +1631,14 @@ DEFUN (vnc_nve_group_export_no_prefixlist, return CMD_WARNING_CONFIG_FAILED; } - if (argv[idx-1]->text[0] == 'z') + if (argv[idx - 1]->text[0] == 'z') is_bgp = 0; - idx += 2; /* skip afi and keyword */ + idx += 2; /* skip afi and keyword */ if (is_bgp) { - if (idx == argc || - strmatch(argv[idx]->arg, - rfg->plist_export_bgp_name[afi])) { + if (idx == argc + || strmatch(argv[idx]->arg, + rfg->plist_export_bgp_name[afi])) { if (rfg->plist_export_bgp_name[afi]) free(rfg->plist_export_bgp_name[afi]); rfg->plist_export_bgp_name[afi] = NULL; @@ -1647,9 +1647,9 @@ DEFUN (vnc_nve_group_export_no_prefixlist, vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi); } } else { - if (idx == argc || - strmatch(argv[idx]->arg, - rfg->plist_export_zebra_name[afi])) { + if (idx == argc + || strmatch(argv[idx]->arg, + rfg->plist_export_zebra_name[afi])) { if (rfg->plist_export_zebra_name[afi]) free(rfg->plist_export_zebra_name[afi]); rfg->plist_export_zebra_name[afi] = NULL; @@ -1700,7 +1700,7 @@ DEFUN (vnc_nve_group_export_prefixlist, return CMD_WARNING_CONFIG_FAILED; } - if (argv[idx-1]->text[0] == 'z') + if (argv[idx - 1]->text[0] == 'z') is_bgp = 0; idx = argc - 1; @@ -1758,18 +1758,19 @@ DEFUN (vnc_nve_group_export_no_routemap, switch (argv[idx]->text[0]) { case 'z': is_bgp = 0; - /* fall thru */ + /* fall thru */ case 'b': idx += 2; break; - default: /* route-map */ + default: /* route-map */ idx++; break; } if (is_bgp) { - if (idx == argc || - strmatch(argv[idx]->arg, rfg->routemap_export_bgp_name)) { + if (idx == argc + || strmatch(argv[idx]->arg, + rfg->routemap_export_bgp_name)) { if (rfg->routemap_export_bgp_name) free(rfg->routemap_export_bgp_name); rfg->routemap_export_bgp_name = NULL; @@ -1779,9 +1780,9 @@ DEFUN (vnc_nve_group_export_no_routemap, vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6); } } else { - if (idx == argc || - strmatch(argv[idx]->arg, - rfg->routemap_export_zebra_name)) { + if (idx == argc + || strmatch(argv[idx]->arg, + rfg->routemap_export_zebra_name)) { if (rfg->routemap_export_zebra_name) free(rfg->routemap_export_zebra_name); rfg->routemap_export_zebra_name = NULL; @@ -2466,8 +2467,7 @@ bgp_rfapi_delete_named_nve_group(struct vty *vty, /* NULL = no output */ if (rfg->rfd) clear_vnc_vrf_closer(rfg); bgp_rfapi_delete_nve_group(vty, bgp, rfg); - } - else /* must be delete all */ + } else /* must be delete all */ for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->nve_groups_sequential, node, nnode, rfg)) { if (rfg->rfd) @@ -3950,7 +3950,9 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) if (rfg->plist_export_bgp_name[afi]) { vty_out(vty, " export %s%s prefix-list %s\n", - (rfg->type == RFAPI_GROUP_CFG_VRF ? "" : "bgp "), + (rfg->type == RFAPI_GROUP_CFG_VRF + ? "" + : "bgp "), afistr, rfg->plist_export_bgp_name [afi]); @@ -3958,7 +3960,9 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) if (rfg->plist_export_zebra_name[afi]) { vty_out(vty, " export %s%s prefix-list %s\n", - (rfg->type == RFAPI_GROUP_CFG_VRF ? "" : "zebra "), + (rfg->type == RFAPI_GROUP_CFG_VRF + ? "" + : "zebra "), afistr, rfg->plist_export_zebra_name [afi]); @@ -3993,12 +3997,16 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) if (rfg->routemap_export_bgp_name) { vty_out(vty, " export %sroute-map %s\n", - (rfg->type == RFAPI_GROUP_CFG_VRF ? "" : "bgp "), + (rfg->type == RFAPI_GROUP_CFG_VRF + ? "" + : "bgp "), rfg->routemap_export_bgp_name); } if (rfg->routemap_export_zebra_name) { vty_out(vty, " export %sroute-map %s\n", - (rfg->type == RFAPI_GROUP_CFG_VRF ? "" : "zebra "), + (rfg->type == RFAPI_GROUP_CFG_VRF + ? "" + : "zebra "), rfg->routemap_export_zebra_name); } if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) { @@ -4098,7 +4106,8 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) } if (hc->default_rd.prefixlen - || hc->default_response_lifetime != BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT + || hc->default_response_lifetime + != BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT || hc->default_rt_import_list || hc->default_rt_export_list || hc->nve_groups_sequential->count) { @@ -4184,8 +4193,8 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) prefix2str(&rfg->vn_prefix, buf, sizeof(buf)); - vty_out(vty, " prefix %s %s\n", - "vn", buf); + vty_out(vty, " prefix %s %s\n", "vn", + buf); } if (rfg->un_prefix.family && rfg->un_node) { @@ -4193,8 +4202,8 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) prefix2str(&rfg->un_prefix, buf, sizeof(buf)); - vty_out(vty, " prefix %s %s\n", - "un", buf); + vty_out(vty, " prefix %s %s\n", "un", + buf); } @@ -4215,11 +4224,10 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) value); } else - vty_out(vty, - " rd %s\n", - prefix_rd2str(&rfg->rd, - buf, - sizeof(buf))); + vty_out(vty, " rd %s\n", + prefix_rd2str( + &rfg->rd, buf, + sizeof(buf))); } if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) { vty_out(vty, " response-lifetime "); From d316210b6580faa2462b1e5fb5020ef3b4f1d03c Mon Sep 17 00:00:00 2001 From: "G. Paul Ziemba" Date: Fri, 9 Feb 2018 13:14:22 -0800 Subject: [PATCH 27/45] whitespace/comment fixes per qlyoung Signed-off-by: G. Paul Ziemba --- bgpd/bgp_route.c | 6 +++--- bgpd/bgpd.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 2a555aae32..046c59aa54 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -9565,9 +9565,9 @@ static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi, pcounts.table = peer->bgp->rib[afi][safi]; /* in-place call via thread subsystem so as to record execution time - * * stats for the thread-walk (i.e. ensure this can't be blamed on - * * on just vty_read()). - * */ + * stats for the thread-walk (i.e. ensure this can't be blamed on + * on just vty_read()). + */ thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0); if (use_json) { diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 747515a870..51709f9ed0 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -895,8 +895,8 @@ struct peer { memory_order_relaxed) /* Statistics field */ - _Atomic uint32_t open_in; /* Open message input count */ - _Atomic uint32_t open_out; /* Open message output count */ + _Atomic uint32_t open_in; /* Open message input count */ + _Atomic uint32_t open_out; /* Open message output count */ _Atomic uint32_t update_in; /* Update message input count */ _Atomic uint32_t update_out; /* Update message ouput count */ _Atomic time_t update_time; /* Update message received time. */ From 1f2129ecd39bf3b1ae16bfb82f82131ef6ec9511 Mon Sep 17 00:00:00 2001 From: mitesh Date: Fri, 9 Feb 2018 16:57:37 -0800 Subject: [PATCH 28/45] zebra: fix build breakage is_vni_l3 was removed as a part of PR1700. However, it seems to be used in master. Causing the breakage. Made the changes to not use the API anymore. Signed-off-by: Mitesh Kanjariya --- zebra/zebra_vxlan.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index a0d7fd3cb6..c9cc556a44 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -4576,6 +4576,8 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, { json_object *json = NULL; void *args[2]; + zebra_l3vni_t *zl3vni = NULL; + zebra_vni_t *zvni = NULL; if (!is_evpn_enabled()) return; @@ -4585,22 +4587,10 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, args[0] = vty; args[1] = json; - if (is_vni_l3(vni)) { - zebra_l3vni_t *zl3vni = NULL; - - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - if (use_json) - vty_out(vty, "{}\n"); - else - vty_out(vty, "%% VNI %u does not exist\n", vni); - return; - } - + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { zl3vni_print(zl3vni, (void *)args); } else { - zebra_vni_t *zvni; - zvni = zvni_lookup(vni); if (!zvni) { if (use_json) From f89a449b5f109668bfcbc823db855244dfa7e170 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Sun, 11 Feb 2018 20:17:11 -0800 Subject: [PATCH 29/45] ospf6d: Fix distance command Reset prevoiusly configured distance command options if user enters new (different) parameters. Ticket:CM-19635 Reviewed By: Testing Done: R1(config-ospf6)# distance ospf6 intra-area 55 external 55 R1#show running-config ospf6d router ospf6 distance ospf6 intra-area 55 external 55 R1(config-ospf6)# distance ospf6 inter-area 55 R1#show running-config ospf6d router ospf6 distance ospf6 inter-area 55 Signed-off-by: Chirag Shah --- ospf6d/ospf6_top.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 749873bcf8..450be5d448 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -521,6 +521,10 @@ DEFUN (ospf6_distance_ospf6, VTY_DECLVAR_CONTEXT(ospf6, o); int idx = 0; + o->distance_intra = 0; + o->distance_inter = 0; + o->distance_external = 0; + if (argv_find(argv, argc, "intra-area", &idx)) o->distance_intra = atoi(argv[idx + 1]->arg); idx = 0; From 926b88f00d0391d1356753fcbdb1983bff2ef79d Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Sun, 11 Feb 2018 20:27:43 -0800 Subject: [PATCH 30/45] ospfd: Fix distance command Reset prevoiusly configured distance command options if user enters new (different) parameters. Ticket:CM-19635 Testing Done: R1(config-router)# distance ospf intra-area 45 external 45 R1# show running-config ospfd router ospf distance ospf intra-area 45 external 45 R1(config-router)# distance ospf inter-area 45 R1# show running-config ospfd router ospf distance ospf inter-area 45 Signed-off-by: Chirag Shah --- ospfd/ospf_vty.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 1276f5477c..09350b45a8 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -8558,6 +8558,10 @@ DEFUN (ospf_distance_ospf, VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); int idx = 0; + ospf->distance_intra = 0; + ospf->distance_inter = 0; + ospf->distance_external = 0; + if (argv_find(argv, argc, "intra-area", &idx)) ospf->distance_intra = atoi(argv[idx + 1]->arg); idx = 0; From 53c84f7800eebf1406ff9c5eb749900e4b425082 Mon Sep 17 00:00:00 2001 From: Mitesh Kanjariya Date: Fri, 9 Feb 2018 01:09:20 -0800 Subject: [PATCH 31/45] bgpd: Policy to control which RIB routes are injected into EVPN FRR/CL provides the means for injecting regular (IPv4) routes from the BGP RIB into EVPN as type-5 routes. This needs to be enhanced to allow selective injection. This can be achieved by adding a route-map option for the "advertise ipv4/ipv6 unicast" command. Signed-off-by: Mitesh Kanjariya --- bgpd/bgp_evpn.c | 13 +++++++++ bgpd/bgp_evpn_vty.c | 70 ++++++++++++++++++++++++++++++++++++--------- bgpd/bgp_routemap.c | 13 +++++++++ bgpd/bgpd.h | 3 ++ 4 files changed, 86 insertions(+), 13 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index c7d5f8d111..ec8e2907a6 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -3275,6 +3275,19 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, */ for (ri = rn->info; ri; ri = ri->next) { if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) { + + /* apply the route-map */ + if (bgp_vrf->adv_cmd_rmap[afi][safi].map) { + int ret = 0; + + ret = + route_map_apply( + bgp_vrf->adv_cmd_rmap[afi][safi].map, + &rn->p, RMAP_BGP, ri); + if (ret == RMAP_DENYMATCH) + continue; + } + bgp_evpn_advertise_type5_route(bgp_vrf, &rn->p, ri->attr, afi, safi); diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index bd42ccdecf..e1e11e44ac 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -2723,19 +2723,34 @@ DEFUN (no_bgp_evpn_advertise_vni_subnet, DEFUN (bgp_evpn_advertise_type5, bgp_evpn_advertise_type5_cmd, - "advertise " BGP_AFI_CMD_STR "" BGP_SAFI_CMD_STR, + "advertise " BGP_AFI_CMD_STR "" BGP_SAFI_CMD_STR " [route-map WORD]", "Advertise prefix routes\n" BGP_AFI_HELP_STR - BGP_SAFI_HELP_STR) + BGP_SAFI_HELP_STR + "route-map for filtering specific routes\n" + "Name of the route map\n") { struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp); /* bgp vrf instance */ int idx_afi = 0; int idx_safi = 0; + int idx_rmap = 0; afi_t afi = 0; safi_t safi = 0; + int ret = 0; + int rmap_changed = 0; argv_find_and_parse_afi(argv, argc, &idx_afi, &afi); argv_find_and_parse_safi(argv, argc, &idx_safi, &safi); + ret = argv_find(argv, argc, "route-map", &idx_rmap); + if (ret) { + if (!bgp_vrf->adv_cmd_rmap[afi][safi].name) + rmap_changed = 1; + else if (strcmp(argv[idx_rmap + 1]->arg, + bgp_vrf->adv_cmd_rmap[afi][safi].name) != 0) + rmap_changed = 1; + } else if (bgp_vrf->adv_cmd_rmap[afi][safi].name) { + rmap_changed = 1; + } if (!(afi == AFI_IP) || (afi == AFI_IP6)) { vty_out(vty, @@ -2754,24 +2769,44 @@ DEFUN (bgp_evpn_advertise_type5, /* if we are already advertising ipv4 prefix as type-5 * nothing to do */ - if (!CHECK_FLAG(bgp_vrf->vrf_flags, - BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) { - SET_FLAG(bgp_vrf->vrf_flags, - BGP_VRF_ADVERTISE_IPV4_IN_EVPN); - bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi); - } + if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags, + BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) + return CMD_WARNING; + SET_FLAG(bgp_vrf->vrf_flags, + BGP_VRF_ADVERTISE_IPV4_IN_EVPN); } else { /* if we are already advertising ipv6 prefix as type-5 * nothing to do */ - if (!CHECK_FLAG(bgp_vrf->vrf_flags, - BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) { - SET_FLAG(bgp_vrf->vrf_flags, - BGP_VRF_ADVERTISE_IPV6_IN_EVPN); - bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi); + if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags, + BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) + return CMD_WARNING; + SET_FLAG(bgp_vrf->vrf_flags, + BGP_VRF_ADVERTISE_IPV6_IN_EVPN); + } + + if (rmap_changed) { + bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi); + if (bgp_vrf->adv_cmd_rmap[afi][safi].name) { + XFREE(MTYPE_ROUTE_MAP_NAME, + bgp_vrf->adv_cmd_rmap[afi][safi].name); + bgp_vrf->adv_cmd_rmap[afi][safi].name = NULL; + bgp_vrf->adv_cmd_rmap[afi][safi].map = NULL; } } + + /* set the route-map for advertise command */ + if (ret && argv[idx_rmap + 1]->arg) { + bgp_vrf->adv_cmd_rmap[afi][safi].name = + XSTRDUP(MTYPE_ROUTE_MAP_NAME, + argv[idx_rmap + 1]->arg); + bgp_vrf->adv_cmd_rmap[afi][safi].map = + route_map_lookup_by_name(argv[idx_rmap + 1]->arg); + } + + /* advertise type-5 routes */ + bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi); return CMD_SUCCESS; } @@ -2827,6 +2862,15 @@ DEFUN (no_bgp_evpn_advertise_type5, BGP_VRF_ADVERTISE_IPV6_IN_EVPN); } } + + /* clear the route-map information for advertise ipv4/ipv6 unicast */ + if (bgp_vrf->adv_cmd_rmap[afi][safi].name) { + XFREE(MTYPE_ROUTE_MAP_NAME, + bgp_vrf->adv_cmd_rmap[afi][safi].name); + bgp_vrf->adv_cmd_rmap[afi][safi].name = NULL; + bgp_vrf->adv_cmd_rmap[afi][safi].map = NULL; + } + return CMD_SUCCESS; } diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 06e53e2daf..4d5624d3b0 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -3076,6 +3076,19 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name, } } } + + /* for type5 command route-maps */ + FOREACH_AFI_SAFI (afi, safi) { + if (bgp->adv_cmd_rmap[afi][safi].name && + strcmp(rmap_name, bgp->adv_cmd_rmap[afi][safi].name) == 0) { + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug( + "Processing route_map %s update on advertise type5 route command", + rmap_name); + bgp_evpn_withdraw_type5_routes(bgp, afi, safi); + bgp_evpn_advertise_type5_routes(bgp, afi, safi); + } + } } static int bgp_route_map_process_update_cb(char *rmap_name) diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 51709f9ed0..220b6d989e 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -452,6 +452,9 @@ struct bgp { /* list of corresponding l2vnis (struct bgpevpn) */ struct list *l2vnis; + /* route map for advertise ipv4/ipv6 unicast (type-5 routes) */ + struct bgp_rmap adv_cmd_rmap[AFI_MAX][SAFI_MAX]; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(bgp) From cf29dab3b545f4d8c2286599d2f74426f365911f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 13 Feb 2018 23:34:52 -0500 Subject: [PATCH 32/45] ospf6d: Fix a possible deref by null found in SA There exists a possibility that rtr_lsa may be null. Add an assert that shows we actually expect it to be non-null at this point in time going forward. Signed-off-by: Donald Sharp --- ospf6d/ospf6_spf.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 17ce1771e2..29ba1bcec7 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -1029,18 +1029,21 @@ struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area, /* Fill Larger LSA Payload */ end = ospf6_lsdb_head(lsdb, 2, type, adv_router, &rtr_lsa); - if (rtr_lsa) { - if (!OSPF6_LSA_IS_MAXAGE(rtr_lsa)) { - /* Append first Link State ID LSA */ - lsa_header = (struct ospf6_lsa_header *)rtr_lsa->header; - memcpy(new_header, lsa_header, - ntohs(lsa_header->length)); - /* Assign new lsa length as aggregated length. */ - ((struct ospf6_lsa_header *)new_header)->length = - htons(total_lsa_length); - new_header += ntohs(lsa_header->length); - num_lsa--; - } + + /* + * We assume at this point in time that rtr_lsa is + * a valid pointer. + */ + assert(rtr_lsa); + if (!OSPF6_LSA_IS_MAXAGE(rtr_lsa)) { + /* Append first Link State ID LSA */ + lsa_header = (struct ospf6_lsa_header *)rtr_lsa->header; + memcpy(new_header, lsa_header, ntohs(lsa_header->length)); + /* Assign new lsa length as aggregated length. */ + ((struct ospf6_lsa_header *)new_header)->length = + htons(total_lsa_length); + new_header += ntohs(lsa_header->length); + num_lsa--; } /* Print LSA Name */ From 9b50aa1fd3f38eb34d77b9ae7e848b35bc814bfc Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 13 Feb 2018 23:37:08 -0500 Subject: [PATCH 33/45] ospfd: Fix some new SA issues found by coverity Fix a || && mixup. Add an assert for area to show we expect it to be non-null going forward. When memory is allocated if it fails we abort then no need to check for null. Signed-off-by: Donald Sharp --- ospfd/ospf_ext.c | 2 +- ospfd/ospf_flood.c | 1 + ospfd/ospf_sr.c | 10 +--------- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c index d42476b6d8..d7faf4b0de 100644 --- a/ospfd/ospf_ext.c +++ b/ospfd/ospf_ext.c @@ -175,7 +175,7 @@ void ospf_ext_term(void) { if ((OspfEXT.scope != OSPF_OPAQUE_AREA_LSA) - || (OspfEXT.scope != OSPF_OPAQUE_AS_LSA)) + && (OspfEXT.scope != OSPF_OPAQUE_AS_LSA)) zlog_warn( "EXT: Unable to unregister Extended Prefix " "Opaque LSA functions: Wrong scope!"); diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 36b6d5143d..7ad9cf9f2f 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -563,6 +563,7 @@ int ospf_flood_through_area(struct ospf_area *area, struct ospf_neighbor *inbr, struct ospf_interface *oi; int lsa_ack_flag = 0; + assert(area); /* All other types are specific to a single area (Area A). The eligible interfaces are all those interfaces attaching to the Area A. If Area A is the backbone, this includes all the virtual diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index c6649a7a04..9827eac71b 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -149,14 +149,6 @@ static struct sr_node *sr_node_new(struct in_addr *rid) new->ext_link->del = del_sr_link; new->ext_prefix->del = del_sr_pref; - /* Check if list are correctly created */ - if (new->ext_link == NULL || new->ext_prefix == NULL) { - list_delete_original(new->ext_link); - list_delete_original(new->ext_prefix); - XFREE(MTYPE_OSPF_SR_PARAMS, new); - return NULL; - } - IPV4_ADDR_COPY(&new->adv_router, rid); new->neighbor = NULL; new->instance = 0; @@ -440,7 +432,7 @@ static struct ospf_path *get_nexthop_by_addr(struct ospf *top, struct route_node *rn; /* Sanity Check */ - if ((top == NULL) && (top->new_table)) + if (top == NULL) return NULL; if (IS_DEBUG_OSPF_SR) From 6447dbb3726089659be4c891be8b2db39031791a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 13 Feb 2018 23:39:09 -0500 Subject: [PATCH 34/45] zebra: Clean up some SA issues found by new code 1) Add asserts in a couple of spots to show we never expect prefix to be bad. 2) Fix some bfd code where out_ctxt will always be NULL. Signed-off-by: Donald Sharp --- zebra/zebra_ptm.c | 9 +++++++-- zebra/zebra_vty.c | 12 ++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 7f5fd472f1..187c2594ad 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -1007,8 +1007,13 @@ int zebra_ptm_bfd_client_register(struct zserv *client, return 0; stream_failure: - if (out_ctxt) - ptm_lib_cleanup_msg(ptm_hdl, out_ctxt); + /* + * IF we ever add more STREAM_GETXXX functions after the out_ctxt + * is allocated then we need to add this code back in + * + * if (out_ctxt) + * ptm_lib_cleanup_msg(ptm_hdl, out_ctxt); + */ return 0; } diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index f5ad9c1c8a..269244f768 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -458,6 +458,12 @@ DEFPY(ip_route_blackhole_vrf, VTY_DECLVAR_CONTEXT(vrf, vrf); struct zebra_vrf *zvrf = vrf->info; + /* + * Coverity is complaining that prefix could + * be dereferenced, but we know that prefix will + * valid. Add an assert to make it happy + */ + assert(prefix); return zebra_static_route_leak(vty, zvrf, zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, NULL, NULL, NULL, flag, @@ -2014,6 +2020,12 @@ DEFPY(ipv6_route_blackhole_vrf, VTY_DECLVAR_CONTEXT(vrf, vrf); struct zebra_vrf *zvrf = vrf->info; + /* + * Coverity is complaining that prefix could + * be dereferenced, but we know that prefix will + * valid. Add an assert to make it happy + */ + assert(prefix); return zebra_static_route_leak(vty, zvrf, zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, from_str, NULL, NULL, flag, From 7d061b3cb120c35c5b580bbbcfb1ec9602f58956 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 14 Feb 2018 01:11:09 -0500 Subject: [PATCH 35/45] lib, sharpd, zebra: Update the zapi_vrf_label call to add afi Add the ability to pass in an afi to zebra. zebra_vrf keeps track of the afi/label tuple and then does the right thing before we call down. AF_MPLS does not care about v4 or v6 it just knows label and what device to use for lookup. Signed-off-by: Donald Sharp --- lib/zclient.c | 3 ++- lib/zclient.h | 8 +++++++- sharpd/sharp_vty.c | 7 +++++-- sharpd/sharp_zebra.c | 4 ++-- sharpd/sharp_zebra.h | 2 +- zebra/zebra_vrf.h | 2 +- zebra/zserv.c | 12 ++++++++---- 7 files changed, 26 insertions(+), 12 deletions(-) diff --git a/lib/zclient.c b/lib/zclient.c index 8e8b50b15e..714888a3f3 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -363,7 +363,7 @@ static int zebra_hello_send(struct zclient *zclient) return 0; } -void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, +void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, afi_t afi, mpls_label_t label, enum lsp_types_t ltype) { struct stream *s; @@ -373,6 +373,7 @@ void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, zclient_create_header(s, ZEBRA_VRF_LABEL, vrf_id); stream_putl(s, label); + stream_putc(s, afi); stream_putc(s, ltype); stream_putw_at(s, 0, stream_get_endp(s)); zclient_send_message(zclient); diff --git a/lib/zclient.h b/lib/zclient.h index 344b45fb54..d8a70c6cf3 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -390,9 +390,15 @@ extern void redist_del_instance(struct redist_proto *, u_short); * label for lookup. If you pass in MPLS_LABEL_NONE * we will cause a delete action and remove this label pop * operation. + * + * The underlying AF_MPLS doesn't care about afi's + * but we can make the zebra_vrf keep track of what + * we have installed and play some special games + * to get them both installed. */ extern void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, - mpls_label_t label, enum lsp_types_t ltype); + afi_t afi, mpls_label_t label, + enum lsp_types_t ltype); extern void zclient_send_reg_requests(struct zclient *, vrf_id_t); extern void zclient_send_dereg_requests(struct zclient *, vrf_id_t); diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index 4f7d61b22f..0e7d1f2c29 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -80,14 +80,17 @@ DEFPY (install_routes, } DEFPY(vrf_label, vrf_label_cmd, - "sharp label vrf NAME$name label (0-100000)$label", + "sharp label vrf NAME$name label (0-100000)$label", "Sharp Routing Protocol\n" "Give a vrf a label\n" + "Pop and forward for IPv4\n" + "Pop and forward for IPv6\n" VRF_CMD_HELP_STR "The label to use, 0 specifies remove the label installed from previous\n" "Specified range to use\n") { struct vrf *vrf; + afi_t afi = (ipv4) ? AFI_IP : AFI_IP6; if (strcmp(name, "default") == 0) vrf = vrf_lookup_by_id(VRF_DEFAULT); @@ -102,7 +105,7 @@ DEFPY(vrf_label, vrf_label_cmd, if (label == 0) label = MPLS_LABEL_NONE; - vrf_label_add(vrf->vrf_id, label); + vrf_label_add(vrf->vrf_id, afi, label); return CMD_SUCCESS; } diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index f771e53f0c..78e8cf0adc 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -152,9 +152,9 @@ static void zebra_connected(struct zclient *zclient) zclient_send_reg_requests(zclient, VRF_DEFAULT); } -void vrf_label_add(vrf_id_t vrf_id, mpls_label_t label) +void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label) { - zclient_send_vrf_label(zclient, vrf_id, label, ZEBRA_LSP_SHARP); + zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP); } void route_add(struct prefix *p, struct nexthop *nh) diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h index 281c67ff94..0bba443bd4 100644 --- a/sharpd/sharp_zebra.h +++ b/sharpd/sharp_zebra.h @@ -24,7 +24,7 @@ extern void sharp_zebra_init(void); -extern void vrf_label_add(vrf_id_t vrf_id, mpls_label_t label); +extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label); extern void route_add(struct prefix *p, struct nexthop *nh); extern void route_delete(struct prefix *p); #endif diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index bfeb4b386c..d3a5316b9d 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -80,7 +80,7 @@ struct zebra_vrf { struct zebra_ns *zns; /* MPLS Label to handle L3VPN <-> vrf popping */ - mpls_label_t label; + mpls_label_t label[AFI_MAX]; /* MPLS static LSP config table */ struct hash *slsp_table; diff --git a/zebra/zserv.c b/zebra/zserv.c index 704b861960..ab8d8b51bc 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2486,23 +2486,27 @@ stream_failure: return 1; } + static void zread_vrf_label(struct zserv *client, struct zebra_vrf *zvrf) { struct interface *ifp; mpls_label_t nlabel; + afi_t afi; struct stream *s; struct zebra_vrf *def_zvrf; enum lsp_types_t ltype; s = client->ibuf; STREAM_GETL(s, nlabel); - if (nlabel == zvrf->label) { + STREAM_GETC(s, afi); + if (nlabel == zvrf->label[afi]) { /* * Nothing to do here move along */ return; } + STREAM_GETC(s, ltype); if (zvrf->vrf->vrf_id != VRF_DEFAULT) @@ -2518,15 +2522,15 @@ static void zread_vrf_label(struct zserv *client, def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); - if (zvrf->label != MPLS_LABEL_NONE) - mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label, + if (zvrf->label[afi] != MPLS_LABEL_NONE) + mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label[afi], NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); if (nlabel != MPLS_LABEL_NONE) mpls_lsp_install(def_zvrf, ltype, nlabel, MPLS_LABEL_IMPLICIT_NULL, NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); - zvrf->label = nlabel; + zvrf->label[afi] = nlabel; stream_failure: return; } From d0a6f3e0c5a28ef927cc4bae9b24b284f966d0bd Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sat, 10 Feb 2018 14:03:09 -0500 Subject: [PATCH 36/45] isisd: Free up some memory allocated. The v4 and v6 prefixes were created but not deleted on shutdown properly. Signed-off-by: Donald Sharp (cherry picked from commit 25b1001dc9c46bbfcb9e1af8231e0fa63a7d3bd3) Signed-off-by: Rafael Zalamena --- isisd/isis_circuit.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index 95e02f8691..98087942a6 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -293,6 +293,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit, if (ip) { listnode_delete(circuit->ip_addrs, ip); + prefix_ipv4_free(ip); if (circuit->area) lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); @@ -328,6 +329,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit, } if (ip6) { listnode_delete(circuit->ipv6_link, ip6); + prefix_ipv6_free(ip6); found = 1; } } else { @@ -339,6 +341,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit, } if (ip6) { listnode_delete(circuit->ipv6_non_link, ip6); + prefix_ipv6_free(ip6); found = 1; } } From 76249532faadfb429f46dd94cf6bbc61d78b3f26 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Fri, 26 Jan 2018 14:53:43 -0800 Subject: [PATCH 37/45] ospf6d: Handle Premature Aging of LSAs RFC 2328 (14.1) Premature aging of LSAs from routing domain : When ospf6d is going away (router going down), send MAXAGEd self originated LSAs to all neighbors in routing domain to trigger Premature aging to remove from resepective LSDBs. Neighbor Router Reboot: Upon receiving Self-originate MAXAGEd LSA, simply discard, Current copy could be non maxaged latest. For neighbor advertised LSA's (current copy in LSDB) is set to MAXAGE but received new LSA with Non-MAXAGE (with current age), discard the current MAXAGE LSA, Send latest copy of LSA to neighbors and update the LSDB with new LSA. When a neighbor transition to FULL, trigger AS-External LSAs update from external LSDB to new neighbor. Testing: R1 ---- DUT --- R5 | \ R2 R3 | R4 Area 1: R5 and DUT Area 0: DUT, R1, R2, R3 Area 2: R2 R4 Add IPv6 static routes at R5 Redistribute kernel routes at R5, Validate routes at R4, redistributed via backbone to area 2. Stop n start frr.service at R5 and validated MAXAGE LSAs then recent age LSAs in Database at DUT-R4. Validated external routes installed DUT to R4. Signed-off-by: Chirag Shah --- ospf6d/ospf6_asbr.c | 26 ++++++++++++++ ospf6d/ospf6_flood.c | 74 ++++++++++++++++++++++++++++++++-------- ospf6d/ospf6_flood.h | 5 +++ ospf6d/ospf6_interface.c | 2 ++ ospf6d/ospf6_interface.h | 1 + ospf6d/ospf6_intra.h | 17 ++++++++- ospf6d/ospf6_lsa.c | 31 +++++++++++++++++ ospf6d/ospf6_lsa.h | 1 + ospf6d/ospf6_lsdb.c | 1 + ospf6d/ospf6_message.c | 34 ++++++++++++++++++ ospf6d/ospf6_neighbor.c | 5 +++ ospf6d/ospf6_top.c | 2 ++ ospf6d/ospf6_top.h | 4 +++ 13 files changed, 187 insertions(+), 16 deletions(-) diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 02f8eb0b09..11f9e7c7b6 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -148,6 +148,32 @@ static void ospf6_as_external_lsa_originate(struct ospf6_route *route) ospf6_lsa_originate_process(lsa, ospf6); } +int ospf6_orig_as_external_lsa(struct thread *thread) +{ + struct ospf6_interface *oi; + struct ospf6_lsa *lsa; + uint32_t type, adv_router; + + oi = (struct ospf6_interface *)THREAD_ARG(thread); + oi->thread_as_extern_lsa = NULL; + + if (oi->state == OSPF6_INTERFACE_DOWN) + return 0; + + type = htons(OSPF6_LSTYPE_AS_EXTERNAL); + adv_router = oi->area->ospf6->router_id; + for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, adv_router, lsa)) { + if (IS_OSPF6_DEBUG_ASBR) + zlog_debug("%s: Send update of AS-External LSA %s seq 0x%x", + __PRETTY_FUNCTION__, lsa->name, + ntohl(lsa->header->seqnum)); + + ospf6_flood_interface(NULL, lsa, oi); + } + + return 0; +} + static route_tag_t ospf6_as_external_lsa_get_tag(struct ospf6_lsa *lsa) { struct ospf6_as_external_lsa *external; diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index 42716fbc7f..17733d6099 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -192,10 +192,6 @@ void ospf6_install_lsa(struct ospf6_lsa *lsa) struct timeval now; struct ospf6_lsa *old; - if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type) - || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type)) - zlog_debug("Install LSA: %s", lsa->name); - /* Remove the old instance from all neighbors' Link state retransmission list (RFC2328 13.2 last paragraph) */ old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id, @@ -237,6 +233,13 @@ void ospf6_install_lsa(struct ospf6_lsa *lsa) ospf6_lsa_checksum(lsa->header); } + if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type) + || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type)) + zlog_debug("%s Install LSA: %s age %d seqnum %x in LSDB.", + __PRETTY_FUNCTION__, lsa->name, + ntohs(lsa->header->age), + ntohl(lsa->header->seqnum)); + /* actually install */ lsa->installed = now; ospf6_lsdb_add(lsa, lsa->lsdb); @@ -246,7 +249,7 @@ void ospf6_install_lsa(struct ospf6_lsa *lsa) /* RFC2740 section 3.5.2. Sending Link State Update packets */ /* RFC2328 section 13.3 Next step in the flooding procedure */ -static void ospf6_flood_interface(struct ospf6_neighbor *from, +void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa, struct ospf6_interface *oi) { @@ -343,15 +346,24 @@ static void ospf6_flood_interface(struct ospf6_neighbor *from, continue; } - /* (d) add retrans-list, schedule retransmission */ - if (is_debug) - zlog_debug("Add retrans-list of this neighbor"); - ospf6_increment_retrans_count(lsa); - ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); - thread_add_timer(master, ospf6_lsupdate_send_neighbor, on, - on->ospf6_if->rxmt_interval, - &on->thread_send_lsupdate); - retrans_added++; + if (ospf6->inst_shutdown) { + if (is_debug) + zlog_debug("%s: Send LSA %s (age %d) update now", + __PRETTY_FUNCTION__, lsa->name, + ntohs(lsa->header->age)); + ospf6_lsupdate_send_neighbor_now(on, lsa); + continue; + } else { + /* (d) add retrans-list, schedule retransmission */ + if (is_debug) + zlog_debug("Add retrans-list of this neighbor"); + ospf6_increment_retrans_count(lsa); + ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); + thread_add_timer(master, ospf6_lsupdate_send_neighbor, + on, on->ospf6_if->rxmt_interval, + &on->thread_send_lsupdate); + retrans_added++; + } } /* (2) examin next interface if not added to retrans-list */ @@ -806,6 +818,17 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from, zlog_debug("Received is duplicated LSA"); SET_FLAG(new->flag, OSPF6_LSA_DUPLICATE); } + if (old->header->adv_router == + from->ospf6_if->area->ospf6->router_id + && OSPF6_LSA_IS_MAXAGE(new)) { + ospf6_acknowledge_lsa(new, ismore_recent, from); + ospf6_lsa_delete(new); + if (is_debug) + zlog_debug("%s: Received is self orig MAXAGE LSA %s, discard (ismore_recent %d)", + __PRETTY_FUNCTION__, old->name, + ismore_recent); + return; + } } /* if no database copy or received is more recent */ @@ -959,12 +982,34 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from, "Send back directly and then discard"); } + /* Neighbor router sent recent age for LSA, + * Router could be restarted while current copy is + * MAXAGEd and not removed.*/ + if (OSPF6_LSA_IS_MAXAGE(old) && + !OSPF6_LSA_IS_MAXAGE(new)) { + + if (is_debug) + zlog_debug("%s: Current copy of LSA %s is MAXAGE, but new has recent Age.", + old->name, + __PRETTY_FUNCTION__); + + ospf6_lsa_purge(old); + if (new->header->adv_router + != from->ospf6_if->area-> + ospf6->router_id) + ospf6_flood(from, new); + + ospf6_install_lsa(new); + return; + } + /* XXX, MinLSArrival check !? RFC 2328 13 (8) */ ospf6_lsdb_add(ospf6_lsa_copy(old), from->lsupdate_list); thread_add_event(master, ospf6_lsupdate_send_neighbor, from, 0, &from->thread_send_lsupdate); + ospf6_lsa_delete(new); return; } @@ -972,7 +1017,6 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from, } } - DEFUN (debug_ospf6_flooding, debug_ospf6_flooding_cmd, "debug ospf6 flooding", diff --git a/ospf6d/ospf6_flood.h b/ospf6d/ospf6_flood.h index 610eefc803..f5d33e2843 100644 --- a/ospf6d/ospf6_flood.h +++ b/ospf6d/ospf6_flood.h @@ -58,5 +58,10 @@ extern void ospf6_install_lsa(struct ospf6_lsa *lsa); extern int config_write_ospf6_debug_flood(struct vty *vty); extern void install_element_ospf6_debug_flood(void); +extern void ospf6_flood_interface(struct ospf6_neighbor *from, + struct ospf6_lsa *lsa, + struct ospf6_interface *oi); +extern int ospf6_lsupdate_send_neighbor_now(struct ospf6_neighbor *on, + struct ospf6_lsa *lsa); #endif /* OSPF6_FLOOD_H */ diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index fc6c46c7e7..5eaf617702 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -301,6 +301,7 @@ void ospf6_interface_disable(struct ospf6_interface *oi) THREAD_OFF(oi->thread_network_lsa); THREAD_OFF(oi->thread_link_lsa); THREAD_OFF(oi->thread_intra_prefix_lsa); + THREAD_OFF(oi->thread_as_extern_lsa); } static struct in6_addr * @@ -532,6 +533,7 @@ static void ospf6_interface_state_change(u_char next_state, OSPF6_NETWORK_LSA_EXECUTE(oi); OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi); OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area); + OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi); } else if (prev_state == OSPF6_INTERFACE_DR || next_state == OSPF6_INTERFACE_DR) { OSPF6_NETWORK_LSA_SCHEDULE(oi); diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h index b67d9a9f2e..9b9952beb6 100644 --- a/ospf6d/ospf6_interface.h +++ b/ospf6d/ospf6_interface.h @@ -108,6 +108,7 @@ struct ospf6_interface { struct thread *thread_network_lsa; struct thread *thread_link_lsa; struct thread *thread_intra_prefix_lsa; + struct thread *thread_as_extern_lsa; struct ospf6_route_table *route_connected; diff --git a/ospf6d/ospf6_intra.h b/ospf6d/ospf6_intra.h index b511a92005..2ae17f0700 100644 --- a/ospf6d/ospf6_intra.h +++ b/ospf6d/ospf6_intra.h @@ -185,11 +185,21 @@ struct ospf6_intra_prefix_lsa { 0, &(oi)->thread_intra_prefix_lsa); \ } while (0) +#define OSPF6_AS_EXTERN_LSA_SCHEDULE(oi) \ + do { \ + if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ + thread_add_event( \ + master, \ + ospf6_orig_as_external_lsa, oi, \ + 0, &(oi)->thread_as_extern_lsa); \ + } while (0) + #define OSPF6_NETWORK_LSA_EXECUTE(oi) \ do { \ THREAD_OFF((oi)->thread_network_lsa); \ thread_execute(master, ospf6_network_lsa_originate, oi, 0); \ } while (0) + #define OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi) \ do { \ THREAD_OFF((oi)->thread_intra_prefix_lsa); \ @@ -198,6 +208,11 @@ struct ospf6_intra_prefix_lsa { 0); \ } while (0) +#define OSPF6_AS_EXTERN_LSA_EXECUTE(oi) \ + do { \ + THREAD_OFF((oi)->thread_as_extern_lsa); \ + thread_execute(master, ospf6_orig_as_external_lsa, oi, 0); \ + } while (0) /* Function Prototypes */ extern char *ospf6_router_lsdesc_lookup(u_char type, u_int32_t interface_id, @@ -215,7 +230,7 @@ extern int ospf6_intra_prefix_lsa_originate_transit(struct thread *); extern int ospf6_intra_prefix_lsa_originate_stub(struct thread *); extern void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa); extern void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa *lsa); - +extern int ospf6_orig_as_external_lsa(struct thread *thread); extern void ospf6_intra_route_calculation(struct ospf6_area *oa); extern void ospf6_intra_brouter_calculation(struct ospf6_area *oa); diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index cca4616c16..4a1ba992e3 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -706,6 +706,37 @@ int ospf6_lsa_refresh(struct thread *thread) return 0; } +void ospf6_flush_self_originated_lsas_now(void) +{ + struct listnode *node; + struct ospf6_area *oa; + struct ospf6_lsa *lsa; + const struct route_node *end = NULL; + uint32_t type, adv_router; + + ospf6->inst_shutdown = 1; + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { + end = ospf6_lsdb_head(oa->lsdb_self, 0, 0, + ospf6->router_id, &lsa); + while (lsa) { + /* RFC 2328 (14.1): Set MAXAGE */ + lsa->header->age = htons(OSPF_LSA_MAXAGE); + /* Flood MAXAGE LSA*/ + ospf6_flood(NULL, lsa); + + lsa = ospf6_lsdb_next(end, lsa); + } + } + + type = htons(OSPF6_LSTYPE_AS_EXTERNAL); + adv_router = ospf6->router_id; + for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, adv_router, lsa)) { + /* RFC 2328 (14.1): Set MAXAGE */ + lsa->header->age = htons(OSPF_LSA_MAXAGE); + ospf6_flood(NULL, lsa); + } +} /* Fletcher Checksum -- Refer to RFC1008. */ diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index db446a3287..369b381faa 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -253,5 +253,6 @@ extern void ospf6_lsa_terminate(void); extern int config_write_ospf6_debug_lsa(struct vty *vty); extern void install_element_ospf6_debug_lsa(void); extern void ospf6_lsa_age_set(struct ospf6_lsa *lsa); +extern void ospf6_flush_self_originated_lsas_now(void); #endif /* OSPF6_LSA_H */ diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c index 418f858a32..152702391b 100644 --- a/ospf6d/ospf6_lsdb.c +++ b/ospf6d/ospf6_lsdb.c @@ -334,6 +334,7 @@ int ospf6_lsdb_maxage_remover(struct ospf6_lsdb *lsdb) } if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)) zlog_debug("Remove MaxAge %s", lsa->name); + if (CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED)) { UNSET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED); /* diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index d76438ea50..fe74ddc982 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -2163,6 +2163,40 @@ int ospf6_lsupdate_send_neighbor(struct thread *thread) return 0; } +int ospf6_lsupdate_send_neighbor_now(struct ospf6_neighbor *on, + struct ospf6_lsa *lsa) +{ + struct ospf6_header *oh; + struct ospf6_lsupdate *lsupdate; + u_char *p; + int lsa_cnt = 0; + + memset(sendbuf, 0, iobuflen); + oh = (struct ospf6_header *)sendbuf; + lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh + + sizeof(struct ospf6_header)); + + p = (u_char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); + ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay); + memcpy(p, lsa->header, OSPF6_LSA_SIZE(lsa->header)); + p += OSPF6_LSA_SIZE(lsa->header); + lsa_cnt++; + + oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; + oh->length = htons(p - sendbuf); + lsupdate->lsa_number = htonl(lsa_cnt); + + if (IS_OSPF6_DEBUG_FLOODING || + IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND)) + zlog_debug("%s: Send lsupdate with lsa %s (age %u)", + __PRETTY_FUNCTION__, lsa->name, + ntohs(lsa->header->age)); + + ospf6_send_lsupdate(on, NULL, oh); + + return 0; +} + int ospf6_lsupdate_send_interface(struct thread *thread) { struct ospf6_interface *oi; diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index bde89f54a6..35d0b0a646 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -189,6 +189,11 @@ static void ospf6_neighbor_state_change(u_char next_state, OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(on->ospf6_if); } OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(on->ospf6_if->area); + + if (prev_state == OSPF6_NEIGHBOR_LOADING && + next_state == OSPF6_NEIGHBOR_FULL) { + OSPF6_AS_EXTERN_LSA_SCHEDULE(on->ospf6_if); + } } if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 749873bcf8..db39420548 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -180,6 +180,8 @@ void ospf6_delete(struct ospf6 *o) struct ospf6_area *oa; QOBJ_UNREG(o); + + ospf6_flush_self_originated_lsas_now(); ospf6_disable(ospf6); for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa)) diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index b39c25ba84..8f99cc33f4 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -94,6 +94,10 @@ struct ospf6 { struct route_table *distance_table; + /* Used during ospf instance going down send LSDB + * update to neighbors immediatly */ + uint8_t inst_shutdown; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(ospf6) From d6927cf390119c731be022acb878f76c3e106521 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Mon, 12 Feb 2018 13:22:04 -0800 Subject: [PATCH 38/45] ospf6d: router-id change notify to restart ospf6d Notify user to store config and restart ospf6d as part of router-id change cli if any of the area active. Store zebra router-id under ospf6, when static router-id removed restore zebra router-id, ask to restart ospf6d. Signed-off-by: Chirag Shah --- ospf6d/ospf6_area.h | 2 ++ ospf6d/ospf6_neighbor.c | 4 ++++ ospf6d/ospf6_top.c | 29 +++++++++++++++++++++++++++-- ospf6d/ospf6_top.h | 2 ++ ospf6d/ospf6_zebra.c | 7 +++---- 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h index b7cd9b4b09..e162d21cd2 100644 --- a/ospf6d/ospf6_area.h +++ b/ospf6d/ospf6_area.h @@ -99,6 +99,8 @@ struct ospf6_area { /* Time stamps. */ struct timeval ts_spf; /* SPF calculation time stamp. */ + + uint32_t full_nbrs; /* Fully adjacent neighbors. */ }; #define OSPF6_AREA_ENABLE 0x01 diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index 35d0b0a646..05bc254951 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -193,7 +193,11 @@ static void ospf6_neighbor_state_change(u_char next_state, if (prev_state == OSPF6_NEIGHBOR_LOADING && next_state == OSPF6_NEIGHBOR_FULL) { OSPF6_AS_EXTERN_LSA_SCHEDULE(on->ospf6_if); + on->ospf6_if->area->full_nbrs++; } + + if (prev_state == OSPF6_NEIGHBOR_FULL) + on->ospf6_if->area->full_nbrs--; } if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index db39420548..c17b8918ec 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -335,6 +335,8 @@ DEFUN(ospf6_router_id, int ret; const char *router_id_str; u_int32_t router_id; + struct ospf6_area *oa; + struct listnode *node; argv_find(argv, argc, "A.B.C.D", &idx); router_id_str = argv[idx]->arg; @@ -346,8 +348,17 @@ DEFUN(ospf6_router_id, } o->router_id_static = router_id; - if (o->router_id == 0) - o->router_id = router_id; + + for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) { + if (oa->full_nbrs) { + vty_out(vty, + "For this router-id change to take effect," + " save config and restart ospf6d\n"); + return CMD_SUCCESS; + } + } + + o->router_id = router_id; return CMD_SUCCESS; } @@ -360,8 +371,22 @@ DEFUN(no_ospf6_router_id, V4NOTATION_STR) { VTY_DECLVAR_CONTEXT(ospf6, o); + struct ospf6_area *oa; + struct listnode *node; + o->router_id_static = 0; + + for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) { + if (oa->full_nbrs) { + vty_out(vty, + "For this router-id change to take effect," + " save config and restart ospf6d\n"); + return CMD_SUCCESS; + } + } o->router_id = 0; + if (o->router_id_zebra.s_addr) + o->router_id = (uint32_t)o->router_id_zebra.s_addr; return CMD_SUCCESS; } diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index 8f99cc33f4..d7a3766b80 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -32,6 +32,8 @@ struct ospf6 { /* static router id */ u_int32_t router_id_static; + struct in_addr router_id_zebra; + /* start time */ struct timeval starttime; diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index cc87c499ee..4fb959b952 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -46,8 +46,6 @@ unsigned char conf_debug_ospf6_zebra = 0; /* information about zebra. */ struct zclient *zclient = NULL; -struct in_addr router_id_zebra; - /* Router-id update message from zebra. */ static int ospf6_router_id_update_zebra(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) @@ -56,13 +54,14 @@ static int ospf6_router_id_update_zebra(int command, struct zclient *zclient, struct ospf6 *o = ospf6; zebra_router_id_update_read(zclient->ibuf, &router_id); - router_id_zebra = router_id.u.prefix4; if (o == NULL) return 0; + o->router_id_zebra = router_id.u.prefix4; + if (o->router_id == 0) - o->router_id = (u_int32_t)router_id_zebra.s_addr; + o->router_id = (uint32_t)o->router_id_zebra.s_addr; return 0; } From 8fd9db586f17d7034ad2ec1fd972e503c70349cb Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 15 Feb 2018 13:52:57 -0500 Subject: [PATCH 39/45] zebra: Ensure unconfiguration works properly for vrf labels If you were to configure a v4 and v6 vrf pop and forward label that both happened to be the same, unconfiguring one would remove them both. This fixes that issue by noticing if we should remove it or not based upon v4 or v6 having the same label or not. Signed-off-by: Donald Sharp --- zebra/zserv.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/zebra/zserv.c b/zebra/zserv.c index ab8d8b51bc..b3b1fa79e9 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2522,9 +2522,29 @@ static void zread_vrf_label(struct zserv *client, def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); - if (zvrf->label[afi] != MPLS_LABEL_NONE) - mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label[afi], - NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); + if (zvrf->label[afi] != MPLS_LABEL_NONE) { + afi_t scrubber; + bool really_remove; + + really_remove = true; + for (scrubber = AFI_IP; scrubber < AFI_MAX ; scrubber++) { + if (scrubber == afi) + continue; + + if (zvrf->label[scrubber] == MPLS_LABEL_NONE) + continue; + + if (zvrf->label[afi] == zvrf->label[scrubber]) { + really_remove = false; + break; + } + } + + if (really_remove) + mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label[afi], + NEXTHOP_TYPE_IFINDEX, NULL, + ifp->ifindex); + } if (nlabel != MPLS_LABEL_NONE) mpls_lsp_install(def_zvrf, ltype, nlabel, MPLS_LABEL_IMPLICIT_NULL, From 9f64bf393c27f01ab8951c3d45c3a27bcc5b0cf1 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 15 Feb 2018 13:35:10 -0500 Subject: [PATCH 40/45] sharpd: Add ability to build from tarball Since sharpd is only typically built with a development build this was not noticed. Add the necessary headers to build this thingie(tm). Signed-off-by: Donald Sharp --- sharpd/subdir.am | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sharpd/subdir.am b/sharpd/subdir.am index da7d68e0bc..490a2ba787 100644 --- a/sharpd/subdir.am +++ b/sharpd/subdir.am @@ -13,6 +13,11 @@ sharpd_libsharp_a_SOURCES = \ sharpd/sharp_vty.c \ # end +noinst_HEADERS += \ + sharpd/sharp_vty.h \ + sharpd/sharp_zebra.h \ + # end + sharpd/sharp_vty_clippy.c: $(CLIPPY_DEPS) sharpd/sharp_vty.$(OBJEXT): sharpd/sharp_vty_clippy.c From 827ed7076d4761e2c3cd8fb91053b738b0231898 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Thu, 15 Feb 2018 20:55:43 +0000 Subject: [PATCH 41/45] bgpd: "no neighbor 10.13.0.12 peer-group ibgp" does not remove peer Signed-off-by: Daniel Walton This worked for unnumbered peers but not for numbered peers. This is before the fix: router bgp 100 coalesce-time 1000 neighbor FOO peer-group neighbor FOO remote-as external neighbor swp1 interface peer-group FOO neighbor 1.1.1.1 peer-group FOO ! line vty exec-timeout 0 0 ! end cel-redxp-10# wr Note: this version of vtysh never writes vtysh.conf Building Configuration... Integrated configuration saved to /etc/frr/frr.conf [OK] cel-redxp-10# conf t cel-redxp-10(config)# router bgp cel-redxp-10(config-router)# no neighbor swp1 interface peer-group FOO cel-redxp-10(config-router)# no neighbor 1.1.1.1 peer-group FOO cel-redxp-10(config-router)# do show run Building configuration... Current configuration: ! frr version 4.1-dev frr defaults datacenter hostname cel-redxp-10 ! service integrated-vtysh-config ! password cn321 ! log syslog ! router bgp 100 coalesce-time 1000 neighbor FOO peer-group neighbor FOO remote-as external neighbor 1.1.1.1 remote-as external ! address-family ipv4 unicast no neighbor 1.1.1.1 activate exit-address-family ! line vty exec-timeout 0 0 ! end cel-redxp-10(config-router)# After the fix "no neighbor 1.1.1.1 peer-group FOO" removes the 1.1.1.1 neighbor. --- bgpd/bgp_vty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 7ee641d6cf..c7140b2f1f 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -3395,7 +3395,7 @@ DEFUN (no_neighbor_set_peer_group, return CMD_WARNING_CONFIG_FAILED; } - ret = peer_group_unbind(bgp, peer, group); + ret = peer_delete(peer); return bgp_vty_return(vty, ret); } From e2063df358308bf505db0561fbae344185e8bd8d Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 16 Feb 2018 11:00:01 +0100 Subject: [PATCH 42/45] bgpd: prevent from configuring vrf-policy when in BGP VRF instance Under a BGP VRF instance, prevent from entering in vrf-policy mode. This mode is reserved for non VRF instances that want to handle several VRF at the same time. Signed-off-by: Philippe Guibert --- bgpd/rfapi/bgp_rfapi_cfg.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index 15e09c639e..f28b8a2ced 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -2977,6 +2977,11 @@ DEFUN_NOSH (vnc_vrf_policy, struct rfapi_nve_group_cfg *rfg; VTY_DECLVAR_CONTEXT(bgp, bgp); + if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) { + vty_out(vty, "Can't configure vrf-policy within a BGP VRF instance\n"); + return CMD_WARNING_CONFIG_FAILED; + } + /* Search for name */ rfg = bgp_rfapi_cfg_match_byname(bgp, argv[1]->arg, RFAPI_GROUP_CFG_VRF); @@ -3007,6 +3012,10 @@ DEFUN (vnc_no_vrf_policy, { VTY_DECLVAR_CONTEXT(bgp, bgp); + /* silently return */ + if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) + return CMD_SUCCESS; + return bgp_rfapi_delete_named_nve_group(vty, bgp, argv[2]->arg, RFAPI_GROUP_CFG_VRF); } From 5a9825aac66ab221ed8baec6b26f21936de85005 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sat, 17 Feb 2018 14:52:44 -0500 Subject: [PATCH 43/45] isisd: Remove impossible check The circuit->area value is always true in every code path to isis_circuit_af_set( isis_vty.c ). Therefore was_enabled will always be true. If was_enabled ever became false then the area->ip_circuits and area->ipv6_circuits lines would segfault. Signed-off-by: Donald Sharp --- isisd/isis_circuit.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index 98087942a6..20ce0f1fad 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -1168,7 +1168,6 @@ void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router, struct isis_area *area = circuit->area; bool change = circuit->ip_router != ip_router || circuit->ipv6_router != ipv6_router; - bool was_enabled = !!circuit->area; area->ip_circuits += ip_router - circuit->ip_router; area->ipv6_circuits += ipv6_router - circuit->ipv6_router; @@ -1182,8 +1181,6 @@ void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router, if (!ip_router && !ipv6_router) isis_csm_state_change(ISIS_DISABLE, circuit, area); - else if (!was_enabled) - isis_csm_state_change(ISIS_ENABLE, circuit, area); else lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); } From 100cb793cce2ad3cad41e9b8c4d16b496dbf102b Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sat, 17 Feb 2018 14:59:32 -0500 Subject: [PATCH 44/45] bgpd: Fix value set but never used The value 'pnt' was being set but never used. If we need this in the future it will be a simple thing to add back in. Signed-off-by: Donald Sharp --- bgpd/bgp_evpn_vty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index e1e11e44ac..1373afec4e 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -83,7 +83,7 @@ static void display_vrf_import_rt(struct vty *vty, case ECOMMUNITY_ENCODE_AS: eas.as = (*pnt++ << 8); eas.as |= (*pnt++); - pnt = ptr_get_be32(pnt, &eas.val); + ptr_get_be32(pnt, &eas.val); snprintf(rt_buf, RT_ADDRSTRLEN, "%u:%u", eas.as, eas.val); @@ -195,7 +195,7 @@ static void display_import_rt(struct vty *vty, struct irt_node *irt, case ECOMMUNITY_ENCODE_AS: eas.as = (*pnt++ << 8); eas.as |= (*pnt++); - pnt = ptr_get_be32(pnt, &eas.val); + ptr_get_be32(pnt, &eas.val); snprintf(rt_buf, RT_ADDRSTRLEN, "%u:%u", eas.as, eas.val); From fa7129639684378ad852b934efeb6246ef82800e Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 20 Sep 2017 00:05:25 -0300 Subject: [PATCH 45/45] zebra: implement recursive MPLS labels When a BGP-labeled route is resolved into an LDP-labeled IGP route, zebra would install it with no labels in the kernel. This patch implements recursive MPLS labels, i.e. make zebra install all labels from the route's nexthop chain (the labels from the top-level nexthop being installed in the top of the MPLS label stack). Multiple recursion levels are supported. Signed-off-by: Renato Westphal --- zebra/rt_netlink.c | 191 ++++++++++++++++++++++----------------------- 1 file changed, 94 insertions(+), 97 deletions(-) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index d778990141..a80ab9d834 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -840,6 +840,7 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen, { struct mpls_label_stack *nh_label; mpls_lse_t out_lse[MPLS_MAX_LABELS]; + int num_labels = 0; char label_buf[256]; /* @@ -849,56 +850,54 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen, * you fix this assumption */ label_buf[0] = '\0'; - /* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP - * (in the case of LER) - */ - nh_label = nexthop->nh_label; - if (rtmsg->rtm_family == AF_MPLS) { - assert(nh_label); - assert(nh_label->num_labels == 1); - } - if (nh_label && nh_label->num_labels) { - int i, num_labels = 0; - u_int32_t bos; + assert(nexthop); + for (struct nexthop *nh = nexthop; nh; nh = nh->rparent) { char label_buf1[20]; - for (i = 0; i < nh_label->num_labels; i++) { - if (nh_label->label[i] != MPLS_LABEL_IMPLICIT_NULL) { - bos = ((i == (nh_label->num_labels - 1)) ? 1 - : 0); - out_lse[i] = mpls_lse_encode(nh_label->label[i], - 0, 0, bos); - if (IS_ZEBRA_DEBUG_KERNEL) { - if (!num_labels) - sprintf(label_buf, "label %u", - nh_label->label[i]); - else { - sprintf(label_buf1, "/%u", - nh_label->label[i]); - strlcat(label_buf, label_buf1, - sizeof(label_buf)); - } - } - num_labels++; - } - } - if (num_labels) { - if (rtmsg->rtm_family == AF_MPLS) - addattr_l(nlmsg, req_size, RTA_NEWDST, &out_lse, - num_labels * sizeof(mpls_lse_t)); - else { - struct rtattr *nest; - u_int16_t encap = LWTUNNEL_ENCAP_MPLS; + nh_label = nh->nh_label; + if (!nh_label || !nh_label->num_labels) + continue; - addattr_l(nlmsg, req_size, RTA_ENCAP_TYPE, - &encap, sizeof(u_int16_t)); - nest = addattr_nest(nlmsg, req_size, RTA_ENCAP); - addattr_l(nlmsg, req_size, MPLS_IPTUNNEL_DST, - &out_lse, - num_labels * sizeof(mpls_lse_t)); - addattr_nest_end(nlmsg, nest); + for (int i = 0; i < nh_label->num_labels; i++) { + if (nh_label->label[i] == MPLS_LABEL_IMPLICIT_NULL) + continue; + + if (IS_ZEBRA_DEBUG_KERNEL) { + if (!num_labels) + sprintf(label_buf, "label %u", + nh_label->label[i]); + else { + sprintf(label_buf1, "/%u", + nh_label->label[i]); + strlcat(label_buf, label_buf1, + sizeof(label_buf)); + } } + + out_lse[num_labels] = + mpls_lse_encode(nh_label->label[i], 0, 0, 0); + num_labels++; + } + } + + if (num_labels) { + /* Set the BoS bit */ + out_lse[num_labels - 1] |= htonl(1 << MPLS_LS_S_SHIFT); + + if (rtmsg->rtm_family == AF_MPLS) + addattr_l(nlmsg, req_size, RTA_NEWDST, &out_lse, + num_labels * sizeof(mpls_lse_t)); + else { + struct rtattr *nest; + u_int16_t encap = LWTUNNEL_ENCAP_MPLS; + + addattr_l(nlmsg, req_size, RTA_ENCAP_TYPE, &encap, + sizeof(u_int16_t)); + nest = addattr_nest(nlmsg, req_size, RTA_ENCAP); + addattr_l(nlmsg, req_size, MPLS_IPTUNNEL_DST, &out_lse, + num_labels * sizeof(mpls_lse_t)); + addattr_nest_end(nlmsg, nest); } } @@ -1045,6 +1044,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen, { struct mpls_label_stack *nh_label; mpls_lse_t out_lse[MPLS_MAX_LABELS]; + int num_labels = 0; char label_buf[256]; rtnh->rtnh_len = sizeof(*rtnh); @@ -1059,63 +1059,60 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen, * you fix this assumption */ label_buf[0] = '\0'; - /* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP - * (in the case of LER) - */ - nh_label = nexthop->nh_label; - if (rtmsg->rtm_family == AF_MPLS) { - assert(nh_label); - assert(nh_label->num_labels == 1); - } - if (nh_label && nh_label->num_labels) { - int i, num_labels = 0; - u_int32_t bos; + assert(nexthop); + for (struct nexthop *nh = nexthop; nh; nh = nh->rparent) { char label_buf1[20]; - for (i = 0; i < nh_label->num_labels; i++) { - if (nh_label->label[i] != MPLS_LABEL_IMPLICIT_NULL) { - bos = ((i == (nh_label->num_labels - 1)) ? 1 - : 0); - out_lse[i] = mpls_lse_encode(nh_label->label[i], - 0, 0, bos); - if (IS_ZEBRA_DEBUG_KERNEL) { - if (!num_labels) - sprintf(label_buf, "label %u", - nh_label->label[i]); - else { - sprintf(label_buf1, "/%u", - nh_label->label[i]); - strlcat(label_buf, label_buf1, - sizeof(label_buf)); - } - } - num_labels++; - } - } - if (num_labels) { - if (rtmsg->rtm_family == AF_MPLS) { - rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_NEWDST, - &out_lse, - num_labels * sizeof(mpls_lse_t)); - rtnh->rtnh_len += RTA_LENGTH( - num_labels * sizeof(mpls_lse_t)); - } else { - struct rtattr *nest; - u_int16_t encap = LWTUNNEL_ENCAP_MPLS; - int len = rta->rta_len; + nh_label = nh->nh_label; + if (!nh_label || !nh_label->num_labels) + continue; - rta_addattr_l(rta, NL_PKT_BUF_SIZE, - RTA_ENCAP_TYPE, &encap, - sizeof(u_int16_t)); - nest = rta_nest(rta, NL_PKT_BUF_SIZE, - RTA_ENCAP); - rta_addattr_l(rta, NL_PKT_BUF_SIZE, - MPLS_IPTUNNEL_DST, &out_lse, - num_labels * sizeof(mpls_lse_t)); - rta_nest_end(rta, nest); - rtnh->rtnh_len += rta->rta_len - len; + for (int i = 0; i < nh_label->num_labels; i++) { + if (nh_label->label[i] == MPLS_LABEL_IMPLICIT_NULL) + continue; + + if (IS_ZEBRA_DEBUG_KERNEL) { + if (!num_labels) + sprintf(label_buf, "label %u", + nh_label->label[i]); + else { + sprintf(label_buf1, "/%u", + nh_label->label[i]); + strlcat(label_buf, label_buf1, + sizeof(label_buf)); + } } + + out_lse[num_labels] = + mpls_lse_encode(nh_label->label[i], 0, 0, 0); + num_labels++; + } + } + + if (num_labels) { + /* Set the BoS bit */ + out_lse[num_labels - 1] |= htonl(1 << MPLS_LS_S_SHIFT); + + if (rtmsg->rtm_family == AF_MPLS) { + rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_NEWDST, + &out_lse, + num_labels * sizeof(mpls_lse_t)); + rtnh->rtnh_len += + RTA_LENGTH(num_labels * sizeof(mpls_lse_t)); + } else { + struct rtattr *nest; + u_int16_t encap = LWTUNNEL_ENCAP_MPLS; + int len = rta->rta_len; + + rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_ENCAP_TYPE, + &encap, sizeof(u_int16_t)); + nest = rta_nest(rta, NL_PKT_BUF_SIZE, RTA_ENCAP); + rta_addattr_l(rta, NL_PKT_BUF_SIZE, MPLS_IPTUNNEL_DST, + &out_lse, + num_labels * sizeof(mpls_lse_t)); + rta_nest_end(rta, nest); + rtnh->rtnh_len += rta->rta_len - len; } }