From acf3a851b97209cbb922c279ae8ae9493a786686 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 22 Aug 2017 15:27:08 +0200 Subject: [PATCH 01/79] lib: fix const-check in route_node route_node->lock is "const" if --enable-dev-build is used. This is done to deter people from messing with internals of the route_table... unfortunately, the inline'd route_[un]lock_node runs into this. Signed-off-by: David Lamparter --- lib/table.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/table.h b/lib/table.h index ece40d86b3..9637fec149 100644 --- a/lib/table.h +++ b/lib/table.h @@ -227,7 +227,7 @@ extern void route_table_iter_cleanup(route_table_iter_t *iter); /* Lock node. */ static inline struct route_node *route_lock_node(struct route_node *node) { - node->lock++; + (*(unsigned *)&node->lock)++; return node; } @@ -235,7 +235,7 @@ static inline struct route_node *route_lock_node(struct route_node *node) static inline void route_unlock_node(struct route_node *node) { assert(node->lock > 0); - node->lock--; + (*(unsigned *)&node->lock)--; if (node->lock == 0) route_node_delete(node); From b81ef7b30a074ab6f90446e595a7ef4aefc75fad Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 22 Aug 2017 10:52:07 -0300 Subject: [PATCH 02/79] zebra: fix display of static routes pointing to nonexistent interfaces Bug introduced a couple of weeks ago by myself. Only happens when the route has an IP nexthop + a nexthop interface. Example: debian(config)# ip route 10.0.1.0/24 172.16.1.10 fake1 debian(config)# do sh run Building configuration... [snip] ! ip route 10.0.1.0/24 172.16.1.10 unknown ! end Signed-off-by: Renato Westphal --- zebra/zebra_vty.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index f01f037ed5..9f887e8401 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -1705,16 +1705,14 @@ static int static_config(struct vty *vty, afi_t afi, safi_t safi, inet_ntop(AF_INET, &si->addr.ipv4, buf, sizeof buf), - ifindex2ifname(si->ifindex, - si->vrf_id)); + si->ifname); break; case STATIC_IPV6_GATEWAY_IFNAME: vty_out(vty, " %s %s", inet_ntop(AF_INET6, &si->addr.ipv6, buf, sizeof buf), - ifindex2ifname(si->ifindex, - si->vrf_id)); + si->ifname); break; } From f0c4b8e1c8209229891ed76a1e408bfccd557cee Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 22 Aug 2017 10:57:55 -0300 Subject: [PATCH 03/79] zebra: redistribute srcdest routes to the client daemons Somehow we missed these bits from the original srcdest patchset. Signed-off-by: Renato Westphal --- zebra/redistribute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index ed27dc3e83..410ddcd4a0 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -114,7 +114,7 @@ static void zebra_redistribute(struct zserv *client, int type, u_short instance, if (!table) return; - for (rn = route_top(table); rn; rn = route_next(rn)) + for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) RNODE_FOREACH_RE(rn, newre) { struct prefix *dst_p, *src_p; From a5fdb4c510dd61f0300f6ed6c1b6a7d33f85933b Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 22 Aug 2017 11:18:10 -0300 Subject: [PATCH 04/79] isisd: return proper error codes in some commands CMD_ERR_AMBIGUOUS should only be used internally by the CLI. Signed-off-by: Renato Westphal --- isisd/isis_vty.c | 86 ++++++++++++++++++++++++------------------------ isisd/isisd.c | 22 ++++++------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/isisd/isis_vty.c b/isisd/isis_vty.c index 2a19465a01..17d8ad3c0b 100644 --- a/isisd/isis_vty.c +++ b/isisd/isis_vty.c @@ -181,7 +181,7 @@ DEFUN (no_isis_passive, if (if_is_loopback(circuit->interface)) { vty_out(vty, "Can't set no passive for loopback interface\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } isis_circuit_passive_set(circuit, 0); @@ -206,7 +206,7 @@ DEFUN (isis_circuit_type, is_type = string2circuit_t(argv[idx_level]->arg); if (!is_type) { vty_out(vty, "Unknown circuit-type \n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } if (circuit->state == C_STATE_UP @@ -214,7 +214,7 @@ DEFUN (isis_circuit_type, && circuit->area->is_type != is_type) { vty_out(vty, "Invalid circuit level for area %s.\n", circuit->area->area_tag); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } isis_circuit_is_type_set(circuit, is_type); @@ -262,7 +262,7 @@ DEFUN (isis_network, if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_P2P)) { vty_out(vty, "isis network point-to-point is valid only on broadcast interfaces\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } return CMD_SUCCESS; @@ -283,7 +283,7 @@ DEFUN (no_isis_network, if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_BROADCAST)) { vty_out(vty, "isis network point-to-point is valid only on broadcast interfaces\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } return CMD_SUCCESS; @@ -313,7 +313,7 @@ DEFUN (isis_passwd, argv[idx_word]->arg); if (rv) { vty_out(vty, "Too long circuit password (>254)\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } return CMD_SUCCESS; @@ -355,7 +355,7 @@ DEFUN (isis_priority, prio = atoi(argv[idx_number]->arg); if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) { vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->priority[0] = prio; @@ -400,7 +400,7 @@ DEFUN (isis_priority_l1, prio = atoi(argv[idx_number]->arg); if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) { vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->priority[0] = prio; @@ -444,7 +444,7 @@ DEFUN (isis_priority_l2, prio = atoi(argv[idx_number]->arg); if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) { vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->priority[1] = prio; @@ -494,7 +494,7 @@ DEFUN (isis_metric, "Invalid metric %d - should be <0-63> " "when narrow metric type enabled\n", met); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } /* RFC4444 */ @@ -504,7 +504,7 @@ DEFUN (isis_metric, "Invalid metric %d - should be <0-16777215> " "when wide metric type enabled\n", met); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } isis_circuit_metric_set(circuit, IS_LEVEL_1, met); @@ -554,7 +554,7 @@ DEFUN (isis_metric_l1, "Invalid metric %d - should be <0-63> " "when narrow metric type enabled\n", met); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } /* RFC4444 */ @@ -564,7 +564,7 @@ DEFUN (isis_metric_l1, "Invalid metric %d - should be <0-16777215> " "when wide metric type enabled\n", met); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } isis_circuit_metric_set(circuit, IS_LEVEL_1, met); @@ -613,7 +613,7 @@ DEFUN (isis_metric_l2, "Invalid metric %d - should be <0-63> " "when narrow metric type enabled\n", met); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } /* RFC4444 */ @@ -623,7 +623,7 @@ DEFUN (isis_metric_l2, "Invalid metric %d - should be <0-16777215> " "when wide metric type enabled\n", met); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } isis_circuit_metric_set(circuit, IS_LEVEL_2, met); @@ -667,7 +667,7 @@ DEFUN (isis_hello_interval, if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) { vty_out(vty, "Invalid hello-interval %d - should be <1-600>\n", interval); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->hello_interval[0] = (u_int16_t)interval; @@ -714,7 +714,7 @@ DEFUN (isis_hello_interval_l1, if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) { vty_out(vty, "Invalid hello-interval %ld - should be <1-600>\n", interval); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->hello_interval[0] = (u_int16_t)interval; @@ -760,7 +760,7 @@ DEFUN (isis_hello_interval_l2, if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) { vty_out(vty, "Invalid hello-interval %ld - should be <1-600>\n", interval); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->hello_interval[1] = (u_int16_t)interval; @@ -806,7 +806,7 @@ DEFUN (isis_hello_multiplier, vty_out(vty, "Invalid hello-multiplier %d - should be <2-100>\n", mult); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->hello_multiplier[0] = (u_int16_t)mult; @@ -854,7 +854,7 @@ DEFUN (isis_hello_multiplier_l1, vty_out(vty, "Invalid hello-multiplier %d - should be <2-100>\n", mult); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->hello_multiplier[0] = (u_int16_t)mult; @@ -901,7 +901,7 @@ DEFUN (isis_hello_multiplier_l2, vty_out(vty, "Invalid hello-multiplier %d - should be <2-100>\n", mult); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->hello_multiplier[1] = (u_int16_t)mult; @@ -979,7 +979,7 @@ DEFUN (csnp_interval, if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) { vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n", interval); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->csnp_interval[0] = (u_int16_t)interval; @@ -1026,7 +1026,7 @@ DEFUN (csnp_interval_l1, if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) { vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n", interval); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->csnp_interval[0] = (u_int16_t)interval; @@ -1072,7 +1072,7 @@ DEFUN (csnp_interval_l2, if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) { vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n", interval); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->csnp_interval[1] = (u_int16_t)interval; @@ -1117,7 +1117,7 @@ DEFUN (psnp_interval, if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) { vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n", interval); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->psnp_interval[0] = (u_int16_t)interval; @@ -1164,7 +1164,7 @@ DEFUN (psnp_interval_l1, if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) { vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n", interval); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->psnp_interval[0] = (u_int16_t)interval; @@ -1210,7 +1210,7 @@ DEFUN (psnp_interval_l2, if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) { vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n", interval); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } circuit->psnp_interval[1] = (u_int16_t)interval; @@ -1253,12 +1253,12 @@ DEFUN (circuit_topology, if (circuit->area && circuit->area->oldmetric) { vty_out(vty, "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } if (mtid == (uint16_t)-1) { vty_out(vty, "Don't know topology '%s'\n", arg); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } return isis_circuit_mt_enabled_set(circuit, mtid, true); @@ -1281,12 +1281,12 @@ DEFUN (no_circuit_topology, if (circuit->area && circuit->area->oldmetric) { vty_out(vty, "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } if (mtid == (uint16_t)-1) { vty_out(vty, "Don't know topology '%s'\n", arg); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } return isis_circuit_mt_enabled_set(circuit, mtid, false); @@ -1298,11 +1298,11 @@ static int validate_metric_style_narrow(struct vty *vty, struct isis_area *area) struct listnode *node; if (!vty) - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; if (!area) { vty_out(vty, "ISIS area is invalid\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { @@ -1311,14 +1311,14 @@ static int validate_metric_style_narrow(struct vty *vty, struct isis_area *area) && (circuit->te_metric[0] > MAX_NARROW_LINK_METRIC)) { vty_out(vty, "ISIS circuit %s metric is invalid\n", circuit->interface->name); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } if ((area->is_type & IS_LEVEL_2) && (circuit->is_type & IS_LEVEL_2) && (circuit->te_metric[1] > MAX_NARROW_LINK_METRIC)) { vty_out(vty, "ISIS circuit %s metric is invalid\n", circuit->interface->name); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } } @@ -1345,7 +1345,7 @@ DEFUN (metric_style, if (area_is_mt(area)) { vty_out(vty, "Narrow metrics cannot be used while multi topology IS-IS is active\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } ret = validate_metric_style_narrow(vty, area); @@ -1373,7 +1373,7 @@ DEFUN (no_metric_style, if (area_is_mt(area)) { vty_out(vty, "Narrow metrics cannot be used while multi topology IS-IS is active\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } ret = validate_metric_style_narrow(vty, area); @@ -1470,7 +1470,7 @@ static int area_lsp_mtu_set(struct vty *vty, unsigned int lsp_mtu) "ISIS area contains circuit %s, which has a maximum PDU size of %zu.\n", circuit->interface->name, isis_circuit_pdu_size(circuit)); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } } @@ -1568,7 +1568,7 @@ static int set_lsp_gen_interval(struct vty *vty, struct isis_area *area, "LSP gen interval %us must be less than " "the LSP refresh interval %us\n", interval, area->lsp_refresh[lvl - 1]); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } } @@ -1817,7 +1817,7 @@ static int area_max_lsp_lifetime_set(struct vty *vty, int level, "the configured LSP gen interval %us\n", refresh_interval, area->lsp_gen_interval[lvl - 1]); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } } } @@ -1890,14 +1890,14 @@ static int area_lsp_refresh_interval_set(struct vty *vty, int level, "LSP refresh interval %us must be greater than " "the configured LSP gen interval %us\n", interval, area->lsp_gen_interval[lvl - 1]); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } if (interval > (area->max_lsp_lifetime[lvl - 1] - 300)) { vty_out(vty, "LSP refresh interval %us must be less than " "the configured LSP lifetime %us less 300\n", interval, area->max_lsp_lifetime[lvl - 1]); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } } @@ -1961,7 +1961,7 @@ static int area_passwd_set(struct vty *vty, int level, if (passwd && strlen(passwd) > 254) { vty_out(vty, "Too long area password (>254)\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } type_set(area, level, passwd, snp_auth); diff --git a/isisd/isisd.c b/isisd/isisd.c index dba34e8e35..f8a9df45c7 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -347,14 +347,14 @@ int area_net_title(struct vty *vty, const char *net_title) "area address must be at least 8..20 octets long (%d)\n", addr->addr_len); XFREE(MTYPE_ISIS_AREA_ADDR, addr); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } if (addr->area_addr[addr->addr_len - 1] != 0) { vty_out(vty, "nsel byte (last byte) in area address must be 0\n"); XFREE(MTYPE_ISIS_AREA_ADDR, addr); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } if (isis->sysid_set == 0) { @@ -374,7 +374,7 @@ int area_net_title(struct vty *vty, const char *net_title) vty_out(vty, "System ID must not change when defining additional area addresses\n"); XFREE(MTYPE_ISIS_AREA_ADDR, addr); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } /* now we see that we don't already have this address */ @@ -419,7 +419,7 @@ int area_clear_net_title(struct vty *vty, const char *net_title) vty_out(vty, "Unsupported area address length %d, should be 8...20 \n", addr.addr_len); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } memcpy(addr.area_addr, buff, (int)addr.addr_len); @@ -1405,7 +1405,7 @@ static int show_isis_database(struct vty *vty, const char *argv, int ui_level) (u_char)strtol((char *)number, NULL, 16); pos -= 4; if (strncmp(pos, ".", 1) != 0) - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING; } if (strncmp(pos, ".", 1) == 0) { memcpy(number, ++pos, 2); @@ -1570,16 +1570,16 @@ DEFUN (isis_topology, if (area->oldmetric) { vty_out(vty, "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } if (mtid == (uint16_t)-1) { vty_out(vty, "Don't know topology '%s'\n", arg); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } if (mtid == ISIS_MT_IPV4_UNICAST) { vty_out(vty, "Cannot configure IPv4 unicast topology\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } area_set_mt_enabled(area, mtid, true); @@ -1603,16 +1603,16 @@ DEFUN (no_isis_topology, if (area->oldmetric) { vty_out(vty, "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } if (mtid == (uint16_t)-1) { vty_out(vty, "Don't know topology '%s'\n", arg); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } if (mtid == ISIS_MT_IPV4_UNICAST) { vty_out(vty, "Cannot configure IPv4 unicast topology\n"); - return CMD_ERR_AMBIGUOUS; + return CMD_WARNING_CONFIG_FAILED; } area_set_mt_enabled(area, mtid, false); From 325730733775c94ba54d769f49ca213df552ce6b Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Tue, 22 Aug 2017 10:55:12 -0400 Subject: [PATCH 05/79] ospfd, ospf6d: cleanup some `no` commands Signed-off-by: Quentin Young --- ospf6d/ospf6_interface.c | 13 +++++++------ ospfd/ospf_vty.c | 11 +++++++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 1d17a1c233..c970e990c8 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -1171,8 +1171,7 @@ DEFUN (ipv6_ospf6_cost, IP6_STR OSPF6_STR "Interface cost\n" - "Outgoing metric of this interface\n" - ) + "Outgoing metric of this interface\n") { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -1206,12 +1205,12 @@ DEFUN (ipv6_ospf6_cost, DEFUN (no_ipv6_ospf6_cost, no_ipv6_ospf6_cost_cmd, - "no ipv6 ospf6 cost", + "no ipv6 ospf6 cost [(1-65535)]", NO_STR IP6_STR OSPF6_STR "Calculate interface cost from bandwidth\n" - ) + "Outgoing metric of this interface\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; @@ -1654,11 +1653,13 @@ DEFUN (ipv6_ospf6_network, DEFUN (no_ipv6_ospf6_network, no_ipv6_ospf6_network_cmd, - "no ipv6 ospf6 network", + "no ipv6 ospf6 network []", NO_STR IP6_STR OSPF6_STR - "Set default network type\n") + "Set default network type\n" + "Specify OSPF6 broadcast network\n" + "Specify OSPF6 point-to-point network\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 47c4d0078c..87aef1ea97 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -1897,7 +1897,8 @@ DEFUN (no_ospf_area_filter_list, DEFUN (ospf_area_authentication_message_digest, ospf_area_authentication_message_digest_cmd, - "area authentication message-digest", + "[no] area authentication message-digest", + NO_STR "OSPF area parameters\n" "OSPF area ID in IP address format\n" "OSPF area ID as a decimal value\n" @@ -1914,7 +1915,7 @@ DEFUN (ospf_area_authentication_message_digest, area = ospf_area_get(ospf, area_id); ospf_area_display_format_set(ospf, area, format); - area->auth_type = OSPF_AUTH_CRYPTOGRAPHIC; + area->auth_type = strmatch(argv[0]->text, "no") ? OSPF_AUTH_NULL : OSPF_AUTH_CRYPTOGRAPHIC; return CMD_SUCCESS; } @@ -6887,10 +6888,12 @@ DEFUN (no_ip_ospf_transmit_delay, DEFUN_HIDDEN (no_ospf_transmit_delay, no_ospf_transmit_delay_cmd, - "no ospf transmit-delay", + "no ospf transmit-delay [(1-65535) [A.B.C.D]]", NO_STR "OSPF interface commands\n" - "Link state transmit delay\n") + "Link state transmit delay\n" + "Seconds\n" + "Address of interface") { return no_ip_ospf_transmit_delay(self, vty, argc, argv); } From feda3ca36c9d28af67b26336b41b1d839fb2d79f Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 22 Aug 2017 18:49:23 +0200 Subject: [PATCH 06/79] *: update git-reindent-branch.py - autodetect whether it's on master or stable/3.0 - grab .clang-format from master Signed-off-by: David Lamparter --- git-reindent-branch.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/git-reindent-branch.py b/git-reindent-branch.py index b0dd8db6de..c207f5946f 100644 --- a/git-reindent-branch.py +++ b/git-reindent-branch.py @@ -11,14 +11,28 @@ def run(cmd): proc.wait() return rv +clangfmt = run(['git', 'show', 'master:.clang-format']) + argp = argparse.ArgumentParser(description = 'git whitespace-fixing tool') argp.add_argument('branch', metavar='BRANCH', type = str, nargs = '?', default = 'HEAD') args = argp.parse_args() branch = args.branch commit = run(['git', 'rev-list', '-n', '1', branch, '--']).strip() -beforeid = run(['git', 'rev-list', '-n', '1', 'reindent-master-before', '--']).strip() -afterid = run(['git', 'rev-list', '-n', '1', 'reindent-master-after', '--']).strip() + +# frr-3.1-dev = first commit that is on master but not on stable/3.0 +masterid = run(['git', 'rev-list', '-n', '1', 'frr-3.1-dev', '--']).strip() +masterbase = run(['git', 'merge-base', commit, masterid]).strip() + +if masterbase == masterid: + refbranch = 'master' +else: + refbranch = '3.0' + +sys.stderr.write('autodetected base: %s (can be 3.0 or master)\n' % refbranch) + +beforeid = run(['git', 'rev-list', '-n', '1', 'reindent-%s-before' % refbranch, '--']).strip() +afterid = run(['git', 'rev-list', '-n', '1', 'reindent-%s-after' % refbranch, '--']).strip() beforebase = run(['git', 'merge-base', commit, beforeid]).strip() afterbase = run(['git', 'merge-base', commit, afterid]).strip() @@ -28,10 +42,10 @@ if afterbase == afterid: sys.exit(1) if beforebase != beforeid: - sys.stderr.write('you need to rebase your branch onto the tag "reindent-master-before"\n') + sys.stderr.write('you need to rebase your branch onto the tag "reindent-%s-before"\n' % refbranch) sys.exit(1) -revs = run(['git', 'rev-list', 'reindent-master-before..%s' % commit]).strip().split('\n') +revs = run(['git', 'rev-list', 'reindent-%s-before..%s' % (refbranch, commit)]).strip().split('\n') revs.reverse() srcdir = os.getcwd() @@ -39,9 +53,12 @@ tmpdir = tempfile.mkdtemp('frrindent') os.chdir(tmpdir) sys.stderr.write('using temporary directory %s; %d revisions\n' % (tmpdir, len(revs))) -run(['git', 'clone', '-s', '-b', 'reindent-master-after', srcdir, 'repo']) +run(['git', 'clone', '-s', '-b', 'reindent-%s-after' % refbranch, srcdir, 'repo']) os.chdir('repo') +with open('.clang-format', 'w') as fd: + fd.write(clangfmt) + prev = beforeid for rev in revs: filestat = run(['git', 'diff', '-z', '--name-status', prev, rev]).rstrip('\0').split('\0') From 318cac96ef7e16a17fd1ab97b67ede5c07651c52 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 22 Aug 2017 18:14:50 +0000 Subject: [PATCH 07/79] bgpd: Memory wasting in zebra by non used MPLS FECs Signed-off-by: Daniel Walton --- bgpd/bgp_route.c | 7 +++- bgpd/bgp_vty.c | 23 +----------- bgpd/bgpd.c | 95 ++++++++++++++++++++++++++++++++++++++---------- bgpd/bgpd.h | 4 ++ 4 files changed, 85 insertions(+), 44 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index bb204b01f1..0c60231ded 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2045,7 +2045,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn, * to do this upon changes to best path except of the label index * changes. */ - if (safi == SAFI_UNICAST) { + if (bgp->allocate_mpls_labels[afi][safi]) { if (new_select) { if (!old_select || bgp_label_index_differs(new_select, old_select) @@ -2066,8 +2066,11 @@ 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)) { + bgp_unregister_for_label(rn); } /* If best route remains the same and this is not due to user-initiated diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 2e18a6d44f..f040ed9a08 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -7018,26 +7018,6 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, return CMD_SUCCESS; } -/* - * Return if we have a peer configured to use this afi/safi - */ -static int bgp_show_summary_afi_safi_peer_exists(struct bgp *bgp, int afi, - int safi) -{ - struct listnode *node; - struct peer *peer; - - for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { - if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) - continue; - - if (peer->afc[afi][safi]) - return 1; - } - - return 0; -} - static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi, int safi, u_char use_json, json_object *json) @@ -7056,8 +7036,7 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi, if (safi_wildcard) safi = 1; /* SAFI_UNICAST */ while (safi < SAFI_MAX) { - if (bgp_show_summary_afi_safi_peer_exists(bgp, afi, - safi)) { + if (bgp_afi_safi_peer_exists(bgp, afi, safi)) { json_output = true; if (is_wildcard) { /* diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 9d7c38c871..ba2e82a42e 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1391,6 +1391,32 @@ void bgp_peer_conf_if_to_su_update(struct peer *peer) hash_get(peer->bgp->peerhash, peer, hash_alloc_intern); } +static void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi, + safi_t safi) +{ + struct bgp_node *rn, *nrn; + + for (rn = bgp_table_top(bgp->rib[afi][safi]); rn; + rn = bgp_route_next(rn)) { + if (rn->info != NULL) { + /* Special handling for 2-level routing + * tables. */ + 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); + } else + bgp_process(bgp, rn, afi, safi); + } + } +} + /* Force a bestpath recalculation for all prefixes. This is used * when 'bgp bestpath' commands are entered. */ @@ -1398,29 +1424,10 @@ void bgp_recalculate_all_bestpaths(struct bgp *bgp) { afi_t afi; safi_t safi; - struct bgp_node *rn, *nrn; for (afi = AFI_IP; afi < AFI_MAX; afi++) { for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { - for (rn = bgp_table_top(bgp->rib[afi][safi]); rn; - rn = bgp_route_next(rn)) { - if (rn->info != NULL) { - /* Special handling for 2-level routing - * tables. */ - 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); - } else - bgp_process(bgp, rn, afi, safi); - } - } + bgp_recalculate_afi_safi_bestpaths(bgp, afi, safi); } } } @@ -1500,6 +1507,25 @@ struct peer *peer_create_accept(struct bgp *bgp) return peer; } +/* + * Return true if we have a peer configured to use this afi/safi + */ +int bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi) +{ + struct listnode *node; + struct peer *peer; + + for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { + if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) + continue; + + if (peer->afc[afi][safi]) + return 1; + } + + return 0; +} + /* Change peer's AS number. */ void peer_as_change(struct peer *peer, as_t as, int as_specified) { @@ -1714,11 +1740,14 @@ int peer_activate(struct peer *peer, afi_t afi, safi_t safi) struct peer_group *group; struct listnode *node, *nnode; struct peer *tmp_peer; + struct bgp *bgp; /* Nothing to do if we've already activated this peer */ if (peer->afc[afi][safi]) return ret; + bgp = peer->bgp; + /* This is a peer-group so activate all of the members of the * peer-group as well */ if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { @@ -1741,6 +1770,17 @@ int peer_activate(struct peer *peer, afi_t afi, safi_t safi) ret |= non_peergroup_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 (BGP_DEBUG(zebra, ZEBRA)) + 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); + } + return ret; } @@ -1798,6 +1838,7 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi) struct peer_group *group; struct peer *tmp_peer; struct listnode *node, *nnode; + struct bgp *bgp; /* Nothing to do if we've already de-activated this peer */ if (!peer->afc[afi][safi]) @@ -1821,6 +1862,20 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi) ret |= non_peergroup_deactivate_af(peer, afi, 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 (BGP_DEBUG(zebra, ZEBRA)) + 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); + } return ret; } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index f6e7b2277f..5ede9ba13d 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -333,6 +333,9 @@ struct bgp { /* BGP redistribute configuration. */ struct list *redist[AFI_MAX][ZEBRA_ROUTE_MAX]; + /* Allocate MPLS labels */ + u_char allocate_mpls_labels[AFI_MAX][SAFI_MAX]; + /* timer to re-evaluate neighbor default-originate route-maps */ struct thread *t_rmap_def_originate_eval; #define RMAP_DEFAULT_ORIGINATE_EVAL_TIMER 5 @@ -1280,6 +1283,7 @@ extern int bgp_listen_limit_unset(struct bgp *); extern int bgp_update_delay_active(struct bgp *); extern int bgp_update_delay_configured(struct bgp *); +extern int bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi); extern void peer_as_change(struct peer *, as_t, int); extern int peer_remote_as(struct bgp *, union sockunion *, const char *, as_t *, int, afi_t, safi_t); From 7b2ff250318a27a03937b1edae68ffbf06714eab Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 22 Aug 2017 19:11:31 +0000 Subject: [PATCH 08/79] bgpd: remove json option from 'sh ip bgp' commands that do not support it Signed-off-by: Daniel Walton --- bgpd/bgp_route.c | 114 +++++++++++++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 39 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 0c60231ded..d54dec269c 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8838,32 +8838,28 @@ DEFUN (show_ip_bgp_large_community, static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi); -/* BGP route print out function. */ + +/* BGP route print out function without JSON */ DEFUN (show_ip_bgp, show_ip_bgp_cmd, "show [ip] bgp [ VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\ - [<\ - cidr-only\ - |dampening \ - |route-map WORD\ - |prefix-list WORD\ - |filter-list WORD\ - |statistics\ - |community [ [exact-match]]\ - |community-list <(1-500)|WORD> [exact-match]\ - |A.B.C.D/M longer-prefixes\ - |X:X::X:X/M longer-prefixes>\ - ] [json]", + \ + |route-map WORD\ + |prefix-list WORD\ + |filter-list WORD\ + |statistics\ + |community [exact-match]\ + |community-list <(1-500)|WORD> [exact-match]\ + |A.B.C.D/M longer-prefixes\ + |X:X::X:X/M longer-prefixes\ + >", SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR BGP_SAFI_WITH_LABEL_HELP_STR - "Display only routes with non-natural netmasks\n" "Display detailed information about dampening\n" - "Display flap statistics of routes\n" - "Display paths suppressed due to dampening\n" "Display detail of configured dampening parameters\n" "Display routes matching the route-map\n" "A route-map to match on\n" @@ -8885,13 +8881,11 @@ DEFUN (show_ip_bgp, "IPv4 prefix\n" "Display route and more specific routes\n" "IPv6 prefix\n" - "Display route and more specific routes\n" - JSON_STR) + "Display route and more specific routes\n") { afi_t afi = AFI_IP6; safi_t safi = SAFI_UNICAST; int exact_match = 0; - enum bgp_show_type sh_type = bgp_show_type_normal; struct bgp *bgp = NULL; int idx = 0; @@ -8900,23 +8894,8 @@ DEFUN (show_ip_bgp, if (!idx) return CMD_WARNING; - int uj = use_json(argc, argv); - if (uj) - argc--; - - if (argv_find(argv, argc, "cidr-only", &idx)) - return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only, - NULL, uj); - if (argv_find(argv, argc, "dampening", &idx)) { - if (argv_find(argv, argc, "dampened-paths", &idx)) - return bgp_show(vty, bgp, afi, safi, - bgp_show_type_dampend_paths, NULL, uj); - else if (argv_find(argv, argc, "flap-statistics", &idx)) - return bgp_show(vty, bgp, afi, safi, - bgp_show_type_flap_statistics, NULL, - uj); - else if (argv_find(argv, argc, "parameters", &idx)) + if (argv_find(argv, argc, "parameters", &idx)) return bgp_show_dampening_parameters(vty, afi, safi); } @@ -8945,10 +8924,6 @@ DEFUN (show_ip_bgp, return bgp_show_community(vty, bgp, argc, argv, exact_match, afi, safi); } - /* show all communities */ - else - return bgp_show(vty, bgp, afi, safi, - bgp_show_type_community_all, NULL, uj); } if (argv_find(argv, argc, "community-list", &idx)) { @@ -8965,6 +8940,66 @@ DEFUN (show_ip_bgp, safi, bgp_show_type_prefix_longer); + return CMD_WARNING; +} + +/* BGP route print out function with JSON */ +DEFUN (show_ip_bgp_json, + show_ip_bgp_json_cmd, + "show [ip] bgp [ VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\ + [<\ + cidr-only\ + |dampening \ + |community \ + >] [json]", + SHOW_STR + IP_STR + BGP_STR + BGP_INSTANCE_HELP_STR + BGP_AFI_HELP_STR + BGP_SAFI_WITH_LABEL_HELP_STR + "Display only routes with non-natural netmasks\n" + "Display detailed information about dampening\n" + "Display flap statistics of routes\n" + "Display paths suppressed due to dampening\n" + "Display routes matching the communities\n" + JSON_STR) +{ + afi_t afi = AFI_IP6; + safi_t safi = SAFI_UNICAST; + enum bgp_show_type sh_type = bgp_show_type_normal; + struct bgp *bgp = NULL; + int idx = 0; + + bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, + &bgp); + if (!idx) + return CMD_WARNING; + + int uj = use_json(argc, argv); + if (uj) + argc--; + + if (argv_find(argv, argc, "cidr-only", &idx)) + return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only, + NULL, uj); + + if (argv_find(argv, argc, "dampening", &idx)) { + if (argv_find(argv, argc, "dampened-paths", &idx)) + return bgp_show(vty, bgp, afi, safi, + bgp_show_type_dampend_paths, NULL, uj); + else if (argv_find(argv, argc, "flap-statistics", &idx)) + return bgp_show(vty, bgp, afi, safi, + bgp_show_type_flap_statistics, NULL, + uj); + } + + if (argv_find(argv, argc, "community", &idx)) { + /* show all communities */ + return bgp_show(vty, bgp, afi, safi, + bgp_show_type_community_all, NULL, uj); + } + if (safi == SAFI_MPLS_VPN) return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal, NULL, 0, uj); @@ -11283,6 +11318,7 @@ void bgp_route_init(void) /* IPv4 labeled-unicast configuration. */ install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd); install_element(VIEW_NODE, &show_ip_bgp_cmd); + install_element(VIEW_NODE, &show_ip_bgp_json_cmd); install_element(VIEW_NODE, &show_ip_bgp_route_cmd); install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd); From e889891d8b543a93521e4d15a51770daf482b979 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 22 Aug 2017 19:33:22 +0000 Subject: [PATCH 09/79] bgpd: 'show ip bgp regex' needs to be VRF aware Signed-off-by: Daniel Walton --- bgpd/bgp_route.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index d54dec269c..cc9e902eb1 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8020,7 +8020,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, const char *regstr, afi_t afi, +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, int argc, struct cmd_token **argv, int exact, afi_t afi, @@ -9109,7 +9110,7 @@ DEFUN (show_ip_bgp_regexp, idx++; char *regstr = argv_concat(argv, argc, idx); - int rc = bgp_show_regexp(vty, (const char *)regstr, afi, safi, + int rc = bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi, bgp_show_type_regexp); XFREE(MTYPE_TMP, regstr); return rc; @@ -9144,7 +9145,8 @@ DEFUN (show_ip_bgp_instance_all, return CMD_SUCCESS; } -static int bgp_show_regexp(struct vty *vty, const char *regstr, afi_t afi, +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; @@ -9156,7 +9158,7 @@ static int bgp_show_regexp(struct vty *vty, const char *regstr, afi_t afi, return CMD_WARNING; } - rc = bgp_show(vty, NULL, afi, safi, type, regex, 0); + rc = bgp_show(vty, bgp, afi, safi, type, regex, 0); bgp_regex_free(regex); return rc; } From d23d6de866561418be6aab0298301a4aa558b538 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Tue, 22 Aug 2017 12:29:53 -0400 Subject: [PATCH 10/79] ospf6d: add `no` forms for interface commands Signed-off-by: Quentin Young --- ospf6d/ospf6_interface.c | 108 +++++++++++++++++++++++++++++++-------- 1 file changed, 87 insertions(+), 21 deletions(-) diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index c970e990c8..bb63fb966e 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -1291,8 +1291,7 @@ DEFUN (ipv6_ospf6_hellointerval, IP6_STR OSPF6_STR "Time between HELLO packets\n" - SECONDS_STR - ) + SECONDS_STR) { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -1304,10 +1303,21 @@ DEFUN (ipv6_ospf6_hellointerval, oi = ospf6_interface_create(ifp); assert(oi); - oi->hello_interval = strtol(argv[idx_number]->arg, NULL, 10); + oi->hello_interval = strmatch(argv[0]->text, "no") + ? OSPF_HELLO_INTERVAL_DEFAULT + : strtoul(argv[idx_number]->arg, NULL, 10); return CMD_SUCCESS; } +ALIAS (ipv6_ospf6_hellointerval, + no_ipv6_ospf6_hellointerval_cmd, + "no ipv6 ospf6 hello-interval [(1-65535)]", + NO_STR + IP6_STR + OSPF6_STR + "Time between HELLO packets\n" + SECONDS_STR) + /* interface variable set command */ DEFUN (ipv6_ospf6_deadinterval, ipv6_ospf6_deadinterval_cmd, @@ -1315,8 +1325,7 @@ DEFUN (ipv6_ospf6_deadinterval, IP6_STR OSPF6_STR "Interval time after which a neighbor is declared down\n" - SECONDS_STR - ) + SECONDS_STR) { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -1328,10 +1337,21 @@ DEFUN (ipv6_ospf6_deadinterval, oi = ospf6_interface_create(ifp); assert(oi); - oi->dead_interval = strtol(argv[idx_number]->arg, NULL, 10); + oi->dead_interval = strmatch(argv[0]->arg, "no") + ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT + : strtoul(argv[idx_number]->arg, NULL, 10); return CMD_SUCCESS; } +ALIAS (ipv6_ospf6_deadinterval, + no_ipv6_ospf6_deadinterval_cmd, + "no ipv6 ospf6 dead-interval [(1-65535)]", + NO_STR + IP6_STR + OSPF6_STR + "Interval time after which a neighbor is declared down\n" + SECONDS_STR) + /* interface variable set command */ DEFUN (ipv6_ospf6_transmitdelay, ipv6_ospf6_transmitdelay_cmd, @@ -1351,10 +1371,21 @@ DEFUN (ipv6_ospf6_transmitdelay, oi = ospf6_interface_create(ifp); assert(oi); - oi->transdelay = strtol(argv[idx_number]->arg, NULL, 10); + oi->transdelay = strmatch(argv[0]->text, "no") + ? OSPF6_INTERFACE_TRANSDELAY + : strtoul(argv[idx_number]->arg, NULL, 10); return CMD_SUCCESS; } +ALIAS (ipv6_ospf6_transmitdelay, + no_ipv6_ospf6_transmitdelay_cmd, + "no ipv6 ospf6 transmit-delay [(1-3600)]", + NO_STR + IP6_STR + OSPF6_STR + "Link state transmit delay\n" + SECONDS_STR) + /* interface variable set command */ DEFUN (ipv6_ospf6_retransmitinterval, ipv6_ospf6_retransmitinterval_cmd, @@ -1362,8 +1393,7 @@ DEFUN (ipv6_ospf6_retransmitinterval, IP6_STR OSPF6_STR "Time between retransmitting lost link state advertisements\n" - SECONDS_STR - ) + SECONDS_STR) { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -1375,10 +1405,21 @@ DEFUN (ipv6_ospf6_retransmitinterval, oi = ospf6_interface_create(ifp); assert(oi); - oi->rxmt_interval = strtol(argv[idx_number]->arg, NULL, 10); + oi->rxmt_interval = strmatch(argv[0]->text, "no") + ? OSPF_RETRANSMIT_INTERVAL_DEFAULT + : strtoul(argv[idx_number]->arg, NULL, 10); return CMD_SUCCESS; } +ALIAS (ipv6_ospf6_retransmitinterval, + no_ipv6_ospf6_retransmitinterval_cmd, + "no ipv6 ospf6 retransmit-interval [(1-65535)]", + NO_STR + IP6_STR + OSPF6_STR + "Time between retransmitting lost link state advertisements\n" + SECONDS_STR) + /* interface variable set command */ DEFUN (ipv6_ospf6_priority, ipv6_ospf6_priority_cmd, @@ -1386,8 +1427,7 @@ DEFUN (ipv6_ospf6_priority, IP6_STR OSPF6_STR "Router priority\n" - "Priority value\n" - ) + "Priority value\n") { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -1399,7 +1439,9 @@ DEFUN (ipv6_ospf6_priority, oi = ospf6_interface_create(ifp); assert(oi); - oi->priority = strtol(argv[idx_number]->arg, NULL, 10); + oi->priority = strmatch(argv[0]->text, "no") + ? OSPF6_INTERFACE_PRIORITY + : strtoul(argv[idx_number]->arg, NULL, 10); if (oi->area && (oi->state == OSPF6_INTERFACE_DROTHER || oi->state == OSPF6_INTERFACE_BDR @@ -1409,14 +1451,22 @@ DEFUN (ipv6_ospf6_priority, return CMD_SUCCESS; } +ALIAS (ipv6_ospf6_priority, + no_ipv6_ospf6_priority_cmd, + "no ipv6 ospf6 priority [(0-255)]", + NO_STR + IP6_STR + OSPF6_STR + "Router priority\n" + "Priority value\n") + DEFUN (ipv6_ospf6_instance, ipv6_ospf6_instance_cmd, "ipv6 ospf6 instance-id (0-255)", IP6_STR OSPF6_STR "Instance ID for this interface\n" - "Instance ID value\n" - ) + "Instance ID value\n") { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -1428,10 +1478,21 @@ DEFUN (ipv6_ospf6_instance, oi = ospf6_interface_create(ifp); assert(oi); - oi->instance_id = strtol(argv[idx_number]->arg, NULL, 10); + oi->instance_id = strmatch(argv[0]->text, "no") + ? OSPF6_INTERFACE_INSTANCE_ID + : strtoul(argv[idx_number]->arg, NULL, 10); return CMD_SUCCESS; } +ALIAS (ipv6_ospf6_instance, + no_ipv6_ospf6_instance_cmd, + "no ipv6 ospf6 instance-id [(0-255)]", + NO_STR + IP6_STR + OSPF6_STR + "Instance ID for this interface\n" + "Instance ID value\n") + DEFUN (ipv6_ospf6_passive, ipv6_ospf6_passive_cmd, "ipv6 ospf6 passive", @@ -1575,13 +1636,13 @@ DEFUN (ipv6_ospf6_advertise_prefix_list, DEFUN (no_ipv6_ospf6_advertise_prefix_list, no_ipv6_ospf6_advertise_prefix_list_cmd, - "no ipv6 ospf6 advertise prefix-list", + "no ipv6 ospf6 advertise prefix-list [WORD]", NO_STR IP6_STR OSPF6_STR "Advertising options\n" "Filter prefix using prefix-list\n" - ) + "Prefix list name\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; @@ -1592,10 +1653,8 @@ DEFUN (no_ipv6_ospf6_advertise_prefix_list, oi = ospf6_interface_create(ifp); assert(oi); - if (oi->plist_name) { + if (oi->plist_name) XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name); - oi->plist_name = NULL; - } ospf6_interface_connected_route_update(oi->interface); @@ -1773,12 +1832,19 @@ void ospf6_interface_init(void) install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd); install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_instance_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd); install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd); From 5e8c8947e3fb53d2fdbdf804c6014d6ecdb0b904 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 22 Aug 2017 17:01:54 -0300 Subject: [PATCH 11/79] zebra: increase maximum label stack depth * Bump MPLS_MAX_LABELS from 2 to 16; * Adjust the static_nh_label structure and the mpls_label2str() function; * On OpenBSD, print an error message when trying to push more than one label at once (kernel limitation). While here, add support for MPLSv6 FTNs in OpenBSD. This is not the full package. We still can't pop multiple labels at once, or do things like swap a label and push other ones. We'll address that in the future. Signed-off-by: Renato Westphal --- zebra/rt_socket.c | 48 ++++++++++++++++++++++++++++++-------- zebra/zebra_mpls.c | 31 ++++++++++-------------- zebra/zebra_mpls.h | 2 +- zebra/zebra_mpls_openbsd.c | 9 +++++++ zebra/zebra_static.h | 4 +++- 5 files changed, 63 insertions(+), 31 deletions(-) diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index 4e4d726b46..32ae41b917 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -71,6 +71,27 @@ static int sin_masklen(struct in_addr mask) } #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ +#ifdef __OpenBSD__ +static int kernel_rtm_add_labels(struct nexthop_label *nh_label, + struct sockaddr_mpls *smpls) +{ + if (nh_label->num_labels > 1) { + zlog_warn( + "%s: can't push %u labels at " + "once (maximum is 1)", + __func__, nh_label->num_labels); + return -1; + } + + memset(smpls, 0, sizeof(*smpls)); + smpls->smpls_len = sizeof(*smpls); + smpls->smpls_family = AF_MPLS; + smpls->smpls_label = htonl(nh_label->label[0] << MPLS_LABEL_OFFSET); + + return 0; +} +#endif + /* Interface between zebra message and rtm message. */ static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re) @@ -150,15 +171,11 @@ static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re) } #ifdef __OpenBSD__ - if (nexthop->nh_label) { - memset(&smpls, 0, sizeof(smpls)); - smpls.smpls_len = sizeof(smpls); - smpls.smpls_family = AF_MPLS; - smpls.smpls_label = - htonl(nexthop->nh_label->label[0] - << MPLS_LABEL_OFFSET); - smplsp = (union sockunion *)&smpls; - } + if (nexthop->nh_label + && !kernel_rtm_add_labels(nexthop->nh_label, + &smpls)) + continue; + smplsp = (union sockunion *)&smpls; #endif error = rtm_write( @@ -266,6 +283,10 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re) { struct sockaddr_in6 *mask; struct sockaddr_in6 sin_dest, sin_mask, sin_gate; +#ifdef __OpenBSD__ + struct sockaddr_mpls smpls; +#endif + union sockunion *smplsp = NULL; struct nexthop *nexthop; int nexthop_num = 0; ifindex_t ifindex = 0; @@ -338,10 +359,17 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re) mask = &sin_mask; } +#ifdef __OpenBSD__ + if (nexthop->nh_label + && !kernel_rtm_add_labels(nexthop->nh_label, &smpls)) + continue; + smplsp = (union sockunion *)&smpls; +#endif + error = rtm_write(cmd, (union sockunion *)&sin_dest, (union sockunion *)mask, gate ? (union sockunion *)&sin_gate : NULL, - NULL, ifindex, re->flags, re->metric); + smplsp, ifindex, re->flags, re->metric); #if 0 if (error) diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 47cf7a3cbf..cee3a03858 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -1671,27 +1671,20 @@ int mpls_str2label(const char *label_str, u_int8_t *num_labels, char *mpls_label2str(u_int8_t num_labels, mpls_label_t *labels, char *buf, int len, int pretty) { - char *buf_ptr = buf; + char label_buf[BUFSIZ]; + int i; + buf[0] = '\0'; - - if (pretty) { - if (num_labels == 1) { - label2str(labels[0], buf, len); - } else if (num_labels == 2) { - label2str(labels[0], buf, len); - buf_ptr += strlen(buf); - - snprintf(buf_ptr, len, "/"); - buf_ptr++; - - label2str(labels[1], buf_ptr, len); - } - } else { - if (num_labels == 1) - snprintf(buf, len, "%u", labels[0]); - else if (num_labels == 2) - snprintf(buf, len, "%u/%u", labels[0], labels[1]); + for (i = 0; i < num_labels; i++) { + if (i != 0) + strlcat(buf, "/", len); + if (pretty) + label2str(labels[i], label_buf, sizeof(label_buf)); + else + snprintf(label_buf, sizeof(label_buf), "%u", labels[i]); + strlcat(buf, label_buf, len); } + return buf; } diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h index c8dab39210..6bddc4d00f 100644 --- a/zebra/zebra_mpls.h +++ b/zebra/zebra_mpls.h @@ -37,7 +37,7 @@ /* Definitions and macros. */ -#define MPLS_MAX_LABELS 2 /* Maximum # labels that can be pushed. */ +#define MPLS_MAX_LABELS 16 /* Maximum # labels that can be pushed. */ #define NHLFE_FAMILY(nhlfe) \ (((nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6 \ diff --git a/zebra/zebra_mpls_openbsd.c b/zebra/zebra_mpls_openbsd.c index 119cd5b700..33f0d49d4d 100644 --- a/zebra/zebra_mpls_openbsd.c +++ b/zebra/zebra_mpls_openbsd.c @@ -256,6 +256,15 @@ static int kernel_lsp_cmd(int action, zebra_lsp_t *lsp) || (action == RTM_DELETE && (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED) && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)))) { + if (nhlfe->nexthop->nh_label->num_labels > 1) { + zlog_warn( + "%s: can't push %u labels at once " + "(maximum is 1)", + __func__, + nhlfe->nexthop->nh_label->num_labels); + continue; + } + nexthop_num++; switch (NHLFE_FAMILY(nhlfe)) { diff --git a/zebra/zebra_static.h b/zebra/zebra_static.h index 6ab47094a1..ff9f0f59e7 100644 --- a/zebra/zebra_static.h +++ b/zebra/zebra_static.h @@ -22,11 +22,13 @@ #ifndef __ZEBRA_STATIC_H__ #define __ZEBRA_STATIC_H__ +#include "zebra/zebra_mpls.h" + /* Static route label information */ struct static_nh_label { u_int8_t num_labels; u_int8_t reserved[3]; - mpls_label_t label[2]; + mpls_label_t label[MPLS_MAX_LABELS]; }; typedef enum { From 5ecf5540097c30ab0b02b3ac18133b17e660c9db Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 22 Aug 2017 20:09:26 -0300 Subject: [PATCH 12/79] bgpd: fix file descriptor leak Bug introduced by commit 37d361e7. Removing the call to bgp_close() from bgp_delete() was a mistake. Reported-by: Don Slice Signed-off-by: Renato Westphal --- bgpd/bgpd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 9d7c38c871..e3650417fa 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3087,6 +3087,8 @@ int bgp_delete(struct bgp *bgp) * routes to be processed still referencing the struct bgp. */ listnode_delete(bm->bgp, bgp); + if (list_isempty(bm->bgp)) + bgp_close(); /* Deregister from Zebra, if needed */ if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) From 9d1c2659293a757a672bf0aa0d2f5ca20a2b28e5 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 23 Aug 2017 15:48:36 +0200 Subject: [PATCH 13/79] zebra: don't print 0.0.0.0:0 for FPM config Fixes: #319 Signed-off-by: David Lamparter --- zebra/zebra_fpm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index b88bce9e82..8c0700ac8b 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -1589,8 +1589,10 @@ static int fpm_remote_srv_write(struct vty *vty) in.s_addr = zfpm_g->fpm_server; - if (zfpm_g->fpm_server != FPM_DEFAULT_IP - || zfpm_g->fpm_port != FPM_DEFAULT_PORT) + if ((zfpm_g->fpm_server != FPM_DEFAULT_IP + && zfpm_g->fpm_server != INADDR_ANY) + || (zfpm_g->fpm_port != FPM_DEFAULT_PORT + && zfpm_g->fpm_port != 0)) vty_out(vty, "fpm connection ip %s port %d\n", inet_ntoa(in), zfpm_g->fpm_port); From d00061ea32901096fa4c3af6b9e65914dd895031 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 12 Aug 2017 13:03:29 -0300 Subject: [PATCH 14/79] *: reduce excessive indentation in a few places Signed-off-by: Renato Westphal --- eigrpd/eigrp_zebra.c | 122 ++++++------- isisd/isis_zebra.c | 130 +++++++------- ospf6d/ospf6_zebra.c | 124 ++++++------- ospfd/ospf_zebra.c | 401 +++++++++++++++++++++---------------------- ripd/rip_zebra.c | 189 ++++++++++---------- ripngd/ripng_zebra.c | 177 ++++++++++--------- 6 files changed, 569 insertions(+), 574 deletions(-) diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index 1ee1237f75..00b269b489 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -398,81 +398,83 @@ void eigrp_zebra_route_add(struct prefix_ipv4 *p, struct list *successors) int psize; struct stream *s; - if (zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP]) { - message = 0; - flags = 0; + if (!zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP]) + return; - /* EIGRP pass nexthop and metric */ - SET_FLAG(message, ZAPI_MESSAGE_NEXTHOP); + message = 0; + flags = 0; - /* Make packet. */ - s = zclient->obuf; - stream_reset(s); + /* EIGRP pass nexthop and metric */ + SET_FLAG(message, ZAPI_MESSAGE_NEXTHOP); - /* Put command, type, flags, message. */ - zclient_create_header(s, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); - stream_putc(s, ZEBRA_ROUTE_EIGRP); - stream_putw(s, 0); - stream_putl(s, flags); - stream_putc(s, message); - stream_putw(s, SAFI_UNICAST); + /* Make packet. */ + s = zclient->obuf; + stream_reset(s); - /* Put prefix information. */ - psize = PSIZE(p->prefixlen); - stream_putc(s, p->prefixlen); - stream_write(s, (u_char *)&p->prefix, psize); + /* Put command, type, flags, message. */ + zclient_create_header(s, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); + stream_putc(s, ZEBRA_ROUTE_EIGRP); + stream_putw(s, 0); + stream_putl(s, flags); + stream_putc(s, message); + stream_putw(s, SAFI_UNICAST); - /* Nexthop count. */ - stream_putc(s, successors->count); + /* Put prefix information. */ + psize = PSIZE(p->prefixlen); + stream_putc(s, p->prefixlen); + stream_write(s, (u_char *)&p->prefix, psize); - /* Nexthop, ifindex, distance and metric information. */ - for (ALL_LIST_ELEMENTS_RO(successors, node, te)) { - if (te->adv_router->src.s_addr) { - stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr(s, &te->adv_router->src); - } else - stream_putc(s, NEXTHOP_TYPE_IFINDEX); - stream_putl(s, te->ei->ifp->ifindex); - } + /* Nexthop count. */ + stream_putc(s, successors->count); - if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug("Zebra: Route add %s/%d nexthop %s", - inet_ntop(AF_INET, &p->prefix, buf[0], - sizeof(buf[0])), - p->prefixlen, - inet_ntop(AF_INET, 0 /*&p->nexthop*/, buf[1], - sizeof(buf[1]))); - } - - stream_putw_at(s, 0, stream_get_endp(s)); - - zclient_send_message(zclient); + /* Nexthop, ifindex, distance and metric information. */ + for (ALL_LIST_ELEMENTS_RO(successors, node, te)) { + if (te->adv_router->src.s_addr) { + stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); + stream_put_in_addr(s, &te->adv_router->src); + } else + stream_putc(s, NEXTHOP_TYPE_IFINDEX); + stream_putl(s, te->ei->ifp->ifindex); } + + if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) { + char buf[2][INET_ADDRSTRLEN]; + zlog_debug("Zebra: Route add %s/%d nexthop %s", + inet_ntop(AF_INET, &p->prefix, buf[0], + sizeof(buf[0])), + p->prefixlen, + inet_ntop(AF_INET, 0 /*&p->nexthop*/, buf[1], + sizeof(buf[1]))); + } + + stream_putw_at(s, 0, stream_get_endp(s)); + + zclient_send_message(zclient); } void eigrp_zebra_route_delete(struct prefix_ipv4 *p) { struct zapi_ipv4 api; - if (zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP]) { - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_EIGRP; - api.instance = 0; - api.flags = 0; - api.message = 0; - api.safi = SAFI_UNICAST; - zapi_ipv4_route(ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api); + if (!zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP]) + return; - if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug("Zebra: Route del %s/%d nexthop %s", - inet_ntop(AF_INET, &p->prefix, buf[0], - sizeof(buf[0])), - p->prefixlen, - inet_ntop(AF_INET, 0 /*&p->nexthop*/, buf[1], - sizeof(buf[1]))); - } + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_EIGRP; + api.instance = 0; + api.flags = 0; + api.message = 0; + api.safi = SAFI_UNICAST; + zapi_ipv4_route(ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api); + + if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) { + char buf[2][INET_ADDRSTRLEN]; + zlog_debug("Zebra: Route del %s/%d nexthop %s", + inet_ntop(AF_INET, &p->prefix, buf[0], + sizeof(buf[0])), + p->prefixlen, + inet_ntop(AF_INET, 0 /*&p->nexthop*/, buf[1], + sizeof(buf[1]))); } return; diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 8c6968f8ec..c1d558fc22 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -258,63 +258,62 @@ static void isis_zebra_route_add_ipv4(struct prefix *prefix, if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) return; - if (vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], - VRF_DEFAULT)) { - message = 0; - flags = 0; + if (!vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], + VRF_DEFAULT)) + return; - SET_FLAG(message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG(message, ZAPI_MESSAGE_METRIC); + message = 0; + flags = 0; + + SET_FLAG(message, ZAPI_MESSAGE_NEXTHOP); + SET_FLAG(message, ZAPI_MESSAGE_METRIC); #if 0 - SET_FLAG (message, ZAPI_MESSAGE_DISTANCE); + SET_FLAG (message, ZAPI_MESSAGE_DISTANCE); #endif - stream = zclient->obuf; - stream_reset(stream); - zclient_create_header(stream, ZEBRA_IPV4_ROUTE_ADD, - VRF_DEFAULT); - /* type */ - stream_putc(stream, ZEBRA_ROUTE_ISIS); - /* instance */ - stream_putw(stream, 0); - /* flags */ - stream_putl(stream, flags); - /* message */ - stream_putc(stream, message); - /* SAFI */ - stream_putw(stream, SAFI_UNICAST); - /* prefix information */ - psize = PSIZE(prefix->prefixlen); - stream_putc(stream, prefix->prefixlen); - stream_write(stream, (u_char *)&prefix->u.prefix4, psize); + stream = zclient->obuf; + stream_reset(stream); + zclient_create_header(stream, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); + /* type */ + stream_putc(stream, ZEBRA_ROUTE_ISIS); + /* instance */ + stream_putw(stream, 0); + /* flags */ + stream_putl(stream, flags); + /* message */ + stream_putc(stream, message); + /* SAFI */ + stream_putw(stream, SAFI_UNICAST); + /* prefix information */ + psize = PSIZE(prefix->prefixlen); + stream_putc(stream, prefix->prefixlen); + stream_write(stream, (u_char *)&prefix->u.prefix4, psize); - stream_putc(stream, listcount(route_info->nexthops)); + stream_putc(stream, listcount(route_info->nexthops)); - /* Nexthop, ifindex, distance and metric information */ - for (ALL_LIST_ELEMENTS_RO(route_info->nexthops, node, - nexthop)) { - /* FIXME: can it be ? */ - if (nexthop->ip.s_addr != INADDR_ANY) { - stream_putc(stream, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr(stream, &nexthop->ip); - stream_putl(stream, nexthop->ifindex); - } else { - stream_putc(stream, NEXTHOP_TYPE_IFINDEX); - stream_putl(stream, nexthop->ifindex); - } + /* Nexthop, ifindex, distance and metric information */ + for (ALL_LIST_ELEMENTS_RO(route_info->nexthops, node, nexthop)) { + /* FIXME: can it be ? */ + if (nexthop->ip.s_addr != INADDR_ANY) { + stream_putc(stream, NEXTHOP_TYPE_IPV4_IFINDEX); + stream_put_in_addr(stream, &nexthop->ip); + stream_putl(stream, nexthop->ifindex); + } else { + stream_putc(stream, NEXTHOP_TYPE_IFINDEX); + stream_putl(stream, nexthop->ifindex); } -#if 0 - if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) - stream_putc (stream, route_info->depth); -#endif - if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) - stream_putl(stream, route_info->cost); - - stream_putw_at(stream, 0, stream_get_endp(stream)); - zclient_send_message(zclient); - SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); } +#if 0 + if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) + stream_putc (stream, route_info->depth); +#endif + if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) + stream_putl(stream, route_info->cost); + + stream_putw_at(stream, 0, stream_get_endp(stream)); + zclient_send_message(zclient); + SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); } static void isis_zebra_route_del_ipv4(struct prefix *prefix, @@ -323,23 +322,22 @@ static void isis_zebra_route_del_ipv4(struct prefix *prefix, struct zapi_ipv4 api; struct prefix_ipv4 prefix4; - if (vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], - VRF_DEFAULT)) { - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_ISIS; - api.instance = 0; - api.flags = 0; - api.message = 0; - api.safi = SAFI_UNICAST; - prefix4.family = AF_INET; - prefix4.prefixlen = prefix->prefixlen; - prefix4.prefix = prefix->u.prefix4; - zapi_ipv4_route(ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, - &api); - } UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - return; + if (!vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], + VRF_DEFAULT)) + return; + + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_ISIS; + api.instance = 0; + api.flags = 0; + api.message = 0; + api.safi = SAFI_UNICAST; + prefix4.family = AF_INET; + prefix4.prefixlen = prefix->prefixlen; + prefix4.prefix = prefix->u.prefix4; + zapi_ipv4_route(ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api); } static void isis_zebra_route_add_ipv6(struct prefix *prefix, @@ -367,8 +365,8 @@ static void isis_zebra_route_add_ipv6(struct prefix *prefix, SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); api.metric = route_info->cost; #if 0 - SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); - api.distance = route_info->depth; + SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); + api.distance = route_info->depth; #endif api.nexthop_num = listcount(route_info->nexthops6); api.ifindex_num = listcount(route_info->nexthops6); diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index d33f41730e..dc97f1ff4b 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -497,40 +497,42 @@ void ospf6_zebra_add_discard(struct ospf6_route *request) char buf[INET6_ADDRSTRLEN]; struct prefix_ipv6 *dest; - if (vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT)) { - if (!CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_OSPF6; - api.flags = ZEBRA_FLAG_BLACKHOLE; - api.instance = 0; - api.message = 0; - api.safi = SAFI_UNICAST; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.ifindex_num = 0; + if (!vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], + VRF_DEFAULT)) + return; - dest = (struct prefix_ipv6 *)&request->prefix; + if (!CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_OSPF6; + api.flags = ZEBRA_FLAG_BLACKHOLE; + api.instance = 0; + api.message = 0; + api.safi = SAFI_UNICAST; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 0; + api.ifindex_num = 0; - zapi_ipv6_route(ZEBRA_IPV6_ROUTE_ADD, zclient, dest, - NULL, &api); + dest = (struct prefix_ipv6 *)&request->prefix; - if (IS_OSPF6_DEBUG_ZEBRA(SEND)) - zlog_debug("Zebra: Route add discard %s/%d", - inet_ntop(AF_INET6, &dest->prefix, - buf, INET6_ADDRSTRLEN), - dest->prefixlen); - SET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED); - } else { - dest = (struct prefix_ipv6 *)&request->prefix; + zapi_ipv6_route(ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, + &api); - if (IS_OSPF6_DEBUG_ZEBRA(SEND)) - zlog_debug( - "Zebra: Blackhole route present already %s/%d", - inet_ntop(AF_INET6, &dest->prefix, buf, - INET6_ADDRSTRLEN), - dest->prefixlen); - } + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug("Zebra: Route add discard %s/%d", + inet_ntop(AF_INET6, &dest->prefix, buf, + INET6_ADDRSTRLEN), + dest->prefixlen); + + SET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED); + } else { + dest = (struct prefix_ipv6 *)&request->prefix; + + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug( + "Zebra: Blackhole route present already %s/%d", + inet_ntop(AF_INET6, &dest->prefix, buf, + INET6_ADDRSTRLEN), + dest->prefixlen); } } @@ -540,39 +542,41 @@ void ospf6_zebra_delete_discard(struct ospf6_route *request) char buf[INET6_ADDRSTRLEN]; struct prefix_ipv6 *dest; - if (vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT)) { - if (CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_OSPF6; - api.flags = ZEBRA_FLAG_BLACKHOLE; - api.instance = 0; - api.message = 0; - api.safi = SAFI_UNICAST; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.ifindex_num = 0; + if (!vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], + VRF_DEFAULT)) + return; - dest = (struct prefix_ipv6 *)&request->prefix; + if (CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_OSPF6; + api.flags = ZEBRA_FLAG_BLACKHOLE; + api.instance = 0; + api.message = 0; + api.safi = SAFI_UNICAST; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 0; + api.ifindex_num = 0; - zapi_ipv6_route(ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, - NULL, &api); + dest = (struct prefix_ipv6 *)&request->prefix; - if (IS_OSPF6_DEBUG_ZEBRA(SEND)) - zlog_debug("Zebra: Route delete discard %s/%d", - inet_ntop(AF_INET6, &dest->prefix, - buf, INET6_ADDRSTRLEN), - dest->prefixlen); - UNSET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED); - } else { - dest = (struct prefix_ipv6 *)&request->prefix; - if (IS_OSPF6_DEBUG_ZEBRA(SEND)) - zlog_debug( - "Zebra: Blackhole route already deleted %s/%d", - inet_ntop(AF_INET6, &dest->prefix, buf, - INET6_ADDRSTRLEN), - dest->prefixlen); - } + zapi_ipv6_route(ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, NULL, + &api); + + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug("Zebra: Route delete discard %s/%d", + inet_ntop(AF_INET6, &dest->prefix, buf, + INET6_ADDRSTRLEN), + dest->prefixlen); + + UNSET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED); + } else { + dest = (struct prefix_ipv6 *)&request->prefix; + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug( + "Zebra: Blackhole route already deleted %s/%d", + inet_ntop(AF_INET6, &dest->prefix, buf, + INET6_ADDRSTRLEN), + dest->prefixlen); } } diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index d615afc072..f9668f2495 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -342,118 +342,116 @@ void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or) struct listnode *node; struct ospf *ospf = ospf_lookup(); - if ((ospf->instance - && redist_check_instance( - &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], - ospf->instance)) - || vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], - VRF_DEFAULT)) { - message = 0; - flags = 0; + if (!(ospf->instance + && redist_check_instance( + &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], + ospf->instance)) + && !vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], + VRF_DEFAULT)) + return; - /* OSPF pass nexthop and metric */ - SET_FLAG(message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG(message, ZAPI_MESSAGE_METRIC); + message = 0; + flags = 0; - /* Distance value. */ - distance = ospf_distance_apply(p, or); - if (distance) - SET_FLAG(message, ZAPI_MESSAGE_DISTANCE); + /* OSPF pass nexthop and metric */ + SET_FLAG(message, ZAPI_MESSAGE_NEXTHOP); + SET_FLAG(message, ZAPI_MESSAGE_METRIC); - /* Check if path type is ASE */ - if (((or->path_type == OSPF_PATH_TYPE1_EXTERNAL) - || (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)) - && (or->u.ext.tag > 0) && (or->u.ext.tag <= ROUTE_TAG_MAX)) - SET_FLAG(message, ZAPI_MESSAGE_TAG); + /* Distance value. */ + distance = ospf_distance_apply(p, or); + if (distance) + SET_FLAG(message, ZAPI_MESSAGE_DISTANCE); - /* Make packet. */ - s = zclient->obuf; - stream_reset(s); + /* Check if path type is ASE */ + if (((or->path_type == OSPF_PATH_TYPE1_EXTERNAL) + || (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)) + && (or->u.ext.tag > 0) && (or->u.ext.tag <= ROUTE_TAG_MAX)) + SET_FLAG(message, ZAPI_MESSAGE_TAG); - /* Put command, type, flags, message. */ - zclient_create_header(s, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); - stream_putc(s, ZEBRA_ROUTE_OSPF); - stream_putw(s, ospf->instance); - stream_putl(s, flags); - stream_putc(s, message); - stream_putw(s, SAFI_UNICAST); + /* Make packet. */ + s = zclient->obuf; + stream_reset(s); - /* Put prefix information. */ - psize = PSIZE(p->prefixlen); - stream_putc(s, p->prefixlen); - stream_write(s, (u_char *)&p->prefix, psize); + /* Put command, type, flags, message. */ + zclient_create_header(s, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); + stream_putc(s, ZEBRA_ROUTE_OSPF); + stream_putw(s, ospf->instance); + stream_putl(s, flags); + stream_putc(s, message); + stream_putw(s, SAFI_UNICAST); - /* Nexthop count. */ - stream_putc(s, or->paths->count); + /* Put prefix information. */ + psize = PSIZE(p->prefixlen); + stream_putc(s, p->prefixlen); + stream_write(s, (u_char *)&p->prefix, psize); - /* Nexthop, ifindex, distance and metric information. */ - for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) { + /* Nexthop count. */ + stream_putc(s, or->paths->count); + + /* Nexthop, ifindex, distance and metric information. */ + for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) { #ifdef HAVE_NETLINK - if (path->unnumbered - || (path->nexthop.s_addr != INADDR_ANY - && path->ifindex != 0)) { - stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr(s, &path->nexthop); + if (path->unnumbered || (path->nexthop.s_addr != INADDR_ANY + && path->ifindex != 0)) { + stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); + stream_put_in_addr(s, &path->nexthop); + stream_putl(s, path->ifindex); + } else if (path->nexthop.s_addr != INADDR_ANY) { + stream_putc(s, NEXTHOP_TYPE_IPV4); + stream_put_in_addr(s, &path->nexthop); + } else { + stream_putc(s, NEXTHOP_TYPE_IFINDEX); + if (path->ifindex) stream_putl(s, path->ifindex); - } else if (path->nexthop.s_addr != INADDR_ANY) { - stream_putc(s, NEXTHOP_TYPE_IPV4); - stream_put_in_addr(s, &path->nexthop); - } else { - stream_putc(s, NEXTHOP_TYPE_IFINDEX); - if (path->ifindex) - stream_putl(s, path->ifindex); - else - stream_putl(s, 0); - } + else + stream_putl(s, 0); + } #else /* HAVE_NETLINK */ - if (path->nexthop.s_addr != INADDR_ANY - && path->ifindex != 0) { - stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr(s, &path->nexthop); + if (path->nexthop.s_addr != INADDR_ANY && path->ifindex != 0) { + stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); + stream_put_in_addr(s, &path->nexthop); + stream_putl(s, path->ifindex); + } else if (path->nexthop.s_addr != INADDR_ANY) { + stream_putc(s, NEXTHOP_TYPE_IPV4); + stream_put_in_addr(s, &path->nexthop); + } else { + stream_putc(s, NEXTHOP_TYPE_IFINDEX); + if (path->ifindex) stream_putl(s, path->ifindex); - } else if (path->nexthop.s_addr != INADDR_ANY) { - stream_putc(s, NEXTHOP_TYPE_IPV4); - stream_put_in_addr(s, &path->nexthop); - } else { - stream_putc(s, NEXTHOP_TYPE_IFINDEX); - if (path->ifindex) - stream_putl(s, path->ifindex); - else - stream_putl(s, 0); - } + else + stream_putl(s, 0); + } #endif /* HAVE_NETLINK */ - if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug( - "Zebra: Route add %s/%d nexthop %s, ifindex=%d", - inet_ntop(AF_INET, &p->prefix, buf[0], - sizeof(buf[0])), - p->prefixlen, - inet_ntop(AF_INET, &path->nexthop, - buf[1], sizeof(buf[1])), - path->ifindex); - } + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { + char buf[2][INET_ADDRSTRLEN]; + zlog_debug( + "Zebra: Route add %s/%d nexthop %s, ifindex=%d", + inet_ntop(AF_INET, &p->prefix, buf[0], + sizeof(buf[0])), + p->prefixlen, inet_ntop(AF_INET, &path->nexthop, + buf[1], sizeof(buf[1])), + path->ifindex); } - - if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) - stream_putc(s, distance); - if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) { - if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL) - stream_putl(s, or->cost + or->u.ext.type2_cost); - else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL) - stream_putl(s, or->u.ext.type2_cost); - else - stream_putl(s, or->cost); - } - - if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG)) - stream_putl(s, or->u.ext.tag); - - stream_putw_at(s, 0, stream_get_endp(s)); - - zclient_send_message(zclient); } + + if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) + stream_putc(s, distance); + if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) { + if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL) + stream_putl(s, or->cost + or->u.ext.type2_cost); + else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL) + stream_putl(s, or->u.ext.type2_cost); + else + stream_putl(s, or->cost); + } + + if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG)) + stream_putl(s, or->u.ext.tag); + + stream_putw_at(s, 0, stream_get_endp(s)); + + zclient_send_message(zclient); } void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or) @@ -467,78 +465,77 @@ void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or) struct listnode *node; struct ospf *ospf = ospf_lookup(); - if ((ospf->instance - && redist_check_instance( - &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], - ospf->instance)) - || vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], - VRF_DEFAULT)) { - message = 0; - flags = 0; - /* Distance value. */ - distance = ospf_distance_apply(p, or); - /* Make packet. */ - s = zclient->obuf; - stream_reset(s); + if (!(ospf->instance + && redist_check_instance( + &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], + ospf->instance)) + && !vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], + VRF_DEFAULT)) + return; - /* Put command, type, flags, message. */ - zclient_create_header(s, ZEBRA_IPV4_ROUTE_DELETE, VRF_DEFAULT); - stream_putc(s, ZEBRA_ROUTE_OSPF); - stream_putw(s, ospf->instance); - stream_putl(s, flags); - stream_putc(s, message); - stream_putw(s, SAFI_UNICAST); + message = 0; + flags = 0; + /* Distance value. */ + distance = ospf_distance_apply(p, or); + /* Make packet. */ + s = zclient->obuf; + stream_reset(s); - /* Put prefix information. */ - psize = PSIZE(p->prefixlen); - stream_putc(s, p->prefixlen); - stream_write(s, (u_char *)&p->prefix, psize); + /* Put command, type, flags, message. */ + zclient_create_header(s, ZEBRA_IPV4_ROUTE_DELETE, VRF_DEFAULT); + stream_putc(s, ZEBRA_ROUTE_OSPF); + stream_putw(s, ospf->instance); + stream_putl(s, flags); + stream_putc(s, message); + stream_putw(s, SAFI_UNICAST); - /* Nexthop count. */ - stream_putc(s, or->paths->count); + /* Put prefix information. */ + psize = PSIZE(p->prefixlen); + stream_putc(s, p->prefixlen); + stream_write(s, (u_char *)&p->prefix, psize); - /* Nexthop, ifindex, distance and metric information. */ - for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) { - if (path->nexthop.s_addr != INADDR_ANY - && path->ifindex != 0) { - stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr(s, &path->nexthop); - stream_putl(s, path->ifindex); - } else if (path->nexthop.s_addr != INADDR_ANY) { - stream_putc(s, NEXTHOP_TYPE_IPV4); - stream_put_in_addr(s, &path->nexthop); - } else { - stream_putc(s, NEXTHOP_TYPE_IFINDEX); - stream_putl(s, path->ifindex); - } + /* Nexthop count. */ + stream_putc(s, or->paths->count); - if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug( - "Zebra: Route delete %s/%d nexthop %s", - inet_ntop(AF_INET, &p->prefix, buf[0], - sizeof(buf[0])), - p->prefixlen, - inet_ntop(AF_INET, &path->nexthop, - buf[1], sizeof(buf[1]))); - } + /* Nexthop, ifindex, distance and metric information. */ + for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) { + if (path->nexthop.s_addr != INADDR_ANY && path->ifindex != 0) { + stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); + stream_put_in_addr(s, &path->nexthop); + stream_putl(s, path->ifindex); + } else if (path->nexthop.s_addr != INADDR_ANY) { + stream_putc(s, NEXTHOP_TYPE_IPV4); + stream_put_in_addr(s, &path->nexthop); + } else { + stream_putc(s, NEXTHOP_TYPE_IFINDEX); + stream_putl(s, path->ifindex); } - if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) - stream_putc(s, distance); - if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) { - if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL) - stream_putl(s, or->cost + or->u.ext.type2_cost); - else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL) - stream_putl(s, or->u.ext.type2_cost); - else - stream_putl(s, or->cost); + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { + char buf[2][INET_ADDRSTRLEN]; + zlog_debug("Zebra: Route delete %s/%d nexthop %s", + inet_ntop(AF_INET, &p->prefix, buf[0], + sizeof(buf[0])), + p->prefixlen, + inet_ntop(AF_INET, &path->nexthop, buf[1], + sizeof(buf[1]))); } - - stream_putw_at(s, 0, stream_get_endp(s)); - - zclient_send_message(zclient); } + + if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) + stream_putc(s, distance); + if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) { + if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL) + stream_putl(s, or->cost + or->u.ext.type2_cost); + else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL) + stream_putl(s, or->u.ext.type2_cost); + else + stream_putl(s, or->cost); + } + + stream_putw_at(s, 0, stream_get_endp(s)); + + zclient_send_message(zclient); } void ospf_zebra_add_discard(struct prefix_ipv4 *p) @@ -546,29 +543,30 @@ void ospf_zebra_add_discard(struct prefix_ipv4 *p) struct zapi_ipv4 api; struct ospf *ospf = ospf_lookup(); - if ((ospf->instance - && redist_check_instance( - &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], - ospf->instance)) - || vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], - VRF_DEFAULT)) { - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_OSPF; - api.instance = ospf->instance; - api.flags = ZEBRA_FLAG_BLACKHOLE; - api.message = 0; - api.safi = SAFI_UNICAST; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.ifindex_num = 0; - api.tag = 0; + if (!(ospf->instance + && redist_check_instance( + &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], + ospf->instance)) + && !vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], + VRF_DEFAULT)) + return; - zapi_ipv4_route(ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api); + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_OSPF; + api.instance = ospf->instance; + api.flags = ZEBRA_FLAG_BLACKHOLE; + api.message = 0; + api.safi = SAFI_UNICAST; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 0; + api.ifindex_num = 0; + api.tag = 0; - if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug("Zebra: Route add discard %s/%d", - inet_ntoa(p->prefix), p->prefixlen); - } + zapi_ipv4_route(ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api); + + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug("Zebra: Route add discard %s/%d", + inet_ntoa(p->prefix), p->prefixlen); } void ospf_zebra_delete_discard(struct prefix_ipv4 *p) @@ -576,29 +574,30 @@ void ospf_zebra_delete_discard(struct prefix_ipv4 *p) struct zapi_ipv4 api; struct ospf *ospf = ospf_lookup(); - if ((ospf->instance - && redist_check_instance( - &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], - ospf->instance)) - || vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], - VRF_DEFAULT)) { - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_OSPF; - api.instance = ospf->instance; - api.flags = ZEBRA_FLAG_BLACKHOLE; - api.message = 0; - api.safi = SAFI_UNICAST; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.ifindex_num = 0; - api.tag = 0; + if (!(ospf->instance + && redist_check_instance( + &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], + ospf->instance)) + && !vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], + VRF_DEFAULT)) + return; - zapi_ipv4_route(ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api); + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_OSPF; + api.instance = ospf->instance; + api.flags = ZEBRA_FLAG_BLACKHOLE; + api.message = 0; + api.safi = SAFI_UNICAST; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 0; + api.ifindex_num = 0; + api.tag = 0; - if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug("Zebra: Route delete discard %s/%d", - inet_ntoa(p->prefix), p->prefixlen); - } + zapi_ipv4_route(ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api); + + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug("Zebra: Route delete discard %s/%d", + inet_ntoa(p->prefix), p->prefixlen); } struct ospf_external *ospf_external_lookup(u_char type, u_short instance) diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index 961a846db2..8a166745ec 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -48,73 +48,70 @@ static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd) struct rip_info *rinfo = NULL; int count = 0; - if (vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], - VRF_DEFAULT)) { - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_RIP; - api.instance = 0; - api.flags = 0; - api.message = 0; - api.safi = SAFI_UNICAST; + if (!vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], + VRF_DEFAULT)) + return; - if (nexthops_len < listcount(list)) { - nexthops_len = listcount(list); - nexthops = XREALLOC(MTYPE_TMP, nexthops, - nexthops_len - * sizeof(struct in_addr *)); - } + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_RIP; + api.instance = 0; + api.flags = 0; + api.message = 0; + api.safi = SAFI_UNICAST; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { - nexthops[count++] = &rinfo->nexthop; - if (cmd == ZEBRA_IPV4_ROUTE_ADD) - SET_FLAG(rinfo->flags, RIP_RTF_FIB); - else - UNSET_FLAG(rinfo->flags, RIP_RTF_FIB); - } - - api.nexthop = nexthops; - api.nexthop_num = count; - api.ifindex_num = 0; - - rinfo = listgetdata(listhead(list)); - - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = rinfo->metric; - - if (rinfo->distance - && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT) { - SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); - api.distance = rinfo->distance; - } - - if (rinfo->tag) { - SET_FLAG(api.message, ZAPI_MESSAGE_TAG); - api.tag = rinfo->tag; - } - - zapi_ipv4_route(cmd, zclient, (struct prefix_ipv4 *)&rp->p, - &api); - - if (IS_RIP_DEBUG_ZEBRA) { - if (rip->ecmp) - zlog_debug("%s: %s/%d nexthops %d", - (cmd == ZEBRA_IPV4_ROUTE_ADD) - ? "Install into zebra" - : "Delete from zebra", - inet_ntoa(rp->p.u.prefix4), - rp->p.prefixlen, count); - else - zlog_debug("%s: %s/%d", - (cmd == ZEBRA_IPV4_ROUTE_ADD) - ? "Install into zebra" - : "Delete from zebra", - inet_ntoa(rp->p.u.prefix4), - rp->p.prefixlen); - } - - rip_global_route_changes++; + if (nexthops_len < listcount(list)) { + nexthops_len = listcount(list); + nexthops = XREALLOC(MTYPE_TMP, nexthops, + nexthops_len * sizeof(struct in_addr *)); } + + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { + nexthops[count++] = &rinfo->nexthop; + if (cmd == ZEBRA_IPV4_ROUTE_ADD) + SET_FLAG(rinfo->flags, RIP_RTF_FIB); + else + UNSET_FLAG(rinfo->flags, RIP_RTF_FIB); + } + + api.nexthop = nexthops; + api.nexthop_num = count; + api.ifindex_num = 0; + + rinfo = listgetdata(listhead(list)); + + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = rinfo->metric; + + if (rinfo->distance && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT) { + SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); + api.distance = rinfo->distance; + } + + if (rinfo->tag) { + SET_FLAG(api.message, ZAPI_MESSAGE_TAG); + api.tag = rinfo->tag; + } + + zapi_ipv4_route(cmd, zclient, (struct prefix_ipv4 *)&rp->p, &api); + + if (IS_RIP_DEBUG_ZEBRA) { + if (rip->ecmp) + zlog_debug("%s: %s/%d nexthops %d", + (cmd == ZEBRA_IPV4_ROUTE_ADD) + ? "Install into zebra" + : "Delete from zebra", + inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen, + count); + else + zlog_debug("%s: %s/%d", + (cmd == ZEBRA_IPV4_ROUTE_ADD) + ? "Install into zebra" + : "Delete from zebra", + inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen); + } + + rip_global_route_changes++; } /* Add/update ECMP routes to zebra. */ @@ -623,39 +620,39 @@ int config_write_rip_redistribute(struct vty *vty, int config_mode) { int i; - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - if (i != zclient->redist_default - && vrf_bitmap_check(zclient->redist[AFI_IP][i], - VRF_DEFAULT)) { - if (config_mode) { - if (rip->route_map[i].metric_config) { - if (rip->route_map[i].name) - vty_out(vty, - " redistribute %s metric %d route-map %s\n", - zebra_route_string(i), - rip->route_map[i] - .metric, - rip->route_map[i].name); - else - vty_out(vty, - " redistribute %s metric %d\n", - zebra_route_string(i), - rip->route_map[i] - .metric); - } else { - if (rip->route_map[i].name) - vty_out(vty, - " redistribute %s route-map %s\n", - zebra_route_string(i), - rip->route_map[i].name); - else - vty_out(vty, - " redistribute %s\n", - zebra_route_string(i)); - } - } else - vty_out(vty, " %s", zebra_route_string(i)); + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { + if (i == zclient->redist_default + || !vrf_bitmap_check(zclient->redist[AFI_IP][i], + VRF_DEFAULT)) + continue; + + if (!config_mode) { + vty_out(vty, " %s", zebra_route_string(i)); + continue; } + + if (rip->route_map[i].metric_config) { + if (rip->route_map[i].name) + vty_out(vty, + " redistribute %s metric %d route-map %s\n", + zebra_route_string(i), + rip->route_map[i].metric, + rip->route_map[i].name); + else + vty_out(vty, " redistribute %s metric %d\n", + zebra_route_string(i), + rip->route_map[i].metric); + } else { + if (rip->route_map[i].name) + vty_out(vty, " redistribute %s route-map %s\n", + zebra_route_string(i), + rip->route_map[i].name); + else + vty_out(vty, " redistribute %s\n", + zebra_route_string(i)); + } + } + return 0; } diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index 386bee43b8..875ec4f225 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -49,71 +49,69 @@ static void ripng_zebra_ipv6_send(struct route_node *rp, u_char cmd) struct ripng_info *rinfo = NULL; int count = 0; - if (vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_RIPNG], - VRF_DEFAULT)) { - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_RIPNG; - api.instance = 0; - api.flags = 0; - api.message = 0; - api.safi = SAFI_UNICAST; + if (!vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_RIPNG], + VRF_DEFAULT)) + return; - if (nexthops_len < listcount(list)) { - nexthops_len = listcount(list); - nexthops = XREALLOC( - MTYPE_TMP, nexthops, - nexthops_len * sizeof(struct in6_addr *)); - ifindexes = - XREALLOC(MTYPE_TMP, ifindexes, - nexthops_len * sizeof(unsigned int)); - } + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_RIPNG; + api.instance = 0; + api.flags = 0; + api.message = 0; + api.safi = SAFI_UNICAST; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); - for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { - nexthops[count] = &rinfo->nexthop; - ifindexes[count] = rinfo->ifindex; - count++; - if (cmd == ZEBRA_IPV6_ROUTE_ADD) - SET_FLAG(rinfo->flags, RIPNG_RTF_FIB); - else - UNSET_FLAG(rinfo->flags, RIPNG_RTF_FIB); - } + if (nexthops_len < listcount(list)) { + nexthops_len = listcount(list); + nexthops = XREALLOC(MTYPE_TMP, nexthops, + nexthops_len * sizeof(struct in6_addr *)); + ifindexes = XREALLOC(MTYPE_TMP, ifindexes, + nexthops_len * sizeof(unsigned int)); + } - api.nexthop = nexthops; - api.nexthop_num = count; - api.ifindex = ifindexes; - api.ifindex_num = count; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); + for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { + nexthops[count] = &rinfo->nexthop; + ifindexes[count] = rinfo->ifindex; + count++; + if (cmd == ZEBRA_IPV6_ROUTE_ADD) + SET_FLAG(rinfo->flags, RIPNG_RTF_FIB); + else + UNSET_FLAG(rinfo->flags, RIPNG_RTF_FIB); + } - rinfo = listgetdata(listhead(list)); + api.nexthop = nexthops; + api.nexthop_num = count; + api.ifindex = ifindexes; + api.ifindex_num = count; - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = rinfo->metric; + rinfo = listgetdata(listhead(list)); - if (rinfo->tag) { - SET_FLAG(api.message, ZAPI_MESSAGE_TAG); - api.tag = rinfo->tag; - } + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = rinfo->metric; - zapi_ipv6_route(cmd, zclient, (struct prefix_ipv6 *)&rp->p, - NULL, &api); + if (rinfo->tag) { + SET_FLAG(api.message, ZAPI_MESSAGE_TAG); + api.tag = rinfo->tag; + } - if (IS_RIPNG_DEBUG_ZEBRA) { - if (ripng->ecmp) - zlog_debug("%s: %s/%d nexthops %d", - (cmd == ZEBRA_IPV6_ROUTE_ADD) - ? "Install into zebra" - : "Delete from zebra", - inet6_ntoa(rp->p.u.prefix6), - rp->p.prefixlen, count); - else - zlog_debug("%s: %s/%d", - (cmd == ZEBRA_IPV6_ROUTE_ADD) - ? "Install into zebra" - : "Delete from zebra", - inet6_ntoa(rp->p.u.prefix6), - rp->p.prefixlen); - } + zapi_ipv6_route(cmd, zclient, (struct prefix_ipv6 *)&rp->p, NULL, &api); + + if (IS_RIPNG_DEBUG_ZEBRA) { + if (ripng->ecmp) + zlog_debug("%s: %s/%d nexthops %d", + (cmd == ZEBRA_IPV6_ROUTE_ADD) + ? "Install into zebra" + : "Delete from zebra", + inet6_ntoa(rp->p.u.prefix6), rp->p.prefixlen, + count); + else + zlog_debug("%s: %s/%d", + (cmd == ZEBRA_IPV6_ROUTE_ADD) + ? "Install into zebra" + : "Delete from zebra", + inet6_ntoa(rp->p.u.prefix6), + rp->p.prefixlen); } } @@ -452,41 +450,38 @@ void ripng_redistribute_write(struct vty *vty, int config_mode) { int i; - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - if (i != zclient->redist_default - && vrf_bitmap_check(zclient->redist[AFI_IP6][i], - VRF_DEFAULT)) { - if (config_mode) { - if (ripng->route_map[i].metric_config) { - if (ripng->route_map[i].name) - vty_out(vty, - " redistribute %s metric %d route-map %s\n", - zebra_route_string(i), - ripng->route_map[i] - .metric, - ripng->route_map[i] - .name); - else - vty_out(vty, - " redistribute %s metric %d\n", - zebra_route_string(i), - ripng->route_map[i] - .metric); - } else { - if (ripng->route_map[i].name) - vty_out(vty, - " redistribute %s route-map %s\n", - zebra_route_string(i), - ripng->route_map[i] - .name); - else - vty_out(vty, - " redistribute %s\n", - zebra_route_string(i)); - } - } else - vty_out(vty, " %s", zebra_route_string(i)); + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { + if (i == zclient->redist_default + || !vrf_bitmap_check(zclient->redist[AFI_IP6][i], + VRF_DEFAULT)) + continue; + + if (!config_mode) { + vty_out(vty, " %s", zebra_route_string(i)); + continue; } + + if (ripng->route_map[i].metric_config) { + if (ripng->route_map[i].name) + vty_out(vty, + " redistribute %s metric %d route-map %s\n", + zebra_route_string(i), + ripng->route_map[i].metric, + ripng->route_map[i].name); + else + vty_out(vty, " redistribute %s metric %d\n", + zebra_route_string(i), + ripng->route_map[i].metric); + } else { + if (ripng->route_map[i].name) + vty_out(vty, " redistribute %s route-map %s\n", + zebra_route_string(i), + ripng->route_map[i].name); + else + vty_out(vty, " redistribute %s\n", + zebra_route_string(i)); + } + } } /* RIPng configuration write function. */ From 153856bbe96ea6b78aa0cc184ba6f4def7aace04 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 19 Aug 2017 11:20:42 -0300 Subject: [PATCH 15/79] lib: remove redundant zebra messages This also fixes a bug of ipv6 routes advertised by the VNC code being ignored by zebra. Signed-off-by: Renato Westphal --- bgpd/rfapi/vnc_zebra.c | 8 ++++---- lib/log.c | 4 ---- lib/zclient.h | 4 ---- zebra/zserv.c | 8 -------- 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index 3075d4109f..8f4a550bde 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -527,8 +527,8 @@ static void vnc_zebra_route_msg(struct prefix *p, int nhp_count, void *nhp_ary, p->prefixlen, nhp_count); } - zapi_ipv4_route((add ? ZEBRA_IPV4_NEXTHOP_ADD - : ZEBRA_IPV4_NEXTHOP_DELETE), + zapi_ipv4_route((add ? ZEBRA_IPV4_ROUTE_ADD + : ZEBRA_IPV4_ROUTE_DELETE), zclient_vnc, (struct prefix_ipv4 *)p, &api); } else if (p->family == AF_INET6) { @@ -561,8 +561,8 @@ static void vnc_zebra_route_msg(struct prefix *p, int nhp_count, void *nhp_ary, p->prefixlen, nhp_count); } - zapi_ipv6_route((add ? ZEBRA_IPV6_NEXTHOP_ADD - : ZEBRA_IPV6_NEXTHOP_DELETE), + zapi_ipv6_route((add ? ZEBRA_IPV6_ROUTE_ADD + : ZEBRA_IPV6_ROUTE_DELETE), zclient_vnc, (struct prefix_ipv6 *)p, NULL, &api); } else { diff --git a/lib/log.c b/lib/log.c index 5c89e7080e..b9ce9e69bc 100644 --- a/lib/log.c +++ b/lib/log.c @@ -908,10 +908,6 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_INTERFACE_LINK_PARAMS), DESC_ENTRY(ZEBRA_MPLS_LABELS_ADD), DESC_ENTRY(ZEBRA_MPLS_LABELS_DELETE), - DESC_ENTRY(ZEBRA_IPV4_NEXTHOP_ADD), - DESC_ENTRY(ZEBRA_IPV4_NEXTHOP_DELETE), - DESC_ENTRY(ZEBRA_IPV6_NEXTHOP_ADD), - DESC_ENTRY(ZEBRA_IPV6_NEXTHOP_DELETE), DESC_ENTRY(ZEBRA_IPMR_ROUTE_STATS), DESC_ENTRY(ZEBRA_LABEL_MANAGER_CONNECT), DESC_ENTRY(ZEBRA_GET_LABEL_CHUNK), diff --git a/lib/zclient.h b/lib/zclient.h index 15d1858d84..0218c1b732 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -100,10 +100,6 @@ typedef enum { ZEBRA_INTERFACE_LINK_PARAMS, ZEBRA_MPLS_LABELS_ADD, ZEBRA_MPLS_LABELS_DELETE, - ZEBRA_IPV4_NEXTHOP_ADD, - ZEBRA_IPV4_NEXTHOP_DELETE, - ZEBRA_IPV6_NEXTHOP_ADD, - ZEBRA_IPV6_NEXTHOP_DELETE, ZEBRA_IPMR_ROUTE_STATS, ZEBRA_LABEL_MANAGER_CONNECT, ZEBRA_GET_LABEL_CHUNK, diff --git a/zebra/zserv.c b/zebra/zserv.c index cd893b5670..aa7189fe89 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2444,14 +2444,6 @@ static int zebra_client_read(struct thread *thread) case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD: zread_ipv4_route_ipv6_nexthop_add(client, length, zvrf); break; - case ZEBRA_IPV4_NEXTHOP_ADD: - zread_ipv4_add(client, length, - zvrf); /* LB: r1.0 merge - id was 1 */ - break; - case ZEBRA_IPV4_NEXTHOP_DELETE: - zread_ipv4_delete(client, length, - zvrf); /* LB: r1.0 merge - id was 1 */ - break; case ZEBRA_IPV6_ROUTE_ADD: zread_ipv6_add(client, length, zvrf); break; From 89a8b5cada731a52f71167b7e4faa8a7028374c6 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 19 Aug 2017 11:28:21 -0300 Subject: [PATCH 16/79] vnc/eigrpd/isisd: check for the correct message types Signed-off-by: Renato Westphal --- bgpd/rfapi/vnc_zebra.c | 4 ++-- eigrpd/eigrp_zebra.c | 4 ++-- isisd/isis_zebra.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index 8f4a550bde..29652e59db 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -367,7 +367,7 @@ static int vnc_zebra_read_ipv4(int command, struct zclient *zclient, else api.metric = 0; - if (command == ZEBRA_IPV4_ROUTE_ADD) { + if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) { if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET_ADDRSTRLEN]; vnc_zlog_debug_verbose( @@ -456,7 +456,7 @@ static int vnc_zebra_read_ipv6(int command, struct zclient *zclient, if (IN6_IS_ADDR_LINKLOCAL(&p.prefix)) return 0; - if (command == ZEBRA_IPV6_ROUTE_ADD) { + if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) { if (BGP_DEBUG(zebra, ZEBRA)) { char buf[INET6_ADDRSTRLEN]; vnc_zlog_debug_verbose( diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index 00b269b489..0ee89eb675 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -162,9 +162,9 @@ static int eigrp_zebra_read_ipv4(int command, struct zclient *zclient, if (eigrp == NULL) return 0; - if (command == ZEBRA_IPV4_ROUTE_ADD) { + if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) { - } else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */ + } else /* if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL) */ { } diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index c1d558fc22..5fc3a24c30 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -568,7 +568,7 @@ static int isis_zebra_read_ipv4(int command, struct zclient *zclient, * without this check) */ if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS) - command = ZEBRA_IPV4_ROUTE_DELETE; + command = ZEBRA_REDISTRIBUTE_IPV4_DEL; if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) isis_redist_add(api.type, p_generic, api.distance, api.metric); @@ -637,7 +637,7 @@ static int isis_zebra_read_ipv6(int command, struct zclient *zclient, * without this check) */ if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS) - command = ZEBRA_IPV6_ROUTE_DELETE; + command = ZEBRA_REDISTRIBUTE_IPV6_DEL; if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) isis_redist_add(api.type, p_generic, api.distance, api.metric); From 34b054ba6d8ff278f52d77328475f542138ce958 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 19 Aug 2017 11:38:47 -0300 Subject: [PATCH 17/79] *: remove leftovers from "router zebra" Signed-off-by: Renato Westphal --- babeld/babel_zebra.c | 28 ----------- bgpd/bgp_zebra.c | 16 ------ isisd/isis_zebra.c | 16 ------ lib/zclient.c | 19 -------- lib/zclient.h | 4 -- ospf6d/ospf6_zebra.c | 113 +------------------------------------------ ospfd/ospf_zebra.c | 32 ------------ ripd/rip_zebra.c | 53 -------------------- ripngd/ripng_zebra.c | 56 --------------------- 9 files changed, 1 insertion(+), 336 deletions(-) diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c index 2ec5c3d7c3..37f441c30f 100644 --- a/babeld/babel_zebra.c +++ b/babeld/babel_zebra.c @@ -37,7 +37,6 @@ void babelz_zebra_init(void); /* we must use a pointer because of zclient.c's functions (new, free). */ struct zclient *zclient; -static int zebra_config_write (struct vty *vty); /* Debug types */ static struct { @@ -55,15 +54,6 @@ static struct { {0, 0, NULL} }; -/* Zebra node structure. */ -struct cmd_node zebra_node = -{ - ZEBRA_NODE, - "%s(config-router)# ", - 1 /* vtysh? yes */ -}; - - /* Zebra route add and delete treatment (ipv6). */ static int babel_zebra_read_ipv6 (int command, struct zclient *zclient, @@ -347,7 +337,6 @@ void babelz_zebra_init(void) zclient->redistribute_route_ipv6_add = babel_zebra_read_ipv6; zclient->redistribute_route_ipv6_del = babel_zebra_read_ipv6; - install_node (&zebra_node, zebra_config_write); install_element(BABEL_NODE, &babel_redistribute_type_cmd); install_element(ENABLE_NODE, &debug_babel_cmd); install_element(ENABLE_NODE, &no_debug_babel_cmd); @@ -357,23 +346,6 @@ void babelz_zebra_init(void) install_element(VIEW_NODE, &show_debugging_babel_cmd); } -static int -zebra_config_write (struct vty *vty) -{ - if (! zclient->enable) - { - vty_out (vty, "no router zebra\n"); - return 1; - } - else if (! vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BABEL], VRF_DEFAULT)) - { - vty_out (vty, "router zebra\n"); - vty_out (vty, " no redistribute babel\n"); - return 1; - } - return 0; -} - void babel_zebra_close_connexion(void) { diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 2fc75ea5a2..193775165c 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1169,14 +1169,6 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, if (!bgp_install_info_to_zebra(bgp)) return; - if ((p->family == AF_INET - && !vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_BGP], - bgp->vrf_id)) - || (p->family == AF_INET6 - && !vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_BGP], - bgp->vrf_id))) - return; - if (bgp->main_zebra_update_hold) return; @@ -1590,14 +1582,6 @@ void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info, safi_t safi) if (!bgp_install_info_to_zebra(peer->bgp)) return; - if ((p->family == AF_INET - && !vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_BGP], - peer->bgp->vrf_id)) - || (p->family == AF_INET6 - && !vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_BGP], - peer->bgp->vrf_id))) - return; - flags = 0; if (peer->sort == BGP_PEER_IBGP) { diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 5fc3a24c30..2eecda91bf 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -258,10 +258,6 @@ static void isis_zebra_route_add_ipv4(struct prefix *prefix, if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) return; - if (!vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], - VRF_DEFAULT)) - return; - message = 0; flags = 0; @@ -324,10 +320,6 @@ static void isis_zebra_route_del_ipv4(struct prefix *prefix, UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - if (!vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], - VRF_DEFAULT)) - return; - api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_ISIS; api.instance = 0; @@ -505,14 +497,6 @@ void isis_zebra_route_update(struct prefix *prefix, if (zclient->sock < 0) return; - if ((prefix->family == AF_INET - && !vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], - VRF_DEFAULT)) - || (prefix->family == AF_INET6 - && !vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_ISIS], - VRF_DEFAULT))) - return; - if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ACTIVE)) { if (prefix->family == AF_INET) isis_zebra_route_add_ipv4(prefix, route_info); diff --git a/lib/zclient.c b/lib/zclient.c index 24cb699196..f8bbdd85c9 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -352,10 +352,6 @@ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id) int i; afi_t afi; - /* zclient is disabled. */ - if (!zclient->enable) - return; - /* If not connected to the zebra yet. */ if (zclient->sock < 0) return; @@ -418,10 +414,6 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id) int i; afi_t afi; - /* zclient is disabled. */ - if (!zclient->enable) - return; - /* If not connected to the zebra yet. */ if (zclient->sock < 0) return; @@ -485,10 +477,6 @@ void zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id, { struct stream *s; - /* zclient is disabled. */ - if (!zclient->enable) - return; - /* If not connected to the zebra yet. */ if (zclient->sock < 0) return; @@ -516,10 +504,6 @@ int zclient_start(struct zclient *zclient) if (zclient_debug) zlog_info("zclient_start is called"); - /* zclient is disabled. */ - if (!zclient->enable) - return 0; - /* If already connected to the zebra. */ if (zclient->sock >= 0) return 0; @@ -564,9 +548,6 @@ void zclient_init(struct zclient *zclient, int redist_default, u_short instance) { int afi, i; - /* Enable zebra client connection by default. */ - zclient->enable = 1; - /* Set -1 to the default socket value. */ zclient->sock = -1; diff --git a/lib/zclient.h b/lib/zclient.h index 0218c1b732..ddd9655443 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -137,10 +137,6 @@ struct zclient { /* Socket to zebra daemon. */ int sock; - /* Flag of communication to zebra is enabled or not. Default is on. - This flag is disabled by `no router zebra' statement. */ - int enable; - /* Connection failure count. */ int fail; diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index dc97f1ff4b..1c266da888 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -317,7 +317,7 @@ DEFUN (show_zebra, } vty_out(vty, "Zebra Infomation\n"); - vty_out(vty, " enable: %d fail: %d\n", zclient->enable, zclient->fail); + vty_out(vty, " fail: %d\n", zclient->fail); vty_out(vty, " redistribute default: %d\n", vrf_bitmap_check(zclient->default_information, VRF_DEFAULT)); vty_out(vty, " redistribute:"); @@ -329,27 +329,6 @@ DEFUN (show_zebra, return CMD_SUCCESS; } -/* Zebra configuration write function. */ -static int config_write_ospf6_zebra(struct vty *vty) -{ - if (!zclient->enable) { - vty_out(vty, "no router zebra\n"); - vty_out(vty, "!\n"); - } else if (!vrf_bitmap_check( - zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT)) { - vty_out(vty, "router zebra\n"); - vty_out(vty, " no redistribute ospf6\n"); - vty_out(vty, "!\n"); - } - return 0; -} - -/* Zebra node structure. */ -static struct cmd_node zebra_node = { - ZEBRA_NODE, "%s(config-zebra)# ", -}; - #define ADD 0 #define REM 1 static void ospf6_zebra_route_update(int type, struct ospf6_route *request) @@ -471,23 +450,11 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request) void ospf6_zebra_route_update_add(struct ospf6_route *request) { - if (!vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT)) { - ospf6->route_table->hook_add = NULL; - ospf6->route_table->hook_remove = NULL; - return; - } ospf6_zebra_route_update(ADD, request); } void ospf6_zebra_route_update_remove(struct ospf6_route *request) { - if (!vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT)) { - ospf6->route_table->hook_add = NULL; - ospf6->route_table->hook_remove = NULL; - return; - } ospf6_zebra_route_update(REM, request); } @@ -497,10 +464,6 @@ void ospf6_zebra_add_discard(struct ospf6_route *request) char buf[INET6_ADDRSTRLEN]; struct prefix_ipv6 *dest; - if (!vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT)) - return; - if (!CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF6; @@ -542,10 +505,6 @@ void ospf6_zebra_delete_discard(struct ospf6_route *request) char buf[INET6_ADDRSTRLEN]; struct prefix_ipv6 *dest; - if (!vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT)) - return; - if (CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF6; @@ -580,65 +539,6 @@ void ospf6_zebra_delete_discard(struct ospf6_route *request) } } -DEFUN (redistribute_ospf6, - redistribute_ospf6_cmd, - "redistribute ospf6", - "Redistribute control\n" - "OSPF6 route\n") -{ - struct ospf6_route *route; - - if (vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT)) - return CMD_SUCCESS; - - vrf_bitmap_set(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT); - - if (ospf6 == NULL) - return CMD_SUCCESS; - - /* send ospf6 route to zebra route table */ - for (route = ospf6_route_head(ospf6->route_table); route; - route = ospf6_route_next(route)) - ospf6_zebra_route_update_add(route); - - ospf6->route_table->hook_add = ospf6_zebra_route_update_add; - ospf6->route_table->hook_remove = ospf6_zebra_route_update_remove; - - return CMD_SUCCESS; -} - -DEFUN (no_redistribute_ospf6, - no_redistribute_ospf6_cmd, - "no redistribute ospf6", - NO_STR - "Redistribute control\n" - "OSPF6 route\n") -{ - struct ospf6_route *route; - - if (!vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT)) - return CMD_SUCCESS; - - vrf_bitmap_unset(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT); - - if (ospf6 == NULL) - return CMD_SUCCESS; - - ospf6->route_table->hook_add = NULL; - ospf6->route_table->hook_remove = NULL; - - /* withdraw ospf6 route from zebra route table */ - for (route = ospf6_route_head(ospf6->route_table); route; - route = ospf6_route_next(route)) - ospf6_zebra_route_update_remove(route); - - return CMD_SUCCESS; -} - static struct ospf6_distance *ospf6_distance_new(void) { return XCALLOC(MTYPE_OSPF6_DISTANCE, sizeof(struct ospf6_distance)); @@ -794,19 +694,8 @@ void ospf6_zebra_init(struct thread_master *master) zclient->redistribute_route_ipv6_add = ospf6_zebra_read_ipv6; zclient->redistribute_route_ipv6_del = ospf6_zebra_read_ipv6; - /* redistribute connected route by default */ - /* ospf6_zebra_redistribute (ZEBRA_ROUTE_CONNECT); */ - - /* Install zebra node. */ - install_node(&zebra_node, config_write_ospf6_zebra); - /* Install command element for zebra node. */ install_element(VIEW_NODE, &show_ospf6_zebra_cmd); - install_default(ZEBRA_NODE); - install_element(ZEBRA_NODE, &redistribute_ospf6_cmd); - install_element(ZEBRA_NODE, &no_redistribute_ospf6_cmd); - - return; } /* Debug */ diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index f9668f2495..6d9d56d92d 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -342,14 +342,6 @@ void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or) struct listnode *node; struct ospf *ospf = ospf_lookup(); - if (!(ospf->instance - && redist_check_instance( - &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], - ospf->instance)) - && !vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], - VRF_DEFAULT)) - return; - message = 0; flags = 0; @@ -465,14 +457,6 @@ void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or) struct listnode *node; struct ospf *ospf = ospf_lookup(); - if (!(ospf->instance - && redist_check_instance( - &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], - ospf->instance)) - && !vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], - VRF_DEFAULT)) - return; - message = 0; flags = 0; /* Distance value. */ @@ -543,14 +527,6 @@ void ospf_zebra_add_discard(struct prefix_ipv4 *p) struct zapi_ipv4 api; struct ospf *ospf = ospf_lookup(); - if (!(ospf->instance - && redist_check_instance( - &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], - ospf->instance)) - && !vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], - VRF_DEFAULT)) - return; - api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; @@ -574,14 +550,6 @@ void ospf_zebra_delete_discard(struct prefix_ipv4 *p) struct zapi_ipv4 api; struct ospf *ospf = ospf_lookup(); - if (!(ospf->instance - && redist_check_instance( - &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], - ospf->instance)) - && !vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], - VRF_DEFAULT)) - return; - api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index 8a166745ec..f9d2d33f19 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -48,10 +48,6 @@ static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd) struct rip_info *rinfo = NULL; int count = 0; - if (!vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], - VRF_DEFAULT)) - return; - api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_RIP; api.instance = 0; @@ -295,27 +291,6 @@ void rip_redistribute_clean(void) } } -DEFUN (rip_redistribute_rip, - rip_redistribute_rip_cmd, - "redistribute rip", - "Redistribute information from another routing protocol\n" - "Routing Information Protocol (RIP)\n") -{ - vrf_bitmap_set(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], VRF_DEFAULT); - return CMD_SUCCESS; -} - -DEFUN (no_rip_redistribute_rip, - no_rip_redistribute_rip_cmd, - "no redistribute rip", - NO_STR - "Redistribute information from another routing protocol\n" - "Routing Information Protocol (RIP)\n") -{ - vrf_bitmap_unset(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], VRF_DEFAULT); - return CMD_SUCCESS; -} - DEFUN (rip_redistribute_type, rip_redistribute_type_cmd, "redistribute " FRR_REDIST_STR_RIPD, @@ -601,21 +576,6 @@ DEFUN (no_rip_default_information_originate, return CMD_SUCCESS; } -/* RIP configuration write function. */ -static int config_write_zebra(struct vty *vty) -{ - if (!zclient->enable) { - vty_out(vty, "no router zebra\n"); - return 1; - } else if (!vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], - VRF_DEFAULT)) { - vty_out(vty, "router zebra\n"); - vty_out(vty, " no redistribute rip\n"); - return 1; - } - return 0; -} - int config_write_rip_redistribute(struct vty *vty, int config_mode) { int i; @@ -656,11 +616,6 @@ int config_write_rip_redistribute(struct vty *vty, int config_mode) return 0; } -/* Zebra node structure. */ -static struct cmd_node zebra_node = { - ZEBRA_NODE, "%s(config-router)# ", -}; - static void rip_zebra_connected(struct zclient *zclient) { zclient_send_reg_requests(zclient, VRF_DEFAULT); @@ -681,14 +636,6 @@ void rip_zclient_init(struct thread_master *master) zclient->redistribute_route_ipv4_add = rip_zebra_read_ipv4; zclient->redistribute_route_ipv4_del = rip_zebra_read_ipv4; - /* Install zebra node. */ - install_node(&zebra_node, config_write_zebra); - - /* Install command elements to zebra node. */ - install_default(ZEBRA_NODE); - install_element(ZEBRA_NODE, &rip_redistribute_rip_cmd); - install_element(ZEBRA_NODE, &no_rip_redistribute_rip_cmd); - /* Install command elements to rip node. */ install_element(RIP_NODE, &rip_redistribute_type_cmd); install_element(RIP_NODE, &rip_redistribute_type_routemap_cmd); diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index 875ec4f225..3845028264 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -49,10 +49,6 @@ static void ripng_zebra_ipv6_send(struct route_node *rp, u_char cmd) struct ripng_info *rinfo = NULL; int count = 0; - if (!vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_RIPNG], - VRF_DEFAULT)) - return; - api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_RIPNG; api.instance = 0; @@ -292,29 +288,6 @@ void ripng_redistribute_clean() } } -DEFUN (ripng_redistribute_ripng, - ripng_redistribute_ripng_cmd, - "redistribute ripng", - "Redistribute information from another routing protocol\n" - "RIPng route\n") -{ - vrf_bitmap_set(zclient->redist[AFI_IP6][ZEBRA_ROUTE_RIPNG], - VRF_DEFAULT); - return CMD_SUCCESS; -} - -DEFUN (no_ripng_redistribute_ripng, - no_ripng_redistribute_ripng_cmd, - "no redistribute ripng", - NO_STR - "Redistribute information from another routing protocol\n" - "RIPng route\n") -{ - vrf_bitmap_unset(zclient->redist[AFI_IP6][ZEBRA_ROUTE_RIPNG], - VRF_DEFAULT); - return CMD_SUCCESS; -} - DEFUN (ripng_redistribute_type, ripng_redistribute_type_cmd, "redistribute " FRR_REDIST_STR_RIPNGD, @@ -484,27 +457,6 @@ void ripng_redistribute_write(struct vty *vty, int config_mode) } } -/* RIPng configuration write function. */ -static int zebra_config_write(struct vty *vty) -{ - if (!zclient->enable) { - vty_out(vty, "no router zebra\n"); - return 1; - } else if (!vrf_bitmap_check( - zclient->redist[AFI_IP6][ZEBRA_ROUTE_RIPNG], - VRF_DEFAULT)) { - vty_out(vty, "router zebra\n"); - vty_out(vty, " no redistribute ripng\n"); - return 1; - } - return 0; -} - -/* Zebra node structure. */ -static struct cmd_node zebra_node = { - ZEBRA_NODE, "%s(config-router)# ", -}; - static void ripng_zebra_connected(struct zclient *zclient) { zclient_send_reg_requests(zclient, VRF_DEFAULT); @@ -527,14 +479,6 @@ void zebra_init(struct thread_master *master) zclient->redistribute_route_ipv6_add = ripng_zebra_read_ipv6; zclient->redistribute_route_ipv6_del = ripng_zebra_read_ipv6; - /* Install zebra node. */ - install_node(&zebra_node, zebra_config_write); - - /* Install command element for zebra node. */ - install_default(ZEBRA_NODE); - install_element(ZEBRA_NODE, &ripng_redistribute_ripng_cmd); - install_element(ZEBRA_NODE, &no_ripng_redistribute_ripng_cmd); - /* Install command elements to ripng node */ install_element(RIPNG_NODE, &ripng_redistribute_type_cmd); install_element(RIPNG_NODE, &ripng_redistribute_type_routemap_cmd); From c125d1d41ef05cf8bd440a3eab94483c18b9874c Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 19 Aug 2017 12:09:38 -0300 Subject: [PATCH 18/79] babeld/nhrpd: ignore ipv6 srcdest routes Signed-off-by: Renato Westphal --- babeld/babel_zebra.c | 12 +++++++++++- nhrpd/nhrp_route.c | 12 ++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c index 37f441c30f..a1d3a9e8cc 100644 --- a/babeld/babel_zebra.c +++ b/babeld/babel_zebra.c @@ -63,7 +63,7 @@ babel_zebra_read_ipv6 (int command, struct zclient *zclient, struct zapi_ipv6 api; unsigned long ifindex = -1; struct in6_addr nexthop; - struct prefix_ipv6 prefix; + struct prefix_ipv6 prefix, src_p; s = zclient->ibuf; ifindex = 0; @@ -82,6 +82,16 @@ babel_zebra_read_ipv6 (int command, struct zclient *zclient, prefix.prefixlen = stream_getc (s); stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen)); + memset(&src_p, 0, sizeof(src_p)); + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { + src_p.family = AF_INET6; + src_p.prefixlen = stream_getc(s); + stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); + } + if (src_p.prefixlen) + /* we completely ignore srcdest routes for now. */ + return 0; + /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { api.nexthop_num = stream_getc (s); diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index c8a608c657..e9651adc54 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -193,6 +193,7 @@ int nhrp_route_read(int cmd, struct zclient *zclient, zebra_size_t length, vrf_i struct stream *s; struct interface *ifp = NULL; struct prefix prefix; + struct prefix_ipv6 src_p; union sockunion nexthop_addr; unsigned char message, nexthop_num, ifindex_num; unsigned ifindex; @@ -226,6 +227,17 @@ int nhrp_route_read(int cmd, struct zclient *zclient, zebra_size_t length, vrf_i prefix.prefixlen = stream_getc(s); stream_get(&prefix.u.val, s, PSIZE(prefix.prefixlen)); + memset(&src_p, 0, sizeof(src_p)); + if (prefix.family == AF_INET6 && + CHECK_FLAG(message, ZAPI_MESSAGE_SRCPFX)) { + src_p.family = AF_INET6; + src_p.prefixlen = stream_getc(s); + stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); + } + if (src_p.prefixlen) + /* we completely ignore srcdest routes for now. */ + return 0; + /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX)) { nexthop_num = stream_getc(s); From f38efb809d91605b3b29cf9eb226825d28f680af Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 19 Aug 2017 13:01:00 -0300 Subject: [PATCH 19/79] zebra: add support for NEXTHOP_TYPE_IPV6_IFINDEX in zserv This is the v6 counterpart of commit c963c20. Fixes a bug where ipv6 routes received from babeld were being ignored. Signed-off-by: Renato Westphal --- zebra/zserv.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/zebra/zserv.c b/zebra/zserv.c index aa7189fe89..b2ee9c0b47 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1534,6 +1534,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length, unsigned int i; struct stream *s; struct in6_addr nhop_addr; + ifindex_t ifindex; struct route_entry *re; u_char message; u_char nexthop_num; @@ -1609,6 +1610,12 @@ static int zread_ipv6_add(struct zserv *client, u_short length, nexthops[nh_count++] = nhop_addr; } break; + case NEXTHOP_TYPE_IPV6_IFINDEX: + stream_get(&nhop_addr, s, 16); + ifindex = stream_getl(s); + route_entry_nexthop_ipv6_ifindex_add( + re, &nhop_addr, ifindex); + break; case NEXTHOP_TYPE_IFINDEX: if (if_count < multipath_num) { ifindices[if_count++] = stream_getl(s); From e959008b1ef36acc572d41555f7df2d3e7f9a0cf Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 19 Aug 2017 14:12:20 -0300 Subject: [PATCH 20/79] babeld/eigrpd/ldpd/nhrpd: add prefix length sanity checks Pulled from d917882. Signed-off-by: Renato Westphal --- babeld/babel_zebra.c | 6 +++--- eigrpd/eigrp_zebra.c | 2 +- ldpd/ldp_zebra.c | 3 ++- nhrpd/nhrp_route.c | 3 ++- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c index a1d3a9e8cc..2b998940d7 100644 --- a/babeld/babel_zebra.c +++ b/babeld/babel_zebra.c @@ -79,7 +79,7 @@ babel_zebra_read_ipv6 (int command, struct zclient *zclient, /* IPv6 prefix. */ prefix.family = AF_INET6; - prefix.prefixlen = stream_getc (s); + prefix.prefixlen = MIN (IPV6_MAX_PREFIXLEN, stream_getc (s)); stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen)); memset(&src_p, 0, sizeof(src_p)); @@ -140,9 +140,9 @@ babel_zebra_read_ipv4 (int command, struct zclient *zclient, api.flags = stream_getl (s); api.message = stream_getc (s); - /* IPv6 prefix. */ + /* IPv4 prefix. */ prefix.family = AF_INET; - prefix.prefixlen = stream_getc (s); + prefix.prefixlen = MIN (IPV4_MAX_PREFIXLEN, stream_getc (s)); stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen)); /* Nexthop, ifindex, distance, metric. */ diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index 0ee89eb675..6fc3f29353 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -137,7 +137,7 @@ static int eigrp_zebra_read_ipv4(int command, struct zclient *zclient, /* IPv4 prefix. */ memset(&p, 0, sizeof(struct prefix_ipv4)); p.family = AF_INET; - p.prefixlen = stream_getc(s); + p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s)); stream_get(&p.prefix, s, PSIZE(p.prefixlen)); if (IPV4_NET127(ntohl(p.prefix.s_addr))) diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c index ecc7db8f2e..54c5af62a4 100644 --- a/ldpd/ldp_zebra.c +++ b/ldpd/ldp_zebra.c @@ -427,17 +427,18 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length, case ZEBRA_REDISTRIBUTE_IPV4_ADD: case ZEBRA_REDISTRIBUTE_IPV4_DEL: kr.af = AF_INET; + kr.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s)); nhlen = sizeof(struct in_addr); break; case ZEBRA_REDISTRIBUTE_IPV6_ADD: case ZEBRA_REDISTRIBUTE_IPV6_DEL: kr.af = AF_INET6; + kr.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc(s)); nhlen = sizeof(struct in6_addr); break; default: fatalx("ldp_zebra_read_route: unknown command"); } - kr.prefixlen = stream_getc(s); stream_get(&kr.prefix, s, PSIZE(kr.prefixlen)); if (bad_addr(kr.af, &kr.prefix) || diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index e9651adc54..5116ad068c 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -215,16 +215,17 @@ int nhrp_route_read(int cmd, struct zclient *zclient, zebra_size_t length, vrf_i case ZEBRA_REDISTRIBUTE_IPV4_ADD: case ZEBRA_REDISTRIBUTE_IPV4_DEL: prefix.family = AF_INET; + prefix.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s)); break; case ZEBRA_REDISTRIBUTE_IPV6_ADD: case ZEBRA_REDISTRIBUTE_IPV6_DEL: prefix.family = AF_INET6; + prefix.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc(s)); break; default: return -1; } afaddrlen = family2addrsize(prefix.family); - prefix.prefixlen = stream_getc(s); stream_get(&prefix.u.val, s, PSIZE(prefix.prefixlen)); memset(&src_p, 0, sizeof(src_p)); From d51b9e4509f69cf3f871a787e69534a60842bab5 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 19 Aug 2017 14:26:00 -0300 Subject: [PATCH 21/79] zserv: simplify handling of route delete requests Route attributes like tag, distance and metric are irrelevant when we want to delete a route from a client daemon. The same can be said about the nexthops of the route. Only the IP prefix and client protocol are enough to identify the route we want to remove, considering that zebra maintains at most one route from each client daemon for each prefix. Once rib_delete() is called, it deletes the selected route with all of its nexthops. Signed-off-by: Renato Westphal --- zebra/zserv.c | 125 ++------------------------------------------------ 1 file changed, 3 insertions(+), 122 deletions(-) diff --git a/zebra/zserv.c b/zebra/zserv.c index b2ee9c0b47..a196eb5945 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1281,21 +1281,12 @@ static int zread_ipv4_add(struct zserv *client, u_short length, static int zread_ipv4_delete(struct zserv *client, u_short length, struct zebra_vrf *zvrf) { - int i; struct stream *s; struct zapi_ipv4 api; - struct in_addr nexthop; - union g_addr *nexthop_p; - unsigned long ifindex; struct prefix p; - u_char nexthop_num; - u_char nexthop_type; u_int32_t table_id; s = client->ibuf; - ifindex = 0; - nexthop.s_addr = 0; - nexthop_p = NULL; /* Type, flags, message. */ api.type = stream_getc(s); @@ -1310,63 +1301,10 @@ static int zread_ipv4_delete(struct zserv *client, u_short length, p.prefixlen = stream_getc(s); stream_get(&p.u.prefix4, s, PSIZE(p.prefixlen)); - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { - nexthop_num = stream_getc(s); - - for (i = 0; i < nexthop_num; i++) { - nexthop_type = stream_getc(s); - - switch (nexthop_type) { - case NEXTHOP_TYPE_IFINDEX: - ifindex = stream_getl(s); - break; - case NEXTHOP_TYPE_IPV4: - nexthop.s_addr = stream_get_ipv4(s); - /* For labeled-unicast, each nexthop is followed - * by label, but - * we don't care for delete. - */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL)) - stream_forward_getp(s, - sizeof(u_int32_t)); - nexthop_p = (union g_addr *)&nexthop; - break; - case NEXTHOP_TYPE_IPV4_IFINDEX: - nexthop.s_addr = stream_get_ipv4(s); - nexthop_p = (union g_addr *)&nexthop; - ifindex = stream_getl(s); - break; - case NEXTHOP_TYPE_IPV6: - stream_forward_getp(s, IPV6_MAX_BYTELEN); - break; - } - } - } - - /* Distance. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(s); - else - api.distance = 0; - - /* Metric. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(s); - else - api.metric = 0; - - /* tag */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl(s); - else - api.tag = 0; - table_id = zvrf->table_id; rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance, - api.flags, &p, NULL, nexthop_p, ifindex, table_id, - api.metric); + api.flags, &p, NULL, NULL, 0, table_id, 0); client->v4_route_del_cnt++; return 0; } @@ -1688,18 +1626,12 @@ static int zread_ipv6_add(struct zserv *client, u_short length, static int zread_ipv6_delete(struct zserv *client, u_short length, struct zebra_vrf *zvrf) { - int i; struct stream *s; struct zapi_ipv6 api; - struct in6_addr nexthop; - union g_addr *pnexthop = NULL; - unsigned long ifindex; struct prefix p; struct prefix_ipv6 src_p, *src_pp; s = client->ibuf; - ifindex = 0; - memset(&nexthop, 0, sizeof(struct in6_addr)); /* Type, flags, message. */ api.type = stream_getc(s); @@ -1723,59 +1655,8 @@ static int zread_ipv6_delete(struct zserv *client, u_short length, } else src_pp = NULL; - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { - u_char nexthop_type; - - api.nexthop_num = stream_getc(s); - for (i = 0; i < api.nexthop_num; i++) { - nexthop_type = stream_getc(s); - - switch (nexthop_type) { - case NEXTHOP_TYPE_IPV6: - stream_get(&nexthop, s, 16); - /* For labeled-unicast, each nexthop is followed - * by label, but - * we don't care for delete. - */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL)) - stream_forward_getp(s, - sizeof(u_int32_t)); - pnexthop = (union g_addr *)&nexthop; - break; - case NEXTHOP_TYPE_IFINDEX: - ifindex = stream_getl(s); - break; - } - } - } - - /* Distance. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(s); - else - api.distance = 0; - - /* Metric. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(s); - else - api.metric = 0; - - /* tag */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl(s); - else - api.tag = 0; - - if (IN6_IS_ADDR_UNSPECIFIED(&nexthop)) - rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, - api.instance, api.flags, &p, src_pp, NULL, ifindex, - client->rtm_table, api.metric); - else - rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, - api.instance, api.flags, &p, src_pp, pnexthop, - ifindex, client->rtm_table, api.metric); + rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance, + api.flags, &p, src_pp, NULL, 0, client->rtm_table, 0); client->v6_route_del_cnt++; return 0; From 81c11e3feafcd20e32cb2d437f39603d645e6880 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 19 Aug 2017 20:00:25 -0300 Subject: [PATCH 22/79] zserv: identify label type based on the client protocol This fixes a problem where the type of the BGP-LU labels was not being set. Signed-off-by: Renato Westphal --- zebra/zserv.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/zebra/zserv.c b/zebra/zserv.c index a196eb5945..e00e1d7c20 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1176,6 +1176,7 @@ static int zread_ipv4_add(struct zserv *client, u_short length, ifindex_t ifindex; safi_t safi; int ret; + enum lsp_types_t label_type; mpls_label_t label; struct nexthop *nexthop; @@ -1208,6 +1209,9 @@ static int zread_ipv4_add(struct zserv *client, u_short length, zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num); + if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) + label_type = lsp_type_from_re_type(client->proto); + for (i = 0; i < nexthop_num; i++) { nexthop_type = stream_getc(s); @@ -1224,9 +1228,8 @@ static int zread_ipv4_add(struct zserv *client, u_short length, * by label. */ if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) { label = (mpls_label_t)stream_getl(s); - nexthop_add_labels( - nexthop, nexthop->nh_label_type, - 1, &label); + nexthop_add_labels(nexthop, label_type, + 1, &label); } break; case NEXTHOP_TYPE_IPV4_IFINDEX: @@ -1339,6 +1342,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, static unsigned int ifindices[MULTIPATH_NUM]; int ret; static mpls_label_t labels[MULTIPATH_NUM]; + enum lsp_types_t label_type; mpls_label_t label; struct nexthop *nexthop; @@ -1379,6 +1383,10 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, nexthop_num = stream_getc(s); zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num); + + if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) + label_type = lsp_type_from_re_type(client->proto); + for (i = 0; i < nexthop_num; i++) { nexthop_type = stream_getc(s); @@ -1423,9 +1431,8 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, re, &nexthops[i]); if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) - nexthop_add_labels( - nexthop, nexthop->nh_label_type, - 1, &labels[i]); + nexthop_add_labels(nexthop, label_type, + 1, &labels[i]); } else { if ((i < if_count) && ifindices[i]) route_entry_nexthop_ifindex_add( @@ -1484,6 +1491,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length, static unsigned int ifindices[MULTIPATH_NUM]; int ret; static mpls_label_t labels[MULTIPATH_NUM]; + enum lsp_types_t label_type; mpls_label_t label; struct nexthop *nexthop; @@ -1530,6 +1538,10 @@ static int zread_ipv6_add(struct zserv *client, u_short length, nexthop_num = stream_getc(s); zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num); + + if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) + label_type = lsp_type_from_re_type(client->proto); + for (i = 0; i < nexthop_num; i++) { nexthop_type = stream_getc(s); @@ -1578,9 +1590,8 @@ static int zread_ipv6_add(struct zserv *client, u_short length, nexthop = route_entry_nexthop_ipv6_add( re, &nexthops[i]); if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) - nexthop_add_labels( - nexthop, nexthop->nh_label_type, - 1, &labels[i]); + nexthop_add_labels(nexthop, label_type, + 1, &labels[i]); } else { if ((i < if_count) && ifindices[i]) route_entry_nexthop_ifindex_add( From bb1b9c47ca090ce4484e1f8061f17b5c33f578ee Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 19 Aug 2017 21:25:12 -0300 Subject: [PATCH 23/79] lib: updates to zapi_route This patch introduces the following changes to the zapi_route structure and associated code: * Use a fixed-size array to store the nexthops instead of a pointer. This makes the zapi_route() function much easier to use when we have multiple nexthops to send. It's also much more efficient to put everything on the stack rather than allocating an array in the heap every time we need to send a route to zebra; * Use the new 'zapi_nexthop' structure. This will allow the client daemons to send labeled routes without having to allocate memory for the labels (the 'nexthop' structure was designed to be memory efficient and doesn't have room for MPLS labels, only a pointer). Also, 'zapi_nexthop' is more compact and more clean from an API perspective; * Embed the route prefix inside the zapi_route structure. Since the route's prefix is sent along with its nexthops and attributes, it makes sense to pack everything inside the same structure. Signed-off-by: Renato Westphal --- babeld/kernel.c | 34 ++++++++++---------- lib/zclient.c | 84 ++++++++++++++++++++++--------------------------- lib/zclient.h | 16 ++++++++-- 3 files changed, 68 insertions(+), 66 deletions(-) diff --git a/babeld/kernel.c b/babeld/kernel.c index 26860f3bae..105a7d0518 100644 --- a/babeld/kernel.c +++ b/babeld/kernel.c @@ -144,15 +144,15 @@ kernel_route_v4(int add, const unsigned char *gate, int ifindex, unsigned int metric) { struct zapi_route api; /* quagga's communication system */ + struct zapi_nexthop *api_nh; /* next router to go - no ECMP */ struct prefix quagga_prefix; /* quagga's prefix */ struct in_addr babel_prefix_addr; /* babeld's prefix addr */ - struct nexthop nexthop; /* next router to go */ - struct nexthop *nexthop_pointer = &nexthop; /* it's an array! */ + + api_nh = &api.nexthops[0]; /* convert to be understandable by quagga */ /* convert given addresses */ uchar_to_inaddr(&babel_prefix_addr, pref); - uchar_to_inaddr(&nexthop.gate.ipv4, gate); /* make prefix structure */ memset (&quagga_prefix, 0, sizeof(quagga_prefix)); @@ -168,6 +168,7 @@ kernel_route_v4(int add, api.instance = 0; api.safi = SAFI_UNICAST; api.vrf_id = VRF_DEFAULT; + api.prefix = quagga_prefix; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); if(metric >= KERNEL_INFINITY) { @@ -175,13 +176,13 @@ kernel_route_v4(int add, api.nexthop_num = 0; } else { api.nexthop_num = 1; - api.nexthop = &nexthop_pointer; - nexthop.ifindex = ifindex; - if (IPV4_ADDR_SAME (&nexthop.gate.ipv4, &quagga_prefix.u.prefix4) && + api_nh->ifindex = ifindex; + uchar_to_inaddr(&api_nh->gate.ipv4, gate); + if (IPV4_ADDR_SAME (&api_nh->gate.ipv4, &quagga_prefix.u.prefix4) && quagga_prefix.prefixlen == 32) { - nexthop.type = NEXTHOP_TYPE_IFINDEX; + api_nh->type = NEXTHOP_TYPE_IFINDEX; } else { - nexthop.type = NEXTHOP_TYPE_IPV4_IFINDEX; + api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; } SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); api.metric = metric; @@ -191,7 +192,7 @@ kernel_route_v4(int add, add ? "adding" : "removing" ); return zapi_route (add ? ZEBRA_IPV4_ROUTE_ADD : ZEBRA_IPV4_ROUTE_DELETE, - zclient, &quagga_prefix, NULL, &api); + zclient, &api); } static int @@ -199,15 +200,15 @@ kernel_route_v6(int add, const unsigned char *pref, unsigned short plen, const unsigned char *gate, int ifindex, unsigned int metric) { struct zapi_route api; /* quagga's communication system */ + struct zapi_nexthop *api_nh; /* next router to go - no ECMP */ struct prefix quagga_prefix; /* quagga's prefix */ struct in6_addr babel_prefix_addr; /* babeld's prefix addr */ - struct nexthop nexthop; /* next router to go */ - struct nexthop *nexthop_pointer = &nexthop; + + api_nh = &api.nexthops[0]; /* convert to be understandable by quagga */ /* convert given addresses */ uchar_to_in6addr(&babel_prefix_addr, pref); - uchar_to_in6addr(&nexthop.gate.ipv6, gate); /* make prefix structure */ memset (&quagga_prefix, 0, sizeof(quagga_prefix)); @@ -223,6 +224,7 @@ kernel_route_v6(int add, const unsigned char *pref, unsigned short plen, api.instance = 0; api.safi = SAFI_UNICAST; api.vrf_id = VRF_DEFAULT; + api.prefix = quagga_prefix; if(metric >= KERNEL_INFINITY) { api.flags = ZEBRA_FLAG_REJECT; @@ -230,10 +232,10 @@ kernel_route_v6(int add, const unsigned char *pref, unsigned short plen, } else { SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; - api.nexthop = &nexthop_pointer; - nexthop.ifindex = ifindex; + api_nh->ifindex = ifindex; + uchar_to_in6addr(&api_nh->gate.ipv6, gate); /* difference to IPv4: always leave the linklocal as nexthop */ - nexthop.type = NEXTHOP_TYPE_IPV6_IFINDEX; + api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); api.metric = metric; } @@ -242,7 +244,7 @@ kernel_route_v6(int add, const unsigned char *pref, unsigned short plen, add ? "adding" : "removing" ); return zapi_route (add ? ZEBRA_IPV6_ROUTE_ADD : ZEBRA_IPV6_ROUTE_DELETE, - zclient, &quagga_prefix, NULL, &api); + zclient, &api); } int diff --git a/lib/zclient.c b/lib/zclient.c index f8bbdd85c9..53e8569b77 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -892,16 +892,12 @@ int zapi_ipv6_route(u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p, return zclient_send_message(zclient); } -int zapi_route(u_char cmd, struct zclient *zclient, struct prefix *p, - struct prefix_ipv6 *src_p, struct zapi_route *api) +int zapi_route(u_char cmd, struct zclient *zclient, struct zapi_route *api) { int i; int psize; struct stream *s; - - /* either we have !SRCPFX && src_p == NULL, or SRCPFX && src_p != NULL - */ - assert(!(api->message & ZAPI_MESSAGE_SRCPFX) == !src_p); + struct zapi_nexthop *api_nh; /* Reset stream. */ s = zclient->obuf; @@ -917,69 +913,63 @@ int zapi_route(u_char cmd, struct zclient *zclient, struct prefix *p, stream_putw(s, api->safi); /* Put prefix information. */ - psize = PSIZE(p->prefixlen); - stream_putc(s, p->prefixlen); - stream_write(s, (u_char *)&p->u.prefix, psize); + psize = PSIZE(api->prefix.prefixlen); + stream_putc(s, api->prefix.prefixlen); + stream_write(s, (u_char *)&api->prefix.u.prefix, psize); if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) { - psize = PSIZE(src_p->prefixlen); - stream_putc(s, src_p->prefixlen); - stream_write(s, (u_char *)&src_p->prefix, psize); + psize = PSIZE(api->src_prefix.prefixlen); + stream_putc(s, api->src_prefix.prefixlen); + stream_write(s, (u_char *)&api->src_prefix.prefix, psize); } /* Nexthop, ifindex, distance and metric information. */ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) { + /* limit the number of nexthops if necessary */ + if (api->nexthop_num > MULTIPATH_NUM) { + char buf[PREFIX2STR_BUFFER]; + + prefix2str(&api->prefix, buf, sizeof(buf)); + zlog_warn( + "%s: prefix %s: encoding %u nexthops out of %u", + __func__, buf, MULTIPATH_NUM, api->nexthop_num); + api->nexthop_num = MULTIPATH_NUM; + } + stream_putc(s, api->nexthop_num); for (i = 0; i < api->nexthop_num; i++) { - stream_putc(s, api->nexthop[i]->type); - switch (api->nexthop[i]->type) { + api_nh = &api->nexthops[i]; + + stream_putc(s, api_nh->type); + switch (api_nh->type) { case NEXTHOP_TYPE_BLACKHOLE: break; case NEXTHOP_TYPE_IPV4: - stream_put_in_addr(s, - &api->nexthop[i]->gate.ipv4); - - /* For labeled-unicast, each nexthop is followed - * by label. */ - if (CHECK_FLAG(api->message, - ZAPI_MESSAGE_LABEL)) - stream_putl( - s, - api->nexthop[i] - ->nh_label->label[0]); + stream_put_in_addr(s, &api_nh->gate.ipv4); break; case NEXTHOP_TYPE_IPV4_IFINDEX: - stream_put_in_addr(s, - &api->nexthop[i]->gate.ipv4); - stream_putl(s, api->nexthop[i]->ifindex); + stream_put_in_addr(s, &api_nh->gate.ipv4); + stream_putl(s, api_nh->ifindex); break; case NEXTHOP_TYPE_IFINDEX: - stream_putl(s, api->nexthop[i]->ifindex); + stream_putl(s, api_nh->ifindex); break; case NEXTHOP_TYPE_IPV6: - stream_write( - s, - (u_char *)&api->nexthop[i]->gate.ipv6, - 16); - - /* For labeled-unicast, each nexthop is followed - * by label. */ - if (CHECK_FLAG(api->message, - ZAPI_MESSAGE_LABEL)) - stream_putl( - s, - api->nexthop[i] - ->nh_label->label[0]); + stream_write(s, (u_char *)&api_nh->gate.ipv6, + 16); break; case NEXTHOP_TYPE_IPV6_IFINDEX: - stream_write( - s, - (u_char *)&api->nexthop[i]->gate.ipv6, - 16); - stream_putl(s, api->nexthop[i]->ifindex); + stream_write(s, (u_char *)&api_nh->gate.ipv6, + 16); + stream_putl(s, api_nh->ifindex); break; } + + /* For labeled-unicast, each nexthop is followed + * by label. */ + if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) + stream_putl(s, api_nh->label); } } diff --git a/lib/zclient.h b/lib/zclient.h index ddd9655443..92aeabb07f 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -224,6 +224,13 @@ struct zserv_header { uint16_t command; }; +struct zapi_nexthop { + enum nexthop_types_t type; + ifindex_t ifindex; + union g_addr gate; + mpls_label_t label; +}; + struct zapi_route { u_char type; u_short instance; @@ -234,8 +241,11 @@ struct zapi_route { safi_t safi; + struct prefix prefix; + struct prefix_ipv6 src_prefix; + u_char nexthop_num; - struct nexthop **nexthop; + struct zapi_nexthop nexthops[MULTIPATH_NUM]; u_char distance; @@ -416,7 +426,7 @@ extern int zapi_ipv6_route(u_char cmd, struct zclient *zclient, extern int zapi_ipv4_route_ipv6_nexthop(u_char, struct zclient *, struct prefix_ipv4 *, struct zapi_ipv6 *); -extern int zapi_route(u_char cmd, struct zclient *zclient, struct prefix *p, - struct prefix_ipv6 *src_p, struct zapi_route *api); +extern int zapi_route(u_char cmd, struct zclient *zclient, + struct zapi_route *api); #endif /* _ZEBRA_ZCLIENT_H */ From 0e51b4a368257d54b1e07ff74492ea4705de97f7 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 19 Aug 2017 21:59:41 -0300 Subject: [PATCH 24/79] lib/zserv: introduce address-family independent ZAPI message types As noticed in 657cde1, the zapi_ipv[4|6]_route functions are broken in many ways and that's the reason that many client daemons (e.g. ospfd, isisd) need to send handcrafted messages to zebra. The zapi_route() function introduced by Donald solves the problem by providing a consistent way to send ipv4/ipv6 routes to zebra with nexthops of any type, in all possible combinations including IPv4 routes with IPv6 nexthops (for BGP unnumbered routes). This patch goes a bit further and creates two new address-family independent ZAPI message types that the client daemons can use to advertise route information to zebra: ZEBRA_ROUTE_ADD and ZEBRA_ROUTE_DELETE. The big advantage of having address-family independent messages is that it allows us to remove a lot of duplicate code in zebra and in the client daemons. This patch also introduces the zapi_route_decode() function. It will be used by zebra to decode route messages sent by the client daemons using zclient_route_send(), which calls zapi_route_encode(). Later on we'll use this same pair of encode/decode functions to send/receive redistributed routes from zebra to the client daemons, taking the idea of removing code duplication to the next level. Signed-off-by: Renato Westphal --- babeld/kernel.c | 10 ++-- lib/log.c | 2 + lib/zclient.c | 116 +++++++++++++++++++++++++++++++++++--- lib/zclient.h | 7 ++- zebra/zserv.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 262 insertions(+), 17 deletions(-) diff --git a/babeld/kernel.c b/babeld/kernel.c index 105a7d0518..6cdd66e48d 100644 --- a/babeld/kernel.c +++ b/babeld/kernel.c @@ -190,9 +190,8 @@ kernel_route_v4(int add, debugf(BABEL_DEBUG_ROUTE, "%s route (ipv4) to zebra", add ? "adding" : "removing" ); - return zapi_route (add ? ZEBRA_IPV4_ROUTE_ADD : - ZEBRA_IPV4_ROUTE_DELETE, - zclient, &api); + return zclient_route_send (add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, + zclient, &api); } static int @@ -242,9 +241,8 @@ kernel_route_v6(int add, const unsigned char *pref, unsigned short plen, debugf(BABEL_DEBUG_ROUTE, "%s route (ipv6) to zebra", add ? "adding" : "removing" ); - return zapi_route (add ? ZEBRA_IPV6_ROUTE_ADD : - ZEBRA_IPV6_ROUTE_DELETE, - zclient, &api); + return zclient_route_send (add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, + zclient, &api); } int diff --git a/lib/log.c b/lib/log.c index b9ce9e69bc..92b2d3b66b 100644 --- a/lib/log.c +++ b/lib/log.c @@ -867,6 +867,8 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_INTERFACE_UP), DESC_ENTRY(ZEBRA_INTERFACE_DOWN), DESC_ENTRY(ZEBRA_INTERFACE_SET_MASTER), + DESC_ENTRY(ZEBRA_ROUTE_ADD), + DESC_ENTRY(ZEBRA_ROUTE_DELETE), DESC_ENTRY(ZEBRA_IPV4_ROUTE_ADD), DESC_ENTRY(ZEBRA_IPV4_ROUTE_DELETE), DESC_ENTRY(ZEBRA_IPV6_ROUTE_ADD), diff --git a/lib/zclient.c b/lib/zclient.c index 53e8569b77..3f5c7a0f6f 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -892,20 +892,23 @@ int zapi_ipv6_route(u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p, return zclient_send_message(zclient); } -int zapi_route(u_char cmd, struct zclient *zclient, struct zapi_route *api) +int zclient_route_send(u_char cmd, struct zclient *zclient, + struct zapi_route *api) { + if (zapi_route_encode(cmd, zclient->obuf, api) < 0) + return -1; + return zclient_send_message(zclient); +} + +int zapi_route_encode(u_char cmd, struct stream *s, struct zapi_route *api) +{ + struct zapi_nexthop *api_nh; int i; int psize; - struct stream *s; - struct zapi_nexthop *api_nh; - /* Reset stream. */ - s = zclient->obuf; stream_reset(s); - zclient_create_header(s, cmd, api->vrf_id); - /* Put type and nexthop. */ stream_putc(s, api->type); stream_putw(s, api->instance); stream_putl(s, api->flags); @@ -913,6 +916,7 @@ int zapi_route(u_char cmd, struct zclient *zclient, struct zapi_route *api) stream_putw(s, api->safi); /* Put prefix information. */ + stream_putc(s, api->prefix.family); psize = PSIZE(api->prefix.prefixlen); stream_putc(s, api->prefix.prefixlen); stream_write(s, (u_char *)&api->prefix.u.prefix, psize); @@ -923,7 +927,7 @@ int zapi_route(u_char cmd, struct zclient *zclient, struct zapi_route *api) stream_write(s, (u_char *)&api->src_prefix.prefix, psize); } - /* Nexthop, ifindex, distance and metric information. */ + /* Nexthops. */ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) { /* limit the number of nexthops if necessary */ if (api->nexthop_num > MULTIPATH_NUM) { @@ -973,6 +977,7 @@ int zapi_route(u_char cmd, struct zclient *zclient, struct zapi_route *api) } } + /* Attributes. */ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE)) stream_putc(s, api->distance); if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC)) @@ -985,7 +990,100 @@ int zapi_route(u_char cmd, struct zclient *zclient, struct zapi_route *api) /* Put length at the first point of the stream. */ stream_putw_at(s, 0, stream_get_endp(s)); - return zclient_send_message(zclient); + return 0; +} + +int zapi_route_decode(struct stream *s, struct zapi_route *api) +{ + struct zapi_nexthop *api_nh; + int i; + + memset(api, 0, sizeof(*api)); + + /* Type, flags, message. */ + api->type = stream_getc(s); + api->instance = stream_getw(s); + api->flags = stream_getl(s); + api->message = stream_getc(s); + api->safi = stream_getw(s); + + /* Prefix. */ + api->prefix.family = stream_getc(s); + switch (api->prefix.family) { + case AF_INET: + api->prefix.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s)); + break; + case AF_INET6: + api->prefix.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc(s)); + break; + } + stream_get(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen)); + if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) { + api->src_prefix.family = AF_INET6; + api->src_prefix.prefixlen = stream_getc(s); + stream_get(&api->src_prefix.prefix, s, + PSIZE(api->src_prefix.prefixlen)); + + if (api->prefix.family != AF_INET6 + || api->src_prefix.prefixlen == 0) + UNSET_FLAG(api->message, ZAPI_MESSAGE_SRCPFX); + } + + /* Nexthops. */ + if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) { + api->nexthop_num = stream_getc(s); + if (api->nexthop_num > MULTIPATH_NUM) { + zlog_warn("%s: invalid number of nexthops (%u)", + __func__, api->nexthop_num); + return -1; + } + + for (i = 0; i < api->nexthop_num; i++) { + api_nh = &api->nexthops[i]; + + api_nh->type = stream_getc(s); + switch (api_nh->type) { + case NEXTHOP_TYPE_BLACKHOLE: + break; + case NEXTHOP_TYPE_IPV4: + api_nh->gate.ipv4.s_addr = stream_get_ipv4(s); + break; + case NEXTHOP_TYPE_IPV4_IFINDEX: + api_nh->gate.ipv4.s_addr = stream_get_ipv4(s); + api_nh->ifindex = stream_getl(s); + break; + case NEXTHOP_TYPE_IFINDEX: + api_nh->ifindex = stream_getl(s); + break; + case NEXTHOP_TYPE_IPV6: + stream_get(&api_nh->gate.ipv6, s, 16); + break; + case NEXTHOP_TYPE_IPV6_IFINDEX: + stream_get(&api_nh->gate.ipv6, s, 16); + api_nh->ifindex = stream_getl(s); + break; + } + + /* For labeled-unicast, each nexthop is followed + * by label. */ + if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) { + stream_get(&api_nh->label, s, + sizeof(api_nh->label)); + } + } + } + + /* Attributes. */ + if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE)) + api->distance = stream_getc(s); + if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC)) + api->metric = stream_getl(s); + if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG)) + api->tag = stream_getl(s); + if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU)) + api->mtu = stream_getl(s); + + return 0; } /* diff --git a/lib/zclient.h b/lib/zclient.h index 92aeabb07f..2e450ed398 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -59,6 +59,8 @@ typedef enum { ZEBRA_INTERFACE_UP, ZEBRA_INTERFACE_DOWN, ZEBRA_INTERFACE_SET_MASTER, + ZEBRA_ROUTE_ADD, + ZEBRA_ROUTE_DELETE, ZEBRA_IPV4_ROUTE_ADD, ZEBRA_IPV4_ROUTE_DELETE, ZEBRA_IPV6_ROUTE_ADD, @@ -426,7 +428,8 @@ extern int zapi_ipv6_route(u_char cmd, struct zclient *zclient, extern int zapi_ipv4_route_ipv6_nexthop(u_char, struct zclient *, struct prefix_ipv4 *, struct zapi_ipv6 *); -extern int zapi_route(u_char cmd, struct zclient *zclient, - struct zapi_route *api); +extern int zclient_route_send(u_char, struct zclient *, struct zapi_route *); +extern int zapi_route_encode(u_char, struct stream *, struct zapi_route *); +extern int zapi_route_decode(struct stream *, struct zapi_route *); #endif /* _ZEBRA_ZCLIENT_H */ diff --git a/zebra/zserv.c b/zebra/zserv.c index e00e1d7c20..94e34865b5 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1157,6 +1157,144 @@ void zserv_nexthop_num_warn(const char *caller, const struct prefix *p, } } +static int zread_route_add(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) +{ + struct stream *s; + struct zapi_route api; + struct zapi_nexthop *api_nh; + afi_t afi; + struct prefix_ipv6 *src_p = NULL; + struct route_entry *re; + struct nexthop *nexthop; + int i, ret; + + s = client->ibuf; + if (zapi_route_decode(s, &api) < 0) + return -1; + + /* Allocate new route. */ + re = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); + re->type = api.type; + re->instance = api.instance; + re->flags = api.flags; + re->uptime = time(NULL); + re->vrf_id = zvrf_id(zvrf); + re->table = zvrf->table_id; + + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { + for (i = 0; i < api.nexthop_num; i++) { + api_nh = &api.nexthops[i]; + + switch (api_nh->type) { + case NEXTHOP_TYPE_IFINDEX: + route_entry_nexthop_ifindex_add( + re, api_nh->ifindex); + break; + case NEXTHOP_TYPE_IPV4: + nexthop = route_entry_nexthop_ipv4_add( + re, &api_nh->gate.ipv4, NULL); + break; + case NEXTHOP_TYPE_IPV4_IFINDEX: + nexthop = route_entry_nexthop_ipv4_ifindex_add( + re, &api_nh->gate.ipv4, NULL, + api_nh->ifindex); + break; + case NEXTHOP_TYPE_IPV6: + nexthop = route_entry_nexthop_ipv6_add( + re, &api_nh->gate.ipv6); + break; + case NEXTHOP_TYPE_IPV6_IFINDEX: + nexthop = route_entry_nexthop_ipv6_ifindex_add( + re, &api_nh->gate.ipv6, + api_nh->ifindex); + break; + case NEXTHOP_TYPE_BLACKHOLE: + route_entry_nexthop_blackhole_add(re); + break; + } + + /* MPLS labels for BGP-LU or Segment Routing */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL) + && api_nh->type != NEXTHOP_TYPE_IFINDEX + && api_nh->type != NEXTHOP_TYPE_BLACKHOLE) { + enum lsp_types_t label_type; + + label_type = + lsp_type_from_re_type(client->proto); + nexthop_add_labels(nexthop, label_type, 1, + &api_nh->label); + } + } + } + + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) + re->distance = api.distance; + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) + re->metric = api.metric; + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) + re->tag = api.tag; + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_MTU)) + re->mtu = api.mtu; + + afi = family2afi(api.prefix.family); + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) + src_p = &api.src_prefix; + + ret = rib_add_multipath(afi, api.safi, &api.prefix, src_p, re); + + /* Stats */ + switch (api.prefix.family) { + case AF_INET: + if (ret > 0) + client->v4_route_add_cnt++; + else if (ret < 0) + client->v4_route_upd8_cnt++; + break; + case AF_INET6: + if (ret > 0) + client->v6_route_add_cnt++; + else if (ret < 0) + client->v6_route_upd8_cnt++; + break; + } + + return 0; +} + +static int zread_route_del(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) +{ + struct stream *s; + struct zapi_route api; + afi_t afi; + struct prefix_ipv6 *src_p = NULL; + + s = client->ibuf; + if (zapi_route_decode(s, &api) < 0) + return -1; + + afi = family2afi(api.prefix.family); + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) + src_p = &api.src_prefix; + + rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance, + api.flags, &api.prefix, src_p, NULL, 0, zvrf->table_id, + api.metric); + + /* Stats */ + switch (api.prefix.family) { + case AF_INET: + client->v4_route_del_cnt++; + break; + case AF_INET6: + client->v6_route_del_cnt++; + break; + } + + return 0; +} + /* This function support multiple nexthop. */ /* * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update re and @@ -2334,6 +2472,12 @@ static int zebra_client_read(struct thread *thread) case ZEBRA_INTERFACE_DELETE: zread_interface_delete(client, length, zvrf); break; + case ZEBRA_ROUTE_ADD: + zread_route_add(client, length, zvrf); + break; + case ZEBRA_ROUTE_DELETE: + zread_route_del(client, length, zvrf); + break; case ZEBRA_IPV4_ROUTE_ADD: zread_ipv4_add(client, length, zvrf); break; From c8f9e916df033897ee8878d970887a7d9bb07a2b Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 19 Aug 2017 22:31:32 -0300 Subject: [PATCH 25/79] babeld: unify kernel_route_v4() and kernel_route_v6() Signed-off-by: Renato Westphal --- babeld/kernel.c | 153 +++++++++++++++++------------------------------- 1 file changed, 55 insertions(+), 98 deletions(-) diff --git a/babeld/kernel.c b/babeld/kernel.c index 6cdd66e48d..394d7b1e81 100644 --- a/babeld/kernel.c +++ b/babeld/kernel.c @@ -51,13 +51,8 @@ THE SOFTWARE. static int -kernel_route_v4(int add, const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, - unsigned int metric); -static int -kernel_route_v6(int add, const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, - unsigned int metric); +zebra_route(int add, int familt, const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, unsigned int metric); int kernel_interface_operational(struct interface *interface) @@ -84,7 +79,7 @@ kernel_route(int operation, const unsigned char *pref, unsigned short plen, unsigned int newmetric) { int rc; - int ipv4; + int family; /* Check that the protocol family is consistent. */ if(plen >= 96 && v4mapped(pref)) { @@ -92,46 +87,37 @@ kernel_route(int operation, const unsigned char *pref, unsigned short plen, errno = EINVAL; return -1; } - ipv4 = 1; + family = AF_INET; } else { if(v4mapped(gate)) { errno = EINVAL; return -1; } - ipv4 = 0; + family = AF_INET6; } switch (operation) { case ROUTE_ADD: - return ipv4 ? - kernel_route_v4(1, pref, plen, gate, ifindex, metric): - kernel_route_v6(1, pref, plen, gate, ifindex, metric); + return zebra_route(1, family, pref, plen, gate, ifindex, metric); break; case ROUTE_FLUSH: - return ipv4 ? - kernel_route_v4(0, pref, plen, gate, ifindex, metric): - kernel_route_v6(0, pref, plen, gate, ifindex, metric); + return zebra_route(0, family, pref, plen, gate, ifindex, metric); break; case ROUTE_MODIFY: if(newmetric == metric && memcmp(newgate, gate, 16) == 0 && newifindex == ifindex) return 0; debugf(BABEL_DEBUG_ROUTE, "Modify route: delete old; add new."); - rc = ipv4 ? - kernel_route_v4(0, pref, plen, gate, ifindex, metric): - kernel_route_v6(0, pref, plen, gate, ifindex, metric); - + rc = zebra_route(0, family, pref, plen, gate, ifindex, metric); if (rc < 0) return -1; - rc = ipv4 ? - kernel_route_v4(1, pref, plen, newgate, newifindex, newmetric): - kernel_route_v6(1, pref, plen, newgate, newifindex, newmetric); - + rc = zebra_route(1, family, pref, plen, newgate, newifindex, + newmetric); return rc; break; default: - zlog_err("this should never appens (false value - kernel_route)"); + zlog_err("this should never happen (false value - kernel_route)"); assert(0); exit(1); break; @@ -139,108 +125,79 @@ kernel_route(int operation, const unsigned char *pref, unsigned short plen, } static int -kernel_route_v4(int add, - const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, unsigned int metric) +zebra_route(int add, int family, const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, unsigned int metric) { struct zapi_route api; /* quagga's communication system */ - struct zapi_nexthop *api_nh; /* next router to go - no ECMP */ struct prefix quagga_prefix; /* quagga's prefix */ - struct in_addr babel_prefix_addr; /* babeld's prefix addr */ + union g_addr babel_prefix_addr; /* babeld's prefix addr */ + struct zapi_nexthop *api_nh; /* next router to go - no ECMP */ api_nh = &api.nexthops[0]; /* convert to be understandable by quagga */ /* convert given addresses */ - uchar_to_inaddr(&babel_prefix_addr, pref); + switch (family) { + case AF_INET: + uchar_to_inaddr(&babel_prefix_addr.ipv4, pref); + break; + case AF_INET6: + uchar_to_in6addr(&babel_prefix_addr.ipv6, pref); + break; + } /* make prefix structure */ memset (&quagga_prefix, 0, sizeof(quagga_prefix)); - quagga_prefix.family = AF_INET; - IPV4_ADDR_COPY (&quagga_prefix.u.prefix4, &babel_prefix_addr); - quagga_prefix.prefixlen = plen - 96; /* our plen is for v4mapped's addr */ + quagga_prefix.family = family; + switch (family) { + case AF_INET: + IPV4_ADDR_COPY (&quagga_prefix.u.prefix4, &babel_prefix_addr.ipv4); + /* our plen is for v4mapped's addr */ + quagga_prefix.prefixlen = plen - 96; + break; + case AF_INET6: + IPV6_ADDR_COPY (&quagga_prefix.u.prefix6, &babel_prefix_addr.ipv6); + quagga_prefix.prefixlen = plen; + break; + } apply_mask(&quagga_prefix); memset(&api, 0, sizeof(api)); api.type = ZEBRA_ROUTE_BABEL; - api.flags = 0; - api.message = 0; - api.instance = 0; api.safi = SAFI_UNICAST; api.vrf_id = VRF_DEFAULT; api.prefix = quagga_prefix; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); if(metric >= KERNEL_INFINITY) { api.flags = ZEBRA_FLAG_REJECT; - api.nexthop_num = 0; } else { + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api_nh->ifindex = ifindex; - uchar_to_inaddr(&api_nh->gate.ipv4, gate); - if (IPV4_ADDR_SAME (&api_nh->gate.ipv4, &quagga_prefix.u.prefix4) && - quagga_prefix.prefixlen == 32) { - api_nh->type = NEXTHOP_TYPE_IFINDEX; - } else { - api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; + + 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) && + quagga_prefix.prefixlen == 32) { + api_nh->type = NEXTHOP_TYPE_IFINDEX; + } else { + api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; + } + break; + case AF_INET6: + uchar_to_in6addr(&api_nh->gate.ipv6, gate); + /* difference to IPv4: always leave the linklocal as nexthop */ + api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; + break; } SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); api.metric = metric; } - debugf(BABEL_DEBUG_ROUTE, "%s route (ipv4) to zebra", - add ? "adding" : "removing" ); - return zclient_route_send (add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, - zclient, &api); -} - -static int -kernel_route_v6(int add, const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, unsigned int metric) -{ - struct zapi_route api; /* quagga's communication system */ - struct zapi_nexthop *api_nh; /* next router to go - no ECMP */ - struct prefix quagga_prefix; /* quagga's prefix */ - struct in6_addr babel_prefix_addr; /* babeld's prefix addr */ - - api_nh = &api.nexthops[0]; - - /* convert to be understandable by quagga */ - /* convert given addresses */ - uchar_to_in6addr(&babel_prefix_addr, pref); - - /* make prefix structure */ - memset (&quagga_prefix, 0, sizeof(quagga_prefix)); - quagga_prefix.family = AF_INET6; - IPV6_ADDR_COPY (&quagga_prefix.u.prefix6, &babel_prefix_addr); - quagga_prefix.prefixlen = plen; - apply_mask(&quagga_prefix); - - memset(&api, 0, sizeof(api)); - api.type = ZEBRA_ROUTE_BABEL; - api.flags = 0; - api.message = 0; - api.instance = 0; - api.safi = SAFI_UNICAST; - api.vrf_id = VRF_DEFAULT; - api.prefix = quagga_prefix; - - if(metric >= KERNEL_INFINITY) { - api.flags = ZEBRA_FLAG_REJECT; - api.nexthop_num = 0; - } else { - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 1; - api_nh->ifindex = ifindex; - uchar_to_in6addr(&api_nh->gate.ipv6, gate); - /* difference to IPv4: always leave the linklocal as nexthop */ - api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = metric; - } - - debugf(BABEL_DEBUG_ROUTE, "%s route (ipv6) to zebra", - add ? "adding" : "removing" ); + debugf(BABEL_DEBUG_ROUTE, "%s route (%s) to zebra", + add ? "adding" : "removing", + (family == AF_INET) ? "ipv4" : "ipv6"); return zclient_route_send (add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, zclient, &api); } From 52dd3aa483441880ac46eb4bb50069d26dbecf13 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 20 Aug 2017 19:57:36 -0300 Subject: [PATCH 26/79] zapi: add support for routes with multiple labels This will be necessary for the Segment Routing feature. Signed-off-by: Renato Westphal --- lib/mpls.h | 3 +++ lib/zclient.c | 42 ++++++++++++++++++++++++++++++++++-------- lib/zclient.h | 5 ++++- zebra/zebra_mpls.h | 2 -- zebra/zserv.c | 5 +++-- 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/lib/mpls.h b/lib/mpls.h index 025770d479..bf98eecd81 100644 --- a/lib/mpls.h +++ b/lib/mpls.h @@ -44,6 +44,9 @@ #define MPLS_DEFAULT_MIN_SRGB_LABEL 16000 #define MPLS_DEFAULT_MAX_SRGB_LABEL 23999 +/* Maximum # labels that can be pushed. */ +#define MPLS_MAX_LABELS 16 + #define IS_MPLS_RESERVED_LABEL(label) \ (label >= MPLS_MIN_RESERVED_LABEL && label <= MPLS_MAX_RESERVED_LABEL) diff --git a/lib/zclient.c b/lib/zclient.c index 3f5c7a0f6f..e063c7151f 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -970,10 +970,26 @@ int zapi_route_encode(u_char cmd, struct stream *s, struct zapi_route *api) break; } - /* For labeled-unicast, each nexthop is followed - * by label. */ - if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) - stream_putl(s, api_nh->label); + /* MPLS labels for BGP-LU or Segment Routing */ + if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) { + if (api_nh->label_num > MPLS_MAX_LABELS) { + char buf[PREFIX2STR_BUFFER]; + prefix2str(&api->prefix, buf, + sizeof(buf)); + zlog_err( + "%s: prefix %s: can't encode " + "%u labels (maximum is %u)", + __func__, buf, + api_nh->label_num, + MPLS_MAX_LABELS); + return -1; + } + + stream_putc(s, api_nh->label_num); + stream_put(s, &api_nh->labels[0], + api_nh->label_num + * sizeof(mpls_label_t)); + } } } @@ -1064,11 +1080,21 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) break; } - /* For labeled-unicast, each nexthop is followed - * by label. */ + /* MPLS labels for BGP-LU or Segment Routing */ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) { - stream_get(&api_nh->label, s, - sizeof(api_nh->label)); + api_nh->label_num = stream_getc(s); + + if (api_nh->label_num > MPLS_MAX_LABELS) { + zlog_warn( + "%s: invalid number of MPLS " + "labels (%u)", + __func__, api_nh->label_num); + return -1; + } + + stream_get(&api_nh->labels[0], s, + api_nh->label_num + * sizeof(mpls_label_t)); } } } diff --git a/lib/zclient.h b/lib/zclient.h index 2e450ed398..40ddbf62df 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -230,7 +230,10 @@ struct zapi_nexthop { enum nexthop_types_t type; ifindex_t ifindex; union g_addr gate; - mpls_label_t label; + + /* MPLS labels for BGP-LU or Segment Routing */ + uint8_t label_num; + mpls_label_t labels[MPLS_MAX_LABELS]; }; struct zapi_route { diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h index 6bddc4d00f..c8df8670f4 100644 --- a/zebra/zebra_mpls.h +++ b/zebra/zebra_mpls.h @@ -37,8 +37,6 @@ /* Definitions and macros. */ -#define MPLS_MAX_LABELS 16 /* Maximum # labels that can be pushed. */ - #define NHLFE_FAMILY(nhlfe) \ (((nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6 \ || (nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) \ diff --git a/zebra/zserv.c b/zebra/zserv.c index 94e34865b5..de475dccfd 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1222,8 +1222,9 @@ static int zread_route_add(struct zserv *client, u_short length, label_type = lsp_type_from_re_type(client->proto); - nexthop_add_labels(nexthop, label_type, 1, - &api_nh->label); + nexthop_add_labels(nexthop, label_type, + api_nh->label_num, + &api_nh->labels[0]); } } } From c9fb3e233e4c3199d3379952eb56e93f856a4544 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 20 Aug 2017 21:17:09 -0300 Subject: [PATCH 27/79] ripd/ripngd: use the new API to send routes to zebra Signed-off-by: Renato Westphal --- ripd/rip_zebra.c | 36 ++++++++++++------------------- ripngd/ripng_zebra.c | 51 ++++++++++++++++---------------------------- 2 files changed, 32 insertions(+), 55 deletions(-) diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index f9d2d33f19..9a9bac51e0 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -39,40 +39,32 @@ struct zclient *zclient = NULL; /* Send ECMP routes to zebra. */ static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd) { - static struct in_addr **nexthops = NULL; - static unsigned int nexthops_len = 0; - struct list *list = (struct list *)rp->info; - struct zapi_ipv4 api; + struct zapi_route api; + struct zapi_nexthop *api_nh; struct listnode *listnode = NULL; struct rip_info *rinfo = NULL; int count = 0; + memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_RIP; - api.instance = 0; - api.flags = 0; - api.message = 0; api.safi = SAFI_UNICAST; - if (nexthops_len < listcount(list)) { - nexthops_len = listcount(list); - nexthops = XREALLOC(MTYPE_TMP, nexthops, - nexthops_len * sizeof(struct in_addr *)); - } - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { - nexthops[count++] = &rinfo->nexthop; - if (cmd == ZEBRA_IPV4_ROUTE_ADD) + api_nh = &api.nexthops[count]; + api_nh->gate.ipv4 = rinfo->nexthop; + api_nh->type = NEXTHOP_TYPE_IPV4; + if (cmd == ZEBRA_ROUTE_ADD) SET_FLAG(rinfo->flags, RIP_RTF_FIB); else UNSET_FLAG(rinfo->flags, RIP_RTF_FIB); + count++; } - api.nexthop = nexthops; + api.prefix = rp->p; api.nexthop_num = count; - api.ifindex_num = 0; rinfo = listgetdata(listhead(list)); @@ -89,19 +81,19 @@ static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd) api.tag = rinfo->tag; } - zapi_ipv4_route(cmd, zclient, (struct prefix_ipv4 *)&rp->p, &api); + zclient_route_send(cmd, zclient, &api); if (IS_RIP_DEBUG_ZEBRA) { if (rip->ecmp) zlog_debug("%s: %s/%d nexthops %d", - (cmd == ZEBRA_IPV4_ROUTE_ADD) + (cmd == ZEBRA_ROUTE_ADD) ? "Install into zebra" : "Delete from zebra", inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen, count); else zlog_debug("%s: %s/%d", - (cmd == ZEBRA_IPV4_ROUTE_ADD) + (cmd == ZEBRA_ROUTE_ADD) ? "Install into zebra" : "Delete from zebra", inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen); @@ -113,13 +105,13 @@ static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd) /* Add/update ECMP routes to zebra. */ void rip_zebra_ipv4_add(struct route_node *rp) { - rip_zebra_ipv4_send(rp, ZEBRA_IPV4_ROUTE_ADD); + rip_zebra_ipv4_send(rp, ZEBRA_ROUTE_ADD); } /* Delete ECMP routes from zebra. */ void rip_zebra_ipv4_delete(struct route_node *rp) { - rip_zebra_ipv4_send(rp, ZEBRA_IPV4_ROUTE_DELETE); + rip_zebra_ipv4_send(rp, ZEBRA_ROUTE_DELETE); } /* Zebra route add and delete treatment. */ diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index 3845028264..a5ed5c7b2c 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -39,47 +39,33 @@ struct zclient *zclient = NULL; /* Send ECMP routes to zebra. */ static void ripng_zebra_ipv6_send(struct route_node *rp, u_char cmd) { - static struct in6_addr **nexthops = NULL; - static ifindex_t *ifindexes = NULL; - static unsigned int nexthops_len = 0; - struct list *list = (struct list *)rp->info; - struct zapi_ipv6 api; + struct zapi_route api; + struct zapi_nexthop *api_nh; struct listnode *listnode = NULL; struct ripng_info *rinfo = NULL; int count = 0; + memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_RIPNG; - api.instance = 0; - api.flags = 0; - api.message = 0; api.safi = SAFI_UNICAST; - - if (nexthops_len < listcount(list)) { - nexthops_len = listcount(list); - nexthops = XREALLOC(MTYPE_TMP, nexthops, - nexthops_len * sizeof(struct in6_addr *)); - ifindexes = XREALLOC(MTYPE_TMP, ifindexes, - nexthops_len * sizeof(unsigned int)); - } + api.prefix = rp->p; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { - nexthops[count] = &rinfo->nexthop; - ifindexes[count] = rinfo->ifindex; + api_nh = &api.nexthops[count]; + api_nh->gate.ipv6 = rinfo->nexthop; + api_nh->ifindex = rinfo->ifindex; + api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; count++; - if (cmd == ZEBRA_IPV6_ROUTE_ADD) + if (cmd == ZEBRA_ROUTE_ADD) SET_FLAG(rinfo->flags, RIPNG_RTF_FIB); else UNSET_FLAG(rinfo->flags, RIPNG_RTF_FIB); } - api.nexthop = nexthops; api.nexthop_num = count; - api.ifindex = ifindexes; - api.ifindex_num = count; rinfo = listgetdata(listhead(list)); @@ -91,36 +77,35 @@ static void ripng_zebra_ipv6_send(struct route_node *rp, u_char cmd) api.tag = rinfo->tag; } - zapi_ipv6_route(cmd, zclient, (struct prefix_ipv6 *)&rp->p, NULL, &api); + zclient_route_send(cmd, zclient, &api); if (IS_RIPNG_DEBUG_ZEBRA) { if (ripng->ecmp) zlog_debug("%s: %s/%d nexthops %d", - (cmd == ZEBRA_IPV6_ROUTE_ADD) + (cmd == ZEBRA_ROUTE_ADD) ? "Install into zebra" : "Delete from zebra", inet6_ntoa(rp->p.u.prefix6), rp->p.prefixlen, count); else - zlog_debug("%s: %s/%d", - (cmd == ZEBRA_IPV6_ROUTE_ADD) - ? "Install into zebra" - : "Delete from zebra", - inet6_ntoa(rp->p.u.prefix6), - rp->p.prefixlen); + zlog_debug( + "%s: %s/%d", + (cmd == ZEBRA_ROUTE_ADD) ? "Install into zebra" + : "Delete from zebra", + inet6_ntoa(rp->p.u.prefix6), rp->p.prefixlen); } } /* Add/update ECMP routes to zebra. */ void ripng_zebra_ipv6_add(struct route_node *rp) { - ripng_zebra_ipv6_send(rp, ZEBRA_IPV6_ROUTE_ADD); + ripng_zebra_ipv6_send(rp, ZEBRA_ROUTE_ADD); } /* Delete ECMP routes from zebra. */ void ripng_zebra_ipv6_delete(struct route_node *rp) { - ripng_zebra_ipv6_send(rp, ZEBRA_IPV6_ROUTE_DELETE); + ripng_zebra_ipv6_send(rp, ZEBRA_ROUTE_DELETE); } /* Zebra route add and delete treatment. */ From 8fb753e3609249c3937a5613e73e2826c7fb3b76 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 20 Aug 2017 21:17:59 -0300 Subject: [PATCH 28/79] eigrpd: use the new API to send routes to zebra Signed-off-by: Renato Westphal --- eigrpd/eigrp_zebra.c | 84 ++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 53 deletions(-) diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index 6fc3f29353..2e386fbf2e 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -391,90 +391,68 @@ static struct interface *zebra_interface_if_lookup(struct stream *s) void eigrp_zebra_route_add(struct prefix_ipv4 *p, struct list *successors) { + struct zapi_route api; + struct zapi_nexthop *api_nh; struct eigrp_neighbor_entry *te; struct listnode *node; - u_char message; - u_char flags; - int psize; - struct stream *s; + int count = 0; if (!zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP]) return; - message = 0; - flags = 0; + memset(&api, 0, sizeof(api)); + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_EIGRP; + api.safi = SAFI_UNICAST; + memcpy(&api.prefix, p, sizeof(*p)); - /* EIGRP pass nexthop and metric */ - SET_FLAG(message, ZAPI_MESSAGE_NEXTHOP); - - /* Make packet. */ - s = zclient->obuf; - stream_reset(s); - - /* Put command, type, flags, message. */ - zclient_create_header(s, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); - stream_putc(s, ZEBRA_ROUTE_EIGRP); - stream_putw(s, 0); - stream_putl(s, flags); - stream_putc(s, message); - stream_putw(s, SAFI_UNICAST); - - /* Put prefix information. */ - psize = PSIZE(p->prefixlen); - stream_putc(s, p->prefixlen); - stream_write(s, (u_char *)&p->prefix, psize); - - /* Nexthop count. */ - stream_putc(s, successors->count); + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = successors->count; /* Nexthop, ifindex, distance and metric information. */ for (ALL_LIST_ELEMENTS_RO(successors, node, te)) { + api_nh = &api.nexthops[count]; if (te->adv_router->src.s_addr) { - stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr(s, &te->adv_router->src); + api_nh->gate.ipv4 = te->adv_router->src; + api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; } else - stream_putc(s, NEXTHOP_TYPE_IFINDEX); - stream_putl(s, te->ei->ifp->ifindex); + api_nh->type = NEXTHOP_TYPE_IFINDEX; + api_nh->ifindex = te->ei->ifp->ifindex; + + count++; } if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) { char buf[2][INET_ADDRSTRLEN]; - zlog_debug("Zebra: Route add %s/%d nexthop %s", - inet_ntop(AF_INET, &p->prefix, buf[0], - sizeof(buf[0])), - p->prefixlen, - inet_ntop(AF_INET, 0 /*&p->nexthop*/, buf[1], - sizeof(buf[1]))); + zlog_debug( + "Zebra: Route add %s/%d nexthop %s", + inet_ntop(AF_INET, &p->prefix, buf[0], sizeof(buf[0])), + p->prefixlen, inet_ntop(AF_INET, 0 /*&p->nexthop*/, + buf[1], sizeof(buf[1]))); } - stream_putw_at(s, 0, stream_get_endp(s)); - - zclient_send_message(zclient); + zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); } void eigrp_zebra_route_delete(struct prefix_ipv4 *p) { - struct zapi_ipv4 api; + struct zapi_route api; if (!zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP]) return; + memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_EIGRP; - api.instance = 0; - api.flags = 0; - api.message = 0; api.safi = SAFI_UNICAST; - zapi_ipv4_route(ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api); + memcpy(&api.prefix, p, sizeof(*p)); + zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug("Zebra: Route del %s/%d nexthop %s", - inet_ntop(AF_INET, &p->prefix, buf[0], - sizeof(buf[0])), - p->prefixlen, - inet_ntop(AF_INET, 0 /*&p->nexthop*/, buf[1], - sizeof(buf[1]))); + char buf[INET_ADDRSTRLEN]; + zlog_debug("Zebra: Route del %s/%d", + inet_ntop(AF_INET, &p->prefix, buf, sizeof(buf)), + p->prefixlen); } return; From c0721de4d4cfad92893271cb5b036dab1fe011b6 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 20 Aug 2017 21:18:36 -0300 Subject: [PATCH 29/79] isisd: use the new API to send routes to zebra Signed-off-by: Renato Westphal --- isisd/isis_zebra.c | 218 +++++++++++---------------------------------- 1 file changed, 51 insertions(+), 167 deletions(-) diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 2eecda91bf..35b2091e98 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -248,66 +248,47 @@ static int isis_zebra_link_params(int command, struct zclient *zclient, static void isis_zebra_route_add_ipv4(struct prefix *prefix, struct isis_route_info *route_info) { - u_char message; - u_int32_t flags; - int psize; - struct stream *stream; + struct zapi_route api; + struct zapi_nexthop *api_nh; struct isis_nexthop *nexthop; struct listnode *node; + int count = 0; if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) return; - message = 0; - flags = 0; - - SET_FLAG(message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG(message, ZAPI_MESSAGE_METRIC); + memset(&api, 0, sizeof(api)); + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_ISIS; + api.safi = SAFI_UNICAST; + api.prefix = *prefix; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = route_info->cost; #if 0 - SET_FLAG (message, ZAPI_MESSAGE_DISTANCE); + SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); + api.distance = route_info->depth; #endif - stream = zclient->obuf; - stream_reset(stream); - zclient_create_header(stream, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); - /* type */ - stream_putc(stream, ZEBRA_ROUTE_ISIS); - /* instance */ - stream_putw(stream, 0); - /* flags */ - stream_putl(stream, flags); - /* message */ - stream_putc(stream, message); - /* SAFI */ - stream_putw(stream, SAFI_UNICAST); - /* prefix information */ - psize = PSIZE(prefix->prefixlen); - stream_putc(stream, prefix->prefixlen); - stream_write(stream, (u_char *)&prefix->u.prefix4, psize); - - stream_putc(stream, listcount(route_info->nexthops)); - /* Nexthop, ifindex, distance and metric information */ for (ALL_LIST_ELEMENTS_RO(route_info->nexthops, node, nexthop)) { + api_nh = &api.nexthops[count]; /* FIXME: can it be ? */ if (nexthop->ip.s_addr != INADDR_ANY) { - stream_putc(stream, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr(stream, &nexthop->ip); - stream_putl(stream, nexthop->ifindex); + api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; + api_nh->gate.ipv4 = nexthop->ip; } else { - stream_putc(stream, NEXTHOP_TYPE_IFINDEX); - stream_putl(stream, nexthop->ifindex); + api_nh->type = NEXTHOP_TYPE_IFINDEX; } + api_nh->ifindex = nexthop->ifindex; + count++; } -#if 0 - if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) - stream_putc (stream, route_info->depth); -#endif - if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) - stream_putl(stream, route_info->cost); + if (!count) + return; - stream_putw_at(stream, 0, stream_get_endp(stream)); - zclient_send_message(zclient); + api.nexthop_num = count; + + zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); } @@ -315,180 +296,83 @@ static void isis_zebra_route_add_ipv4(struct prefix *prefix, static void isis_zebra_route_del_ipv4(struct prefix *prefix, struct isis_route_info *route_info) { - struct zapi_ipv4 api; - struct prefix_ipv4 prefix4; + struct zapi_route api; UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_ISIS; - api.instance = 0; - api.flags = 0; - api.message = 0; api.safi = SAFI_UNICAST; - prefix4.family = AF_INET; - prefix4.prefixlen = prefix->prefixlen; - prefix4.prefix = prefix->u.prefix4; - zapi_ipv4_route(ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api); + api.prefix = *prefix; + + zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); } static void isis_zebra_route_add_ipv6(struct prefix *prefix, struct isis_route_info *route_info) { - struct zapi_ipv6 api; - struct in6_addr **nexthop_list; - ifindex_t *ifindex_list; + struct zapi_route api; + struct zapi_nexthop *api_nh; struct isis_nexthop6 *nexthop6; - int i, size; struct listnode *node; - struct prefix_ipv6 prefix6; + int count = 0; if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) return; + memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_ISIS; - api.instance = 0; - api.flags = 0; - api.message = 0; api.safi = SAFI_UNICAST; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); api.metric = route_info->cost; #if 0 - SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); + SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); api.distance = route_info->depth; #endif - api.nexthop_num = listcount(route_info->nexthops6); - api.ifindex_num = listcount(route_info->nexthops6); - - /* allocate memory for nexthop_list */ - size = sizeof(struct isis_nexthop6 *) - * listcount(route_info->nexthops6); - nexthop_list = (struct in6_addr **)XMALLOC(MTYPE_ISIS_TMP, size); - if (!nexthop_list) { - zlog_err("isis_zebra_add_route_ipv6: out of memory!"); - return; - } - - /* allocate memory for ifindex_list */ - size = sizeof(unsigned int) * listcount(route_info->nexthops6); - ifindex_list = (ifindex_t *)XMALLOC(MTYPE_ISIS_TMP, size); - if (!ifindex_list) { - zlog_err("isis_zebra_add_route_ipv6: out of memory!"); - XFREE(MTYPE_ISIS_TMP, nexthop_list); - return; - } + api.prefix = *prefix; /* for each nexthop */ - i = 0; for (ALL_LIST_ELEMENTS_RO(route_info->nexthops6, node, nexthop6)) { if (!IN6_IS_ADDR_LINKLOCAL(&nexthop6->ip6) && !IN6_IS_ADDR_UNSPECIFIED(&nexthop6->ip6)) { - api.nexthop_num--; - api.ifindex_num--; continue; } - nexthop_list[i] = &nexthop6->ip6; - ifindex_list[i] = nexthop6->ifindex; - i++; + api_nh = &api.nexthops[count]; + api_nh->gate.ipv6 = nexthop6->ip6; + api_nh->ifindex = nexthop6->ifindex; + api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; + count++; } + if (!count) + return; - api.nexthop = nexthop_list; - api.ifindex = ifindex_list; + api.nexthop_num = count; - if (api.nexthop_num && api.ifindex_num) { - prefix6.family = AF_INET6; - prefix6.prefixlen = prefix->prefixlen; - memcpy(&prefix6.prefix, &prefix->u.prefix6, - sizeof(struct in6_addr)); - zapi_ipv6_route(ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, NULL, - &api); - SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); - } - - XFREE(MTYPE_ISIS_TMP, nexthop_list); - XFREE(MTYPE_ISIS_TMP, ifindex_list); - - return; + zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); + SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); } static void isis_zebra_route_del_ipv6(struct prefix *prefix, struct isis_route_info *route_info) { - struct zapi_ipv6 api; - struct in6_addr **nexthop_list; - ifindex_t *ifindex_list; - struct isis_nexthop6 *nexthop6; - int i, size; - struct listnode *node; - struct prefix_ipv6 prefix6; + struct zapi_route api; if (!CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) return; + memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_ISIS; - api.instance = 0; - api.flags = 0; - api.message = 0; api.safi = SAFI_UNICAST; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); - api.nexthop_num = listcount(route_info->nexthops6); - api.ifindex_num = listcount(route_info->nexthops6); + api.prefix = *prefix; - /* allocate memory for nexthop_list */ - size = sizeof(struct isis_nexthop6 *) - * listcount(route_info->nexthops6); - nexthop_list = (struct in6_addr **)XMALLOC(MTYPE_ISIS_TMP, size); - if (!nexthop_list) { - zlog_err("isis_zebra_route_del_ipv6: out of memory!"); - return; - } - - /* allocate memory for ifindex_list */ - size = sizeof(unsigned int) * listcount(route_info->nexthops6); - ifindex_list = (ifindex_t *)XMALLOC(MTYPE_ISIS_TMP, size); - if (!ifindex_list) { - zlog_err("isis_zebra_route_del_ipv6: out of memory!"); - XFREE(MTYPE_ISIS_TMP, nexthop_list); - return; - } - - /* for each nexthop */ - i = 0; - for (ALL_LIST_ELEMENTS_RO(route_info->nexthops6, node, nexthop6)) { - if (!IN6_IS_ADDR_LINKLOCAL(&nexthop6->ip6) - && !IN6_IS_ADDR_UNSPECIFIED(&nexthop6->ip6)) { - api.nexthop_num--; - api.ifindex_num--; - continue; - } - - nexthop_list[i] = &nexthop6->ip6; - ifindex_list[i] = nexthop6->ifindex; - i++; - } - - api.nexthop = nexthop_list; - api.ifindex = ifindex_list; - - if (api.nexthop_num && api.ifindex_num) { - prefix6.family = AF_INET6; - prefix6.prefixlen = prefix->prefixlen; - memcpy(&prefix6.prefix, &prefix->u.prefix6, - sizeof(struct in6_addr)); - zapi_ipv6_route(ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, - NULL, &api); - UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - } - - XFREE(MTYPE_ISIS_TMP, nexthop_list); - XFREE(MTYPE_ISIS_TMP, ifindex_list); + zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); } void isis_zebra_route_update(struct prefix *prefix, From 6f27a9f6a52aefc26f4c6ee633975cfc9942f5ac Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 20 Aug 2017 21:18:50 -0300 Subject: [PATCH 30/79] nhrpd: use the new API to send routes to zebra Signed-off-by: Renato Westphal --- nhrpd/nhrp_route.c | 52 +++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index 5116ad068c..3062b23a6d 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -108,24 +108,27 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix SET_FLAG(flags, ZEBRA_FLAG_INTERNAL); if (p->family == AF_INET) { - struct in_addr *nexthop_ipv4; - struct zapi_ipv4 api; + struct zapi_route api; + struct zapi_nexthop *api_nh = &api.nexthops[0];; memset(&api, 0, sizeof(api)); api.flags = flags; api.type = ZEBRA_ROUTE_NHRP; api.safi = SAFI_UNICAST; + api.prefix = *p; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 1; if (nexthop) { - nexthop_ipv4 = (struct in_addr *) sockunion_get_addr(nexthop); - api.nexthop_num = 1; - api.nexthop = &nexthop_ipv4; + api_nh->gate.ipv4 = nexthop->sin.sin_addr; + api_nh->type = NEXTHOP_TYPE_IPV4; } if (ifp) { - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); - api.ifindex_num = 1; - api.ifindex = &ifp->ifindex; + api_nh->ifindex = ifp->ifindex; + if (api_nh->type == NEXTHOP_TYPE_IPV4) + api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; + else + api_nh->type = NEXTHOP_TYPE_IFINDEX; } if (mtu) { SET_FLAG(api.message, ZAPI_MESSAGE_MTU); @@ -139,32 +142,34 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix add ? "add" : "del", inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])), p->prefixlen, - nexthop ? inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])) : "", + nexthop ? inet_ntop(AF_INET, &api_nh->gate.ipv4, buf[1], sizeof(buf[1])) : "", api.metric, api.nexthop_num, ifp->name); } - zapi_ipv4_route( - add ? ZEBRA_IPV4_ROUTE_ADD : ZEBRA_IPV4_ROUTE_DELETE, - zclient, (struct prefix_ipv4 *) p, &api); + zclient_route_send(add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, + zclient, &api); } else if (p->family == AF_INET6) { - struct in6_addr *nexthop_ipv6; - struct zapi_ipv6 api; + struct zapi_route api; + struct zapi_nexthop *api_nh = &api.nexthops[0];; memset(&api, 0, sizeof(api)); api.flags = flags; api.type = ZEBRA_ROUTE_NHRP; api.safi = SAFI_UNICAST; + api.prefix = *p; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 1; if (nexthop) { - nexthop_ipv6 = (struct in6_addr *) sockunion_get_addr(nexthop); - api.nexthop_num = 1; - api.nexthop = &nexthop_ipv6; + api_nh->gate.ipv6 = nexthop->sin6.sin6_addr; + api_nh->type = NEXTHOP_TYPE_IPV6; } if (ifp) { - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); - api.ifindex_num = 1; - api.ifindex = &ifp->ifindex; + api_nh->ifindex = ifp->ifindex; + if (api_nh->type == NEXTHOP_TYPE_IPV6) + api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; + else + api_nh->type = NEXTHOP_TYPE_IFINDEX; } if (mtu) { SET_FLAG(api.message, ZAPI_MESSAGE_MTU); @@ -178,13 +183,12 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix add ? "add" : "del", inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])), p->prefixlen, - nexthop ? inet_ntop(AF_INET6, api.nexthop[0], buf[1], sizeof(buf[1])) : "", + nexthop ? inet_ntop(AF_INET6, &api_nh->gate.ipv6, buf[1], sizeof(buf[1])) : "", api.metric, api.nexthop_num, ifp->name); } - zapi_ipv6_route( - add ? ZEBRA_IPV6_ROUTE_ADD : ZEBRA_IPV6_ROUTE_DELETE, - zclient, (struct prefix_ipv6 *) p, NULL, &api); + zclient_route_send(add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, + zclient, &api); } } From 5fef910e7121b655ef50f12398c2766bde12b6ac Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 20 Aug 2017 21:18:58 -0300 Subject: [PATCH 31/79] ospfd: use the new API to send routes to zebra Signed-off-by: Renato Westphal --- ospfd/ospf_zebra.c | 221 +++++++++++++-------------------------------- 1 file changed, 63 insertions(+), 158 deletions(-) diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 6d9d56d92d..53b68a022b 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -333,87 +333,68 @@ static int ospf_interface_link_params(int command, struct zclient *zclient, void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or) { - u_char message; + struct zapi_route api; + struct zapi_nexthop *api_nh; u_char distance; - u_int32_t flags; - int psize; - struct stream *s; struct ospf_path *path; struct listnode *node; struct ospf *ospf = ospf_lookup(); + int count = 0; - message = 0; - flags = 0; + memset(&api, 0, sizeof(api)); + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_OSPF; + api.instance = ospf->instance; + api.safi = SAFI_UNICAST; - /* OSPF pass nexthop and metric */ - SET_FLAG(message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG(message, ZAPI_MESSAGE_METRIC); + memcpy(&api.prefix, p, sizeof(*p)); + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = or->paths->count; - /* Distance value. */ - distance = ospf_distance_apply(p, or); - if (distance) - SET_FLAG(message, ZAPI_MESSAGE_DISTANCE); + /* Metric value. */ + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL) + api.metric = or->cost + or->u.ext.type2_cost; + else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL) + api.metric = or->u.ext.type2_cost; + else + api.metric = or->cost; /* Check if path type is ASE */ if (((or->path_type == OSPF_PATH_TYPE1_EXTERNAL) || (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)) - && (or->u.ext.tag > 0) && (or->u.ext.tag <= ROUTE_TAG_MAX)) - SET_FLAG(message, ZAPI_MESSAGE_TAG); + && (or->u.ext.tag > 0) && (or->u.ext.tag <= ROUTE_TAG_MAX)) { + SET_FLAG(api.message, ZAPI_MESSAGE_TAG); + api.tag = or->u.ext.tag; + } - /* Make packet. */ - s = zclient->obuf; - stream_reset(s); - - /* Put command, type, flags, message. */ - zclient_create_header(s, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); - stream_putc(s, ZEBRA_ROUTE_OSPF); - stream_putw(s, ospf->instance); - stream_putl(s, flags); - stream_putc(s, message); - stream_putw(s, SAFI_UNICAST); - - /* Put prefix information. */ - psize = PSIZE(p->prefixlen); - stream_putc(s, p->prefixlen); - stream_write(s, (u_char *)&p->prefix, psize); - - /* Nexthop count. */ - stream_putc(s, or->paths->count); + /* Distance value. */ + distance = ospf_distance_apply(p, or); + if (distance) { + SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); + api.distance = distance; + } /* Nexthop, ifindex, distance and metric information. */ for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) { + api_nh = &api.nexthops[count]; #ifdef HAVE_NETLINK if (path->unnumbered || (path->nexthop.s_addr != INADDR_ANY && path->ifindex != 0)) { - stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr(s, &path->nexthop); - stream_putl(s, path->ifindex); - } else if (path->nexthop.s_addr != INADDR_ANY) { - stream_putc(s, NEXTHOP_TYPE_IPV4); - stream_put_in_addr(s, &path->nexthop); - } else { - stream_putc(s, NEXTHOP_TYPE_IFINDEX); - if (path->ifindex) - stream_putl(s, path->ifindex); - else - stream_putl(s, 0); - } #else /* HAVE_NETLINK */ if (path->nexthop.s_addr != INADDR_ANY && path->ifindex != 0) { - stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr(s, &path->nexthop); - stream_putl(s, path->ifindex); - } else if (path->nexthop.s_addr != INADDR_ANY) { - stream_putc(s, NEXTHOP_TYPE_IPV4); - stream_put_in_addr(s, &path->nexthop); - } else { - stream_putc(s, NEXTHOP_TYPE_IFINDEX); - if (path->ifindex) - stream_putl(s, path->ifindex); - else - stream_putl(s, 0); - } #endif /* HAVE_NETLINK */ + api_nh->gate.ipv4 = path->nexthop; + api_nh->ifindex = path->ifindex; + api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; + } else if (path->nexthop.s_addr != INADDR_ANY) { + api_nh->gate.ipv4 = path->nexthop; + api_nh->type = NEXTHOP_TYPE_IPV4; + } else { + api_nh->ifindex = path->ifindex; + api_nh->type = NEXTHOP_TYPE_IFINDEX; + } + count++; if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { char buf[2][INET_ADDRSTRLEN]; @@ -427,118 +408,45 @@ void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or) } } - if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) - stream_putc(s, distance); - if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) { - if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL) - stream_putl(s, or->cost + or->u.ext.type2_cost); - else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL) - stream_putl(s, or->u.ext.type2_cost); - else - stream_putl(s, or->cost); - } - - if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG)) - stream_putl(s, or->u.ext.tag); - - stream_putw_at(s, 0, stream_get_endp(s)); - - zclient_send_message(zclient); + zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); } void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or) { - u_char message; - u_char distance; - u_int32_t flags; - int psize; - struct stream *s; - struct ospf_path *path; - struct listnode *node; + struct zapi_route api; struct ospf *ospf = ospf_lookup(); - message = 0; - flags = 0; - /* Distance value. */ - distance = ospf_distance_apply(p, or); - /* Make packet. */ - s = zclient->obuf; - stream_reset(s); + memset(&api, 0, sizeof(api)); + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_OSPF; + api.instance = ospf->instance; + api.safi = SAFI_UNICAST; + memcpy(&api.prefix, p, sizeof(*p)); - /* Put command, type, flags, message. */ - zclient_create_header(s, ZEBRA_IPV4_ROUTE_DELETE, VRF_DEFAULT); - stream_putc(s, ZEBRA_ROUTE_OSPF); - stream_putw(s, ospf->instance); - stream_putl(s, flags); - stream_putc(s, message); - stream_putw(s, SAFI_UNICAST); - - /* Put prefix information. */ - psize = PSIZE(p->prefixlen); - stream_putc(s, p->prefixlen); - stream_write(s, (u_char *)&p->prefix, psize); - - /* Nexthop count. */ - stream_putc(s, or->paths->count); - - /* Nexthop, ifindex, distance and metric information. */ - for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) { - if (path->nexthop.s_addr != INADDR_ANY && path->ifindex != 0) { - stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr(s, &path->nexthop); - stream_putl(s, path->ifindex); - } else if (path->nexthop.s_addr != INADDR_ANY) { - stream_putc(s, NEXTHOP_TYPE_IPV4); - stream_put_in_addr(s, &path->nexthop); - } else { - stream_putc(s, NEXTHOP_TYPE_IFINDEX); - stream_putl(s, path->ifindex); - } - - if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug("Zebra: Route delete %s/%d nexthop %s", - inet_ntop(AF_INET, &p->prefix, buf[0], - sizeof(buf[0])), - p->prefixlen, - inet_ntop(AF_INET, &path->nexthop, buf[1], - sizeof(buf[1]))); - } + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { + char buf[INET_ADDRSTRLEN]; + zlog_debug("Zebra: Route delete %s/%d", + inet_ntop(AF_INET, &p->prefix, buf, sizeof(buf[0])), + p->prefixlen); } - if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) - stream_putc(s, distance); - if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) { - if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL) - stream_putl(s, or->cost + or->u.ext.type2_cost); - else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL) - stream_putl(s, or->u.ext.type2_cost); - else - stream_putl(s, or->cost); - } - - stream_putw_at(s, 0, stream_get_endp(s)); - - zclient_send_message(zclient); + zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); } void ospf_zebra_add_discard(struct prefix_ipv4 *p) { - struct zapi_ipv4 api; + struct zapi_route api; struct ospf *ospf = ospf_lookup(); + memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.flags = ZEBRA_FLAG_BLACKHOLE; - api.message = 0; api.safi = SAFI_UNICAST; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.ifindex_num = 0; - api.tag = 0; + memcpy(&api.prefix, p, sizeof(*p)); - zapi_ipv4_route(ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api); + zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) zlog_debug("Zebra: Route add discard %s/%d", @@ -547,21 +455,18 @@ void ospf_zebra_add_discard(struct prefix_ipv4 *p) void ospf_zebra_delete_discard(struct prefix_ipv4 *p) { - struct zapi_ipv4 api; + struct zapi_route api; struct ospf *ospf = ospf_lookup(); + memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.flags = ZEBRA_FLAG_BLACKHOLE; - api.message = 0; api.safi = SAFI_UNICAST; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.ifindex_num = 0; - api.tag = 0; + memcpy(&api.prefix, p, sizeof(*p)); - zapi_ipv4_route(ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api); + zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) zlog_debug("Zebra: Route delete discard %s/%d", From 5afa1c6be2b538c2beea713420c0e41e4b49c536 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 20 Aug 2017 21:19:07 -0300 Subject: [PATCH 32/79] ospf6d: use the new API to send routes to zebra Signed-off-by: Renato Westphal --- ospf6d/ospf6_route.c | 8 ++-- ospf6d/ospf6_route.h | 4 +- ospf6d/ospf6_zebra.c | 93 ++++++++++++-------------------------------- 3 files changed, 31 insertions(+), 74 deletions(-) diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index bfe583a911..03791ad7a0 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -285,8 +285,7 @@ void ospf6_add_nexthop(struct list *nh_list, int ifindex, struct in6_addr *addr) } void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route, - ifindex_t *ifindexes, - struct in6_addr **nexthop_addr, + struct zapi_nexthop nexthops[], int entries) { struct ospf6_nexthop *nh; @@ -307,8 +306,9 @@ void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route, IFNAMSIZ, ifname, nh->ifindex); } if (i < entries) { - nexthop_addr[i] = &nh->address; - ifindexes[i] = nh->ifindex; + nexthops[i].gate.ipv6 = nh->address; + nexthops[i].ifindex = nh->ifindex; + nexthops[i].type = NEXTHOP_TYPE_IPV6_IFINDEX; i++; } else { return; diff --git a/ospf6d/ospf6_route.h b/ospf6d/ospf6_route.h index 166074fb70..9eacadbdb7 100644 --- a/ospf6d/ospf6_route.h +++ b/ospf6d/ospf6_route.h @@ -22,6 +22,7 @@ #define OSPF6_ROUTE_H #include "command.h" +#include "zclient.h" #define OSPF6_MULTI_PATH_LIMIT 4 @@ -266,8 +267,7 @@ extern int ospf6_num_nexthops(struct list *nh_list); extern int ospf6_route_cmp_nexthops(struct ospf6_route *a, struct ospf6_route *b); extern void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route, - ifindex_t *ifindices, - struct in6_addr **addr, + struct zapi_nexthop nexthops[], int entries); extern int ospf6_route_get_first_nh_index(struct ospf6_route *route); diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 1c266da888..5655502879 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -333,13 +333,11 @@ DEFUN (show_zebra, #define REM 1 static void ospf6_zebra_route_update(int type, struct ospf6_route *request) { - struct zapi_ipv6 api; + struct zapi_route api; char buf[PREFIX2STR_BUFFER]; int nhcount; - struct in6_addr **nexthops; - ifindex_t *ifindexes; int ret = 0; - struct prefix_ipv6 *dest; + struct prefix *dest; if (IS_OSPF6_DEBUG_ZEBRA(SEND)) { prefix2str(&request->prefix, buf, sizeof(buf)); @@ -387,36 +385,16 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request) return; } - /* allocate memory for nexthop_list */ - nexthops = - XCALLOC(MTYPE_OSPF6_OTHER, nhcount * sizeof(struct in6_addr *)); - if (nexthops == NULL) { - zlog_warn("Can't send route to zebra: malloc failed"); - return; - } - - /* allocate memory for ifindex_list */ - ifindexes = XCALLOC(MTYPE_OSPF6_OTHER, nhcount * sizeof(ifindex_t)); - if (ifindexes == NULL) { - zlog_warn("Can't send route to zebra: malloc failed"); - XFREE(MTYPE_OSPF6_OTHER, nexthops); - return; - } - - ospf6_route_zebra_copy_nexthops(request, ifindexes, nexthops, nhcount); + dest = &request->prefix; + memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF6; - api.instance = 0; - api.flags = 0; - api.message = 0; api.safi = SAFI_UNICAST; + api.prefix = *dest; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = nhcount; - api.nexthop = nexthops; - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); - api.ifindex_num = nhcount; - api.ifindex = ifindexes; + ospf6_route_zebra_copy_nexthops(request, api.nexthops, nhcount); SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); api.metric = (request->path.metric_type == 2 ? request->path.u.cost_e2 : request->path.cost); @@ -425,26 +403,20 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request) api.tag = request->path.tag; } - dest = (struct prefix_ipv6 *)&request->prefix; - SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); - api.distance = ospf6_distance_apply(dest, request); + api.distance = + ospf6_distance_apply((struct prefix_ipv6 *)dest, request); if (type == REM) - ret = zapi_ipv6_route(ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, - NULL, &api); + ret = zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); else - ret = zapi_ipv6_route(ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, - &api); + ret = zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); if (ret < 0) - zlog_err("zapi_ipv6_route() %s failed: %s", + zlog_err("zclient_route_send() %s failed: %s", (type == REM ? "delete" : "add"), safe_strerror(errno)); - XFREE(MTYPE_OSPF6_OTHER, nexthops); - XFREE(MTYPE_OSPF6_OTHER, ifindexes); - return; } @@ -460,40 +432,32 @@ void ospf6_zebra_route_update_remove(struct ospf6_route *request) void ospf6_zebra_add_discard(struct ospf6_route *request) { - struct zapi_ipv6 api; + struct zapi_route api; char buf[INET6_ADDRSTRLEN]; - struct prefix_ipv6 *dest; + struct prefix *dest = &request->prefix; if (!CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { + memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF6; api.flags = ZEBRA_FLAG_BLACKHOLE; - api.instance = 0; - api.message = 0; api.safi = SAFI_UNICAST; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.ifindex_num = 0; + api.prefix = *dest; - dest = (struct prefix_ipv6 *)&request->prefix; - - zapi_ipv6_route(ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, - &api); + zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); if (IS_OSPF6_DEBUG_ZEBRA(SEND)) zlog_debug("Zebra: Route add discard %s/%d", - inet_ntop(AF_INET6, &dest->prefix, buf, + inet_ntop(AF_INET6, &dest->u.prefix6, buf, INET6_ADDRSTRLEN), dest->prefixlen); SET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED); } else { - dest = (struct prefix_ipv6 *)&request->prefix; - if (IS_OSPF6_DEBUG_ZEBRA(SEND)) zlog_debug( "Zebra: Blackhole route present already %s/%d", - inet_ntop(AF_INET6, &dest->prefix, buf, + inet_ntop(AF_INET6, &dest->u.prefix6, buf, INET6_ADDRSTRLEN), dest->prefixlen); } @@ -501,39 +465,32 @@ void ospf6_zebra_add_discard(struct ospf6_route *request) void ospf6_zebra_delete_discard(struct ospf6_route *request) { - struct zapi_ipv6 api; + struct zapi_route api; char buf[INET6_ADDRSTRLEN]; - struct prefix_ipv6 *dest; + struct prefix *dest = &request->prefix; if (CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { + memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF6; api.flags = ZEBRA_FLAG_BLACKHOLE; - api.instance = 0; - api.message = 0; api.safi = SAFI_UNICAST; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.ifindex_num = 0; + api.prefix = *dest; - dest = (struct prefix_ipv6 *)&request->prefix; - - zapi_ipv6_route(ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, NULL, - &api); + zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); if (IS_OSPF6_DEBUG_ZEBRA(SEND)) zlog_debug("Zebra: Route delete discard %s/%d", - inet_ntop(AF_INET6, &dest->prefix, buf, + inet_ntop(AF_INET6, &dest->u.prefix6, buf, INET6_ADDRSTRLEN), dest->prefixlen); UNSET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED); } else { - dest = (struct prefix_ipv6 *)&request->prefix; if (IS_OSPF6_DEBUG_ZEBRA(SEND)) zlog_debug( "Zebra: Blackhole route already deleted %s/%d", - inet_ntop(AF_INET6, &dest->prefix, buf, + inet_ntop(AF_INET6, &dest->u.prefix6, buf, INET6_ADDRSTRLEN), dest->prefixlen); } From 9eed278b163d2175ee714869085a54f2c3726cca Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 23 Aug 2017 16:18:49 +0200 Subject: [PATCH 33/79] lib: centralized memstats-at-exit adds a new all-daemon "debug memstats-at-exit" command. Also saves memstats to a file in /tmp, useful if a long-running daemon is having weird issues (e.g. in a user install). Fixes: #437 Signed-off-by: David Lamparter --- bgpd/bgp_main.c | 3 --- lib/command.c | 17 +++++++++++++++++ lib/libfrr.c | 30 ++++++++++++++++++++++++++++++ lib/libfrr.h | 2 ++ lib/log.c | 2 +- lib/memory.c | 10 ++++++---- lib/memory.h | 4 +++- lib/sigevent.c | 2 +- tests/isisd/test_fuzz_isis_tlv.c | 2 +- tests/lib/cli/common_cli.c | 2 +- 10 files changed, 62 insertions(+), 12 deletions(-) diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 3bf9ea02d5..fa8c45b004 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -219,9 +219,6 @@ static __attribute__((__noreturn__)) void bgp_exit(int status) memset(bm, 0, sizeof(*bm)); frr_fini(); - - if (bgp_debug_count()) - log_memstats_stderr("bgpd"); exit(status); } diff --git a/lib/command.c b/lib/command.c index 45b5593a3e..f47bf81452 100644 --- a/lib/command.c +++ b/lib/command.c @@ -42,6 +42,7 @@ #include "command_graph.h" #include "qobj.h" #include "defaults.h" +#include "libfrr.h" DEFINE_MTYPE(LIB, HOST, "Host config") DEFINE_MTYPE(LIB, STRVEC, "String vector") @@ -555,6 +556,9 @@ static int config_write_host(struct vty *vty) else if (!host.motd) vty_out(vty, "no banner motd\n"); + if (debug_memstats_at_exit) + vty_out(vty, "!\ndebug memstats-at-exit\n"); + return 1; } @@ -2366,6 +2370,17 @@ DEFUN (no_config_log_timestamp_precision, return CMD_SUCCESS; } +DEFUN (debug_memstats, + debug_memstats_cmd, + "[no] debug memstats-at-exit", + NO_STR + DEBUG_STR + "Print memory type statistics at exit\n") +{ + debug_memstats_at_exit = !!strcmp(argv[0]->text, "no"); + return CMD_SUCCESS; +} + int cmd_banner_motd_file(const char *file) { int success = CMD_SUCCESS; @@ -2527,6 +2542,7 @@ void cmd_init(int terminal) /* Each node's basic commands. */ install_element(VIEW_NODE, &show_version_cmd); install_element(ENABLE_NODE, &show_startup_config_cmd); + install_element(ENABLE_NODE, &debug_memstats_cmd); if (terminal) { install_element(VIEW_NODE, &config_list_cmd); @@ -2560,6 +2576,7 @@ void cmd_init(int terminal) install_element(CONFIG_NODE, &hostname_cmd); install_element(CONFIG_NODE, &no_hostname_cmd); install_element(CONFIG_NODE, &frr_version_defaults_cmd); + install_element(CONFIG_NODE, &debug_memstats_cmd); if (terminal > 0) { install_element(CONFIG_NODE, &password_cmd); diff --git a/lib/libfrr.c b/lib/libfrr.c index 255f91ec71..c3ef04c673 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -52,6 +52,8 @@ char frr_zclientpath[256]; static char pidfile_default[256]; static char vtypath_default[256]; +bool debug_memstats_at_exit = 0; + static char comb_optstr[256]; static struct option comb_lo[64]; static struct option *comb_next_lo = &comb_lo[0]; @@ -841,6 +843,10 @@ void frr_early_fini(void) void frr_fini(void) { + FILE *fp; + char filename[128]; + int have_leftovers; + hook_call(frr_fini); /* memory_init -> nothing needed */ @@ -851,4 +857,28 @@ void frr_fini(void) thread_master_free(master); closezlog(); /* frrmod_init -> nothing needed / hooks */ + + if (!debug_memstats_at_exit) + return; + + have_leftovers = log_memstats(stderr, di->name); + + /* in case we decide at runtime that we want exit-memstats for + * a daemon, but it has no stderr because it's daemonized + * (only do this if we actually have something to print though) + */ + if (!have_leftovers) + return; + + snprintf(filename, sizeof(filename), + "/tmp/frr-memstats-%s-%llu-%llu", + di->name, + (unsigned long long)getpid(), + (unsigned long long)time(NULL)); + + fp = fopen(filename, "w"); + if (fp) { + log_memstats(fp, di->name); + fclose(fp); + } } diff --git a/lib/libfrr.h b/lib/libfrr.h index 8a15d168a1..f7d69eecb3 100644 --- a/lib/libfrr.h +++ b/lib/libfrr.h @@ -121,4 +121,6 @@ extern const char frr_moduledir[]; extern char frr_protoname[]; extern char frr_protonameinst[]; +extern bool debug_memstats_at_exit; + #endif /* _ZEBRA_FRR_H */ diff --git a/lib/log.c b/lib/log.c index 5c89e7080e..5b2429b31a 100644 --- a/lib/log.c +++ b/lib/log.c @@ -701,7 +701,7 @@ void _zlog_assert_failed(const char *assertion, const char *file, assertion, file, line, (function ? function : "?")); zlog_backtrace(LOG_CRIT); zlog_thread_info(LOG_CRIT); - log_memstats_stderr("log"); + log_memstats(stderr, "log"); abort(); } diff --git a/lib/memory.c b/lib/memory.c index 0ccc204002..c684c7605c 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -104,6 +104,7 @@ int qmem_walk(qmem_walk_fn *func, void *arg) } struct exit_dump_args { + FILE *fp; const char *prefix; int error; }; @@ -113,7 +114,7 @@ static int qmem_exit_walker(void *arg, struct memgroup *mg, struct memtype *mt) struct exit_dump_args *eda = arg; if (!mt) { - fprintf(stderr, + fprintf(eda->fp, "%s: showing active allocations in " "memory group %s\n", eda->prefix, mg->name); @@ -122,15 +123,16 @@ static int qmem_exit_walker(void *arg, struct memgroup *mg, struct memtype *mt) char size[32]; eda->error++; snprintf(size, sizeof(size), "%10zu", mt->size); - fprintf(stderr, "%s: memstats: %-30s: %6zu * %s\n", + fprintf(eda->fp, "%s: memstats: %-30s: %6zu * %s\n", eda->prefix, mt->name, mt->n_alloc, mt->size == SIZE_VAR ? "(variably sized)" : size); } return 0; } -void log_memstats_stderr(const char *prefix) +int log_memstats(FILE *fp, const char *prefix) { - struct exit_dump_args eda = {.prefix = prefix, .error = 0}; + struct exit_dump_args eda = { .fp = fp, .prefix = prefix, .error = 0 }; qmem_walk(qmem_exit_walker, &eda); + return eda.error; } diff --git a/lib/memory.h b/lib/memory.h index d5facad583..132d4abd30 100644 --- a/lib/memory.h +++ b/lib/memory.h @@ -18,6 +18,7 @@ #define _QUAGGA_MEMORY_H #include +#include #include #define array_size(ar) (sizeof(ar) / sizeof(ar[0])) @@ -194,7 +195,8 @@ static inline size_t mtype_stats_alloc(struct memtype *mt) * last value from qmem_walk_fn. */ typedef int qmem_walk_fn(void *arg, struct memgroup *mg, struct memtype *mt); extern int qmem_walk(qmem_walk_fn *func, void *arg); -extern void log_memstats_stderr(const char *); +extern int log_memstats(FILE *fp, const char *); +#define log_memstats_stderr(prefix) log_memstats(stderr, prefix) extern void memory_oom(size_t size, const char *name); diff --git a/lib/sigevent.c b/lib/sigevent.c index 2a04fa23cb..d55f368dfb 100644 --- a/lib/sigevent.c +++ b/lib/sigevent.c @@ -245,7 +245,7 @@ core_handler(int signo #endif ); /* dump memory stats on core */ - log_memstats_stderr("core_handler"); + log_memstats(stderr, "core_handler"); abort(); } diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c index 6727e663f5..e61e9639ee 100644 --- a/tests/isisd/test_fuzz_isis_tlv.c +++ b/tests/isisd/test_fuzz_isis_tlv.c @@ -23,7 +23,7 @@ static bool atexit_registered; static void show_meminfo_at_exit(void) { - log_memstats_stderr("isis fuzztest"); + log_memstats(stderr, "isis fuzztest"); } static int comp_line(const void *p1, const void *p2) diff --git a/tests/lib/cli/common_cli.c b/tests/lib/cli/common_cli.c index 77f1610fe2..0fd2f80a39 100644 --- a/tests/lib/cli/common_cli.c +++ b/tests/lib/cli/common_cli.c @@ -53,7 +53,7 @@ static void vty_do_exit(int isexit) thread_master_free(master); closezlog(); - log_memstats_stderr("testcli"); + log_memstats(stderr, "testcli"); if (!isexit) exit(0); } From 6bd2b3608d6dc1eca171c30916f029f6f867db6b Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 23 Aug 2017 16:23:17 +0200 Subject: [PATCH 34/79] lib: fix cosmetic issue with exit race if we're using --terminal, the daemon may in some cases exit fast enough for the parent to see this; this resulted in a confusing/bogus "failed to start, exited 0" message. Signed-off-by: David Lamparter --- lib/libfrr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/libfrr.c b/lib/libfrr.c index c3ef04c673..9944fdd1e1 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -641,7 +641,10 @@ static void frr_daemon_wait(int fd) exit(0); /* child failed one way or another ... */ - if (WIFEXITED(exitstat)) + if (WIFEXITED(exitstat) && WEXITSTATUS(exitstat) == 0) + /* can happen in --terminal case if exit is fast enough */ + (void)0; + else if (WIFEXITED(exitstat)) fprintf(stderr, "%s failed to start, exited %d\n", di->name, WEXITSTATUS(exitstat)); else if (WIFSIGNALED(exitstat)) From 427f8e61bb711b51891dbaee845215ca228951f1 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 23 Aug 2017 16:54:15 +0200 Subject: [PATCH 35/79] ospf6d: properly update prefix list references Register add/delete hooks with the prefix list code to properly change ospf6_area's prefix list in/out pointers. There are 2 other uncached uses of prefix lists in the ASBR route-map code and the interface code; these should probably be cached too. (To be fixed another day...) Fixes: #453 Signed-off-by: David Lamparter --- lib/plist.c | 8 ++++++ lib/plist.h | 1 + ospf6d/ospf6_abr.c | 59 ++++++++++++++++++--------------------------- ospf6d/ospf6_area.c | 41 ++++++++++++++++++------------- ospf6d/ospf6_area.h | 1 + ospf6d/ospf6d.c | 18 ++++++++++++++ 6 files changed, 75 insertions(+), 53 deletions(-) diff --git a/lib/plist.c b/lib/plist.c index b0cf42ca49..ebd628d724 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -122,6 +122,14 @@ const char *prefix_list_name(struct prefix_list *plist) return plist->name; } +afi_t prefix_list_afi(struct prefix_list *plist) +{ + if (plist->master == &prefix_master_ipv4 + || plist->master == &prefix_master_orf_v4) + return AFI_IP; + return AFI_IP6; +} + /* Lookup prefix_list from list of prefix_list by name. */ static struct prefix_list *prefix_list_lookup_do(afi_t afi, int orf, const char *name) diff --git a/lib/plist.h b/lib/plist.h index 73d8da509a..3eba3046ae 100644 --- a/lib/plist.h +++ b/lib/plist.h @@ -48,6 +48,7 @@ extern void prefix_list_add_hook(void (*func)(struct prefix_list *)); extern void prefix_list_delete_hook(void (*func)(struct prefix_list *)); extern const char *prefix_list_name(struct prefix_list *); +extern afi_t prefix_list_afi(struct prefix_list *); extern struct prefix_list *prefix_list_lookup(afi_t, const char *); extern enum prefix_list_type prefix_list_apply(struct prefix_list *, void *); diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index f198ac4af6..36528d063c 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -386,27 +386,20 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, } /* Check filter-list */ - if (PREFIX_NAME_OUT(area)) { - if (PREFIX_LIST_OUT(area) == NULL) - PREFIX_LIST_OUT(area) = prefix_list_lookup( - AFI_IP6, PREFIX_NAME_OUT(area)); - - if (PREFIX_LIST_OUT(area)) - if (prefix_list_apply(PREFIX_LIST_OUT(area), - &route->prefix) - != PREFIX_PERMIT) { - if (is_debug) { - inet_ntop(AF_INET, - &(ADV_ROUTER_IN_PREFIX( - &route->prefix)), - buf, sizeof(buf)); - zlog_debug( - "prefix %s was denied by filter-list out", - buf); - } - return 0; + if (PREFIX_LIST_OUT(area)) + if (prefix_list_apply(PREFIX_LIST_OUT(area), &route->prefix) + != PREFIX_PERMIT) { + if (is_debug) { + inet_ntop(AF_INET, + &(ADV_ROUTER_IN_PREFIX( + &route->prefix)), + buf, sizeof(buf)); + zlog_debug( + "prefix %s was denied by filter-list out", + buf); } - } + return 0; + } /* the route is going to be originated. store it in area's summary_table */ @@ -873,22 +866,16 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) } /* Check input prefix-list */ - if (PREFIX_NAME_IN(oa)) { - if (PREFIX_LIST_IN(oa) == NULL) - PREFIX_LIST_IN(oa) = - prefix_list_lookup(AFI_IP6, PREFIX_NAME_IN(oa)); - - if (PREFIX_LIST_IN(oa)) - if (prefix_list_apply(PREFIX_LIST_IN(oa), &prefix) - != PREFIX_PERMIT) { - if (is_debug) - zlog_debug( - "Prefix was denied by prefix-list"); - if (old) - ospf6_route_remove(old, table); - return; - } - } + if (PREFIX_LIST_IN(oa)) + if (prefix_list_apply(PREFIX_LIST_IN(oa), &prefix) + != PREFIX_PERMIT) { + if (is_debug) + zlog_debug( + "Prefix was denied by prefix-list"); + if (old) + ospf6_route_remove(old, table); + return; + } /* (5),(6): the path preference is handled by the sorting in the routing table. Always install the path by substituting diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index a4cc0bf420..649d7a1000 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -45,6 +45,8 @@ #include "ospf6_asbr.h" #include "ospf6d.h" +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PLISTNAME, "Prefix list name") + int ospf6_area_cmp(void *va, void *vb) { struct ospf6_area *oa = (struct ospf6_area *)va; @@ -579,17 +581,15 @@ DEFUN (area_filter_list, plist = prefix_list_lookup(AFI_IP6, plistname); if (strmatch(inout, "in")) { PREFIX_LIST_IN(area) = plist; - if (PREFIX_NAME_IN(area)) - free(PREFIX_NAME_IN(area)); - - PREFIX_NAME_IN(area) = strdup(plistname); + XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_IN(area)); + PREFIX_NAME_IN(area) = XSTRDUP(MTYPE_OSPF6_PLISTNAME, + plistname); ospf6_abr_reimport(area); } else { PREFIX_LIST_OUT(area) = plist; - if (PREFIX_NAME_OUT(area)) - free(PREFIX_NAME_OUT(area)); - - PREFIX_NAME_OUT(area) = strdup(plistname); + XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_OUT(area)); + PREFIX_NAME_OUT(area) = XSTRDUP(MTYPE_OSPF6_PLISTNAME, + plistname); ospf6_abr_enable_area(area); } @@ -622,27 +622,34 @@ DEFUN (no_area_filter_list, return CMD_SUCCESS; PREFIX_LIST_IN(area) = NULL; - if (PREFIX_NAME_IN(area)) - free(PREFIX_NAME_IN(area)); - - PREFIX_NAME_IN(area) = NULL; + XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_IN(area)); ospf6_abr_reimport(area); } else { if (PREFIX_NAME_OUT(area)) if (!strmatch(PREFIX_NAME_OUT(area), plistname)) return CMD_SUCCESS; - PREFIX_LIST_OUT(area) = NULL; - if (PREFIX_NAME_OUT(area)) - free(PREFIX_NAME_OUT(area)); - - PREFIX_NAME_OUT(area) = NULL; + XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_OUT(area)); ospf6_abr_enable_area(area); } return CMD_SUCCESS; } +void ospf6_area_plist_update(struct prefix_list *plist, int add) +{ + struct ospf6_area *oa; + struct listnode *n; + const char *name = prefix_list_name(plist); + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) { + if (!strcmp(PREFIX_NAME_IN(oa), name)) + PREFIX_LIST_IN(oa) = add ? plist : NULL; + if (!strcmp(PREFIX_NAME_OUT(oa), name)) + PREFIX_LIST_OUT(oa) = add ? plist : NULL; + } +} + DEFUN (area_import_list, area_import_list_cmd, "area A.B.C.D import-list NAME", diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h index 4bc24a6dd8..d212d92387 100644 --- a/ospf6d/ospf6_area.h +++ b/ospf6d/ospf6_area.h @@ -122,6 +122,7 @@ extern void ospf6_area_disable(struct ospf6_area *); extern void ospf6_area_show(struct vty *, struct ospf6_area *); +extern void ospf6_area_plist_update(struct prefix_list *plist, int add); extern void ospf6_area_config_write(struct vty *vty); extern void ospf6_area_init(void); diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c index f6b9e0ec14..84a56fb505 100644 --- a/ospf6d/ospf6d.c +++ b/ospf6d/ospf6d.c @@ -24,6 +24,7 @@ #include "linklist.h" #include "vty.h" #include "command.h" +#include "plist.h" #include "ospf6_proto.h" #include "ospf6_network.h" @@ -1139,6 +1140,20 @@ DEFUN (show_ipv6_ospf6_linkstate_detail, return CMD_SUCCESS; } +static void ospf6_plist_add(struct prefix_list *plist) +{ + if (prefix_list_afi(plist) != AFI_IP6) + return; + ospf6_area_plist_update(plist, 1); +} + +static void ospf6_plist_del(struct prefix_list *plist) +{ + if (prefix_list_afi(plist) != AFI_IP6) + return; + ospf6_area_plist_update(plist, 0); +} + /* Install ospf related commands. */ void ospf6_init(void) { @@ -1154,6 +1169,9 @@ void ospf6_init(void) ospf6_asbr_init(); ospf6_abr_init(); + prefix_list_add_hook(ospf6_plist_add); + prefix_list_delete_hook(ospf6_plist_del); + ospf6_bfd_init(); install_node(&debug_node, config_write_ospf6_debug); From 3cbb67f2294305ab8046db0405b0d486650d30dd Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 23 Aug 2017 17:06:24 +0200 Subject: [PATCH 36/79] lib: better warnings for install_element Also fixes misuse of vector_slot() - that one doesn't check for access beyond end of vector... And print node names in grammar sandbox "printall". Fixes: #543 Signed-off-by: David Lamparter --- lib/command.c | 32 ++++++++++++++++++-------------- lib/grammar_sandbox.c | 3 ++- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/lib/command.c b/lib/command.c index f47bf81452..c86025a3bd 100644 --- a/lib/command.c +++ b/lib/command.c @@ -360,21 +360,23 @@ void install_element(enum node_type ntype, struct cmd_element *cmd) return; } - cnode = vector_slot(cmdvec, ntype); + cnode = vector_lookup(cmdvec, ntype); if (cnode == NULL) { fprintf(stderr, - "Command node %d doesn't exist, please check it\n", - ntype); - fprintf(stderr, - "Have you called install_node before this install_element?\n"); + "%s[%s]:\n" + "\tnode %d (%s) does not exist.\n" + "\tplease call install_node() before install_element()\n", + cmd->name, cmd->string, ntype, node_names[ntype]); exit(EXIT_FAILURE); } if (hash_lookup(cnode->cmd_hash, cmd) != NULL) { fprintf(stderr, - "Multiple command installs to node %d of command:\n%s\n", - ntype, cmd->string); + "%s[%s]:\n" + "\tnode %d (%s) already has this command installed.\n" + "\tduplicate install_element call?\n", + cmd->name, cmd->string, ntype, node_names[ntype]); return; } @@ -407,21 +409,23 @@ void uninstall_element(enum node_type ntype, struct cmd_element *cmd) return; } - cnode = vector_slot(cmdvec, ntype); + cnode = vector_lookup(cmdvec, ntype); if (cnode == NULL) { fprintf(stderr, - "Command node %d doesn't exist, please check it\n", - ntype); - fprintf(stderr, - "Have you called install_node before this install_element?\n"); + "%s[%s]:\n" + "\tnode %d (%s) does not exist.\n" + "\tplease call install_node() before uninstall_element()\n", + cmd->name, cmd->string, ntype, node_names[ntype]); exit(EXIT_FAILURE); } if (hash_release(cnode->cmd_hash, cmd) == NULL) { fprintf(stderr, - "Trying to uninstall non-installed command (node %d):\n%s\n", - ntype, cmd->string); + "%s[%s]:\n" + "\tnode %d (%s) does not have this command installed.\n" + "\tduplicate uninstall_element call?\n", + cmd->name, cmd->string, ntype, node_names[ntype]); return; } diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c index 96ecfa44d3..3c6396f347 100644 --- a/lib/grammar_sandbox.c +++ b/lib/grammar_sandbox.c @@ -404,7 +404,8 @@ DEFUN (grammar_findambig, nodegraph = cnode->cmdgraph; if (!nodegraph) continue; - vty_out(vty, "scanning node %d\n", scannode - 1); + vty_out(vty, "scanning node %d (%s)\n", + scannode - 1, node_names[scannode - 1]); } commands = cmd_graph_permutations(nodegraph); From 67eb7a6c9910c121e7975e26eaae199cb03ff2b1 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 23 Aug 2017 17:33:17 +0200 Subject: [PATCH 37/79] python/clippy: make output file writing less weird This should stomp out any parallel build issues in this regard. Fixes: #971 Signed-off-by: David Lamparter --- common.am | 3 +-- python/clidef.py | 2 +- python/clippy/__init__.py | 15 ++++++++++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/common.am b/common.am index b115a871b9..c0094b1b88 100644 --- a/common.am +++ b/common.am @@ -13,8 +13,7 @@ CLIPPY_DEPS = $(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py SUFFIXES = _clippy.c .proto .pb-c.c .pb-c.h .pb.h .c_clippy.c: @{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; } - $(AM_V_CLIPPY)$(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py $< > $@.tmp - @{ test -f $@ && diff $@.tmp $@ >/dev/null 2>/dev/null; } && rm $@.tmp || mv $@.tmp $@ + $(AM_V_CLIPPY)$(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py -o $@ $< ## automake's "ylwrap" is a great piece of GNU software... not. .l.c: diff --git a/python/clidef.py b/python/clidef.py index 8e3c7595b7..aa6cd18b8b 100644 --- a/python/clidef.py +++ b/python/clidef.py @@ -257,4 +257,4 @@ if __name__ == '__main__': process_file(args.cfile, ofd, dumpfd, args.all_defun) if args.o is not None: - clippy.wrdiff(args.o, ofd) + clippy.wrdiff(args.o, ofd, [args.cfile, os.path.realpath(__file__)]) diff --git a/python/clippy/__init__.py b/python/clippy/__init__.py index 82aa9495d4..41aeae6b4d 100644 --- a/python/clippy/__init__.py +++ b/python/clippy/__init__.py @@ -16,6 +16,7 @@ # with this program; see the file COPYING; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +import os, stat import _clippy from _clippy import parse, Graph, GraphNode @@ -47,7 +48,7 @@ def dump(graph): for i, depth in graph_iterate(graph): print('\t%s%s %r' % (' ' * (depth * 2), i.type, i.text)) -def wrdiff(filename, buf): +def wrdiff(filename, buf, reffiles = []): '''write buffer to file if contents changed''' expl = '' @@ -57,8 +58,16 @@ def wrdiff(filename, buf): try: old = open(filename, 'r').read() except: pass if old == buf: + for reffile in reffiles: + # ensure output timestamp is newer than inputs, for make + reftime = os.stat(reffile)[stat.ST_MTIME] + outtime = os.stat(filename)[stat.ST_MTIME] + if outtime <= reftime: + os.utime(filename, (reftime + 1, reftime + 1)) # sys.stderr.write('%s unchanged, not written\n' % (filename)) return - with open('.new.' + filename, 'w') as out: + + newname = '%s.new-%d' % (filename, os.getpid()) + with open(newname, 'w') as out: out.write(buf) - os.rename('.new.' + filename, filename) + os.rename(newname, filename) From 8d0ab76de11bdaf38d9c89291347497bfed2d18b Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 23 Aug 2017 18:21:30 +0200 Subject: [PATCH 38/79] bgpd: fix stats counting for IPv6 Fixes: #991 Signed-off-by: David Lamparter --- bgpd/bgp_route.c | 51 +++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index bb204b01f1..ee6f867cb9 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -20,6 +20,7 @@ */ #include +#include #include "prefix.h" #include "linklist.h" @@ -9347,6 +9348,7 @@ static const char *table_stats_strs[] = { struct bgp_table_stats { struct bgp_table *table; unsigned long long counts[BGP_STATS_MAX]; + double total_space; }; #if 0 @@ -9415,8 +9417,8 @@ static int bgp_table_stats_walker(struct thread *t) ts->counts[BGP_STATS_UNAGGREGATEABLE]++; /* announced address space */ if (space) - ts->counts[BGP_STATS_SPACE] += - 1 << (space - rn->p.prefixlen); + ts->total_space += pow(2.0, + space - rn->p.prefixlen); } else if (prn->info) ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++; @@ -9526,31 +9528,26 @@ static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi, break; case BGP_STATS_SPACE: vty_out(vty, "%-30s: ", table_stats_strs[i]); - vty_out(vty, "%12llu\n", ts.counts[i]); - if (ts.counts[BGP_STATS_MAXBITLEN] < 9) - break; - vty_out(vty, "%30s: ", "%% announced "); - vty_out(vty, "%12.2f\n", - 100 * (float)ts.counts[BGP_STATS_SPACE] - / (float)((uint64_t)1UL - << ts.counts - [BGP_STATS_MAXBITLEN])); - vty_out(vty, "%30s: ", "/8 equivalent "); - vty_out(vty, "%12.2f\n", - (float)ts.counts[BGP_STATS_SPACE] - / (float)(1UL - << (ts.counts - [BGP_STATS_MAXBITLEN] - - 8))); - if (ts.counts[BGP_STATS_MAXBITLEN] < 25) - break; - vty_out(vty, "%30s: ", "/24 equivalent "); - vty_out(vty, "%12.2f", - (float)ts.counts[BGP_STATS_SPACE] - / (float)(1UL - << (ts.counts - [BGP_STATS_MAXBITLEN] - - 24))); + vty_out(vty, "%12g\n", ts.total_space); + + if (afi == AFI_IP6) { + vty_out(vty, "%30s: ", "/32 equivalent "); + vty_out(vty, "%12g\n", + 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)); + } 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)); + vty_out(vty, "%30s: ", "/24 equivalent "); + vty_out(vty, "%12.2f\n", + ts.total_space * pow(2.0, -32+24)); + } break; default: vty_out(vty, "%-30s: ", table_stats_strs[i]); From c0e29be115fcf67e9b7ea77581fbcd94b3402672 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 23 Aug 2017 18:51:18 +0200 Subject: [PATCH 39/79] lib: prefix: try harder to not hash garbage With prefix_ptr or prefix_ls, there can still be stuff in a struct prefix that we shouldn't hash. Signed-off-by: David Lamparter --- lib/prefix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/prefix.c b/lib/prefix.c index 2f61eb6e8b..10f77bda87 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -1263,5 +1263,6 @@ unsigned prefix_hash_key(void *pp) * padding and unused prefix bytes. */ memset(©, 0, sizeof(copy)); prefix_copy(©, (struct prefix *)pp); - return jhash(©, sizeof(copy), 0x55aa5a5a); + return jhash(©, offsetof(struct prefix, u.prefix) + + PSIZE(copy.prefixlen), 0x55aa5a5a); } From 6a35bfba5e4e4135a29e87dc554b4e7f19f06831 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 23 Aug 2017 15:45:05 +0200 Subject: [PATCH 40/79] build: fix libtool stupidity wrt. parallel install there's no dependency between libraries and other things to be installed, but libtool in its 90ies design wants to relink libraries when installing them. Add manual dependencies to work around this. Signed-off-by: David Lamparter --- Makefile.am | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Makefile.am b/Makefile.am index 494fcd4d56..48f4e50daa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,6 +25,14 @@ pkginclude_HEADERS = nodist_pkginclude_HEADERS = dist_examples_DATA = +## libtool, the self-made GNU scourge +## ... this should fix relinking +## ... and AUTOMAKE_DUMMY is needed to prevent automake from treating this +## as overriding the normal targets... +$(AUTOMAKE_DUMMY)install-moduleLTLIBRARIES: install-libLTLIBRARIES +$(AUTOMAKE_DUMMY)install-binPROGRAMS: install-libLTLIBRARIES +$(AUTOMAKE_DUMMY)install-sbinPROGRAMS: install-libLTLIBRARIES + include lib/subdir.am include zebra/subdir.am include qpb/subdir.am From de1a880c4e1f24e5cb4a2c1e4793fed73107ecbe Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 23 Aug 2017 20:22:31 +0200 Subject: [PATCH 41/79] lib: split off compiler magic into its own file Also make timed notices available via CONFDATE. Signed-off-by: David Lamparter --- Makefile.am | 2 +- lib/compiler.h | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/memory.h | 36 +--------------------- lib/prefix.h | 17 +---------- lib/subdir.am | 1 + lib/vty.h | 19 +++--------- 6 files changed, 89 insertions(+), 67 deletions(-) create mode 100644 lib/compiler.h diff --git a/Makefile.am b/Makefile.am index 48f4e50daa..f204f8a724 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ include common.am AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib AM_CFLAGS = $(WERROR) -DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" +DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE) LIBCAP = @LIBCAP@ EXTRA_DIST = diff --git a/lib/compiler.h b/lib/compiler.h new file mode 100644 index 0000000000..49a2f2a422 --- /dev/null +++ b/lib/compiler.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2015-2017 David Lamparter, for NetDEF, Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _FRR_COMPILER_H +#define _FRR_COMPILER_H + +/* function attributes, use like + * void prototype(void) __attribute__((_CONSTRUCTOR(100))); + */ +#if defined(__clang__) +# if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 5) +# define _RET_NONNULL , returns_nonnull +# endif +# define _CONSTRUCTOR(x) constructor(x) +#elif defined(__GNUC__) +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) +# define _RET_NONNULL , returns_nonnull +# endif +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) +# define _CONSTRUCTOR(x) constructor(x) +# define _DESTRUCTOR(x) destructor(x) +# define _ALLOC_SIZE(x) alloc_size(x) +# endif +#endif + +#ifdef __sun +/* Solaris doesn't do constructor priorities due to linker restrictions */ +# undef _CONSTRUCTOR +# undef _DESTRUCTOR +#endif + +/* fallback versions */ +#ifndef _RET_NONNULL +# define _RET_NONNULL +#endif +#ifndef _CONSTRUCTOR +# define _CONSTRUCTOR(x) constructor +#endif +#ifndef _DESTRUCTOR +# define _DESTRUCTOR(x) destructor +#endif +#ifndef _ALLOC_SIZE +# define _ALLOC_SIZE(x) +#endif + +/* + * for warnings on macros, put in the macro content like this: + * #define MACRO BLA CPP_WARN("MACRO has been deprecated") + */ +#define CPP_STR(X) #X + +#if defined(__ICC) +#define CPP_NOTICE(text) _Pragma(CPP_STR(message __FILE__ ": " text)) +#define CPP_WARN(text) CPP_NOTICE(text) + +#elif (defined(__GNUC__) \ + && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) \ + || (defined(__clang__) \ + && (__clang_major__ >= 4 \ + || (__clang_major__ == 3 && __clang_minor__ >= 5))) +#define CPP_WARN(text) _Pragma(CPP_STR(GCC warning text)) +#define CPP_NOTICE(text) _Pragma(CPP_STR(message text)) + +#else +#define CPP_WARN(text) +#endif + +#endif /* _FRR_COMPILER_H */ diff --git a/lib/memory.h b/lib/memory.h index 132d4abd30..6de370514a 100644 --- a/lib/memory.h +++ b/lib/memory.h @@ -20,6 +20,7 @@ #include #include #include +#include "compiler.h" #define array_size(ar) (sizeof(ar) / sizeof(ar[0])) @@ -37,41 +38,6 @@ struct memgroup { const char *name; }; -#if defined(__clang__) -#if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 5) -# define _RET_NONNULL , returns_nonnull -#endif -# define _CONSTRUCTOR(x) constructor(x) -#elif defined(__GNUC__) -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) -# define _RET_NONNULL , returns_nonnull -#endif -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) -# define _CONSTRUCTOR(x) constructor(x) -# define _DESTRUCTOR(x) destructor(x) -# define _ALLOC_SIZE(x) alloc_size(x) -#endif -#endif - -#ifdef __sun -/* Solaris doesn't do constructor priorities due to linker restrictions */ -#undef _CONSTRUCTOR -#undef _DESTRUCTOR -#endif - -#ifndef _RET_NONNULL -# define _RET_NONNULL -#endif -#ifndef _CONSTRUCTOR -# define _CONSTRUCTOR(x) constructor -#endif -#ifndef _DESTRUCTOR -# define _DESTRUCTOR(x) destructor -#endif -#ifndef _ALLOC_SIZE -# define _ALLOC_SIZE(x) -#endif - /* macro usage: * * mydaemon.h diff --git a/lib/prefix.h b/lib/prefix.h index bc4abb492a..eab4ac2bb7 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -33,28 +33,13 @@ #endif #include "sockunion.h" #include "ipaddr.h" +#include "compiler.h" #ifndef ETH_ALEN #define ETH_ALEN 6 #endif /* for compatibility */ -#if defined(__ICC) -#define CPP_WARN_STR(X) #X -#define CPP_WARN(text) _Pragma(CPP_WARN_STR(message __FILE__ ": " text)) - -#elif (defined(__GNUC__) \ - && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) \ - || (defined(__clang__) \ - && (__clang_major__ >= 4 \ - || (__clang_major__ == 3 && __clang_minor__ >= 5))) -#define CPP_WARN_STR(X) #X -#define CPP_WARN(text) _Pragma(CPP_WARN_STR(GCC warning text)) - -#else -#define CPP_WARN(text) -#endif - #ifdef ETHER_ADDR_LEN #undef ETHER_ADDR_LEN #endif diff --git a/lib/subdir.am b/lib/subdir.am index 8545184228..d6349ba22d 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -85,6 +85,7 @@ pkginclude_HEADERS += \ lib/command.h \ lib/command_graph.h \ lib/command_match.h \ + lib/compiler.h \ lib/csv.h \ lib/distribute.h \ lib/event_counter.h \ diff --git a/lib/vty.h b/lib/vty.h index dcb8da225d..9acd62af3c 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -25,6 +25,7 @@ #include "log.h" #include "sockunion.h" #include "qobj.h" +#include "compiler.h" #define VTY_BUFSIZ 4096 #define VTY_MAXHIST 20 @@ -182,23 +183,11 @@ struct vty_arg { /* Integrated configuration file. */ #define INTEGRATE_DEFAULT_CONFIG "frr.conf" -/* for compatibility */ -#if defined(__ICC) -#define CPP_WARN_STR(X) #X -#define CPP_WARN(text) _Pragma(CPP_WARN_STR(message __FILE__ ": " text)) - -#elif (defined(__GNUC__) \ - && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) \ - || (defined(__clang__) \ - && (__clang_major__ >= 4 \ - || (__clang_major__ == 3 && __clang_minor__ >= 5))) -#define CPP_WARN_STR(X) #X -#define CPP_WARN(text) _Pragma(CPP_WARN_STR(GCC warning text)) - -#else -#define CPP_WARN(text) +#if CONFDATE > 20180401 +CPP_NOTICE("It's probably time to remove VTY_NEWLINE compatibility foo.") #endif +/* for compatibility */ #define VNL "\n" CPP_WARN("VNL has been replaced with \\n.") #define VTYNL "\n" CPP_WARN("VTYNL has been replaced with \\n.") #define VTY_NEWLINE "\n" CPP_WARN("VTY_NEWLINE has been replaced with \\n.") From 9913029c5c2a4e2d3d78d470aa9b91fdeb0fb007 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 20 Aug 2017 21:19:25 -0300 Subject: [PATCH 42/79] bgpd: use the new API to send routes to zebra Signed-off-by: Renato Westphal --- bgpd/bgp_zebra.c | 238 ++++++++++++++--------------------------- bgpd/rfapi/vnc_zebra.c | 66 ++++++------ 2 files changed, 114 insertions(+), 190 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 193775165c..2e8188b537 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -58,11 +58,6 @@ /* All information about zebra. */ struct zclient *zclient = NULL; -/* Growable buffer for nexthops sent to zebra */ -struct stream *bgp_nexthop_buf = NULL; -struct stream *bgp_ifindices_buf = NULL; -struct stream *bgp_label_buf = NULL; - /* These array buffers are used in making a copy of the attributes for route-map apply. Arrays are being used here to minimize mallocs and frees for the temporary copy of the attributes. @@ -1153,7 +1148,10 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, struct bgp_info *info, struct bgp *bgp, afi_t afi, safi_t safi) { - u_int32_t flags; + struct zapi_route api; + struct zapi_nexthop *api_nh; + int valid_nh_count = 0; + u_char distance; struct peer *peer; struct bgp_info *mpinfo; @@ -1172,7 +1170,14 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, if (bgp->main_zebra_update_hold) return; - flags = 0; + /* Make Zebra API structure. */ + memset(&api, 0, sizeof(api)); + api.vrf_id = bgp->vrf_id; + api.type = ZEBRA_ROUTE_BGP; + api.safi = safi; + api.prefix = *p; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + peer = info->peer; tag = info->attr->tag; @@ -1181,33 +1186,27 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, * in * the RIB */ if (info->sub_type == BGP_ROUTE_AGGREGATE) - SET_FLAG(flags, ZEBRA_FLAG_BLACKHOLE); + SET_FLAG(api.flags, ZEBRA_FLAG_BLACKHOLE); if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED || info->sub_type == BGP_ROUTE_AGGREGATE) { - SET_FLAG(flags, ZEBRA_FLAG_IBGP); - SET_FLAG(flags, ZEBRA_FLAG_INTERNAL); + SET_FLAG(api.flags, ZEBRA_FLAG_IBGP); + SET_FLAG(api.flags, ZEBRA_FLAG_INTERNAL); } if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1) || CHECK_FLAG(peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK) || bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK)) - SET_FLAG(flags, ZEBRA_FLAG_INTERNAL); + SET_FLAG(api.flags, ZEBRA_FLAG_INTERNAL); if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(info->attr)) { - struct zapi_ipv4 api; struct in_addr *nexthop; char buf[2][INET_ADDRSTRLEN]; - int valid_nh_count = 0; int has_valid_label = 0; - /* resize nexthop buffer size if necessary */ - stream_reset(bgp_nexthop_buf); nexthop = NULL; - stream_reset(bgp_label_buf); - if (bgp->table_map[afi][safi].name) BGP_INFO_ATTR_BUF_INIT(); @@ -1240,26 +1239,21 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, if (nexthop == NULL) continue; - stream_put(bgp_nexthop_buf, &nexthop, - sizeof(struct in_addr *)); + api_nh = &api.nexthops[valid_nh_count]; + api_nh->gate.ipv4 = *nexthop; + api_nh->type = NEXTHOP_TYPE_IPV4; + if (mpinfo->extra && bgp_is_valid_label(&mpinfo->extra->label)) { has_valid_label = 1; label = label_pton(&mpinfo->extra->label); - stream_put(bgp_label_buf, &label, - sizeof(mpls_label_t)); + + api_nh->label_num = 1; + api_nh->labels[0] = label; } valid_nh_count++; } - api.vrf_id = bgp->vrf_id; - api.flags = flags; - api.type = ZEBRA_ROUTE_BGP; - api.instance = 0; - api.message = 0; - api.safi = safi; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - if (has_valid_label) SET_FLAG(api.message, ZAPI_MESSAGE_LABEL); @@ -1272,24 +1266,15 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, * do not want to also encode the 0.0.0.0 nexthop for the * aggregate route. */ - if (CHECK_FLAG(flags, ZEBRA_FLAG_BLACKHOLE)) + if (CHECK_FLAG(api.flags, ZEBRA_FLAG_BLACKHOLE)) api.nexthop_num = 0; else api.nexthop_num = valid_nh_count; - api.nexthop = (struct in_addr **)STREAM_DATA(bgp_nexthop_buf); - if (has_valid_label) { - api.label_num = valid_nh_count; - api.label = (unsigned int *)STREAM_DATA(bgp_label_buf); - } else { - api.label_num = 0; - api.label = NULL; - } - api.ifindex_num = 0; SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); api.metric = metric; - api.tag = 0; + api.tag = 0; if (tag) { SET_FLAG(api.message, ZAPI_MESSAGE_TAG); api.tag = tag; @@ -1313,20 +1298,23 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, p->prefixlen, api.metric, api.tag, api.nexthop_num); for (i = 0; i < api.nexthop_num; i++) { + api_nh = &api.nexthops[i]; + label_buf[0] = '\0'; if (has_valid_label) sprintf(label_buf, "label %u", - api.label[i]); + api_nh->labels[0]); zlog_debug(" nhop [%d]: %s %s", i + 1, - inet_ntop(AF_INET, api.nexthop[i], - buf[1], sizeof(buf[1])), + inet_ntop(AF_INET, + &api_nh->gate.ipv4, buf[1], + sizeof(buf[1])), label_buf); } } - zapi_ipv4_route(valid_nh_count ? ZEBRA_IPV4_ROUTE_ADD - : ZEBRA_IPV4_ROUTE_DELETE, - zclient, (struct prefix_ipv4 *)p, &api); + zclient_route_send(valid_nh_count ? ZEBRA_ROUTE_ADD + : ZEBRA_ROUTE_DELETE, + zclient, &api); } /* We have to think about a IPv6 link-local address curse. */ @@ -1334,15 +1322,9 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, || (p->family == AF_INET && BGP_ATTR_NEXTHOP_AFI_IP6(info->attr))) { ifindex_t ifindex; struct in6_addr *nexthop; - struct zapi_ipv6 api; - int valid_nh_count = 0; char buf[2][INET6_ADDRSTRLEN]; int has_valid_label = 0; - stream_reset(bgp_nexthop_buf); - stream_reset(bgp_ifindices_buf); - stream_reset(bgp_label_buf); - ifindex = 0; nexthop = NULL; @@ -1399,30 +1381,22 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, if (ifindex == 0) continue; - stream_put(bgp_nexthop_buf, &nexthop, - sizeof(struct in6_addr *)); - stream_put(bgp_ifindices_buf, &ifindex, - sizeof(unsigned int)); + api_nh = &api.nexthops[valid_nh_count]; + api_nh->gate.ipv6 = *nexthop; + api_nh->ifindex = ifindex; + api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; if (mpinfo->extra && bgp_is_valid_label(&mpinfo->extra->label)) { has_valid_label = 1; label = label_pton(&mpinfo->extra->label); - stream_put(bgp_label_buf, &label, - sizeof(mpls_label_t)); + + api_nh->label_num = 1; + api_nh->labels[0] = label; } valid_nh_count++; } - /* Make Zebra API structure. */ - api.vrf_id = bgp->vrf_id; - api.flags = flags; - api.type = ZEBRA_ROUTE_BGP; - api.instance = 0; - api.message = 0; - api.safi = safi; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - if (has_valid_label) SET_FLAG(api.message, ZAPI_MESSAGE_LABEL); @@ -1435,26 +1409,15 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, * do not want to also encode the :: nexthop for the aggregate * route. */ - if (CHECK_FLAG(flags, ZEBRA_FLAG_BLACKHOLE)) + if (CHECK_FLAG(api.flags, ZEBRA_FLAG_BLACKHOLE)) api.nexthop_num = 0; else api.nexthop_num = valid_nh_count; - api.nexthop = (struct in6_addr **)STREAM_DATA(bgp_nexthop_buf); - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); - api.ifindex_num = valid_nh_count; - api.ifindex = (ifindex_t *)STREAM_DATA(bgp_ifindices_buf); - if (has_valid_label) { - api.label_num = valid_nh_count; - api.label = (unsigned int *)STREAM_DATA(bgp_label_buf); - } else { - api.label_num = 0; - api.label = NULL; - } SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); api.metric = metric; - api.tag = 0; + api.tag = 0; if (tag) { SET_FLAG(api.message, ZAPI_MESSAGE_TAG); api.tag = tag; @@ -1478,33 +1441,31 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, buf[0], sizeof(buf[0])), p->prefixlen, api.metric, api.tag); for (i = 0; i < api.nexthop_num; i++) { + api_nh = &api.nexthops[i]; + label_buf[0] = '\0'; if (has_valid_label) sprintf(label_buf, "label %u", - api.label[i]); + api_nh->labels[0]); zlog_debug( " nhop [%d]: %s if %s %s", i + 1, inet_ntop(AF_INET6, - api.nexthop[i], + &api_nh->gate.ipv6, buf[1], sizeof(buf[1])), - ifindex2ifname(api.ifindex[i], + ifindex2ifname(api_nh->ifindex, bgp->vrf_id), label_buf); } } if (valid_nh_count) - zapi_ipv4_route_ipv6_nexthop( - ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD, - zclient, (struct prefix_ipv4 *)p, - (struct zapi_ipv6 *)&api); + zclient_route_send(ZEBRA_ROUTE_ADD, zclient, + &api); else - zapi_ipv4_route(ZEBRA_IPV4_ROUTE_DELETE, - zclient, - (struct prefix_ipv4 *)p, - (struct zapi_ipv4 *)&api); + zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, + &api); } else { if (bgp_debug_zebra(p)) { int i; @@ -1517,27 +1478,28 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, buf[0], sizeof(buf[0])), p->prefixlen, api.metric, api.tag); for (i = 0; i < api.nexthop_num; i++) { + api_nh = &api.nexthops[i]; + label_buf[0] = '\0'; if (has_valid_label) sprintf(label_buf, "label %u", - api.label[i]); + api_nh->labels[0]); zlog_debug( " nhop [%d]: %s if %s %s", i + 1, inet_ntop(AF_INET6, - api.nexthop[i], + &api_nh->gate.ipv6, buf[1], sizeof(buf[1])), - ifindex2ifname(api.ifindex[i], + ifindex2ifname(api_nh->ifindex, bgp->vrf_id), label_buf); } } - zapi_ipv6_route( - valid_nh_count ? ZEBRA_IPV6_ROUTE_ADD - : ZEBRA_IPV6_ROUTE_DELETE, - zclient, (struct prefix_ipv6 *)p, NULL, &api); + zclient_route_send(valid_nh_count ? ZEBRA_ROUTE_ADD + : ZEBRA_ROUTE_DELETE, + zclient, &api); } } } @@ -1595,79 +1557,47 @@ void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info, safi_t safi) SET_FLAG(flags, ZEBRA_FLAG_INTERNAL); if (p->family == AF_INET) { - struct zapi_ipv4 api; + struct zapi_route api; + memset(&api, 0, sizeof(api)); api.vrf_id = peer->bgp->vrf_id; api.flags = flags; - api.type = ZEBRA_ROUTE_BGP; - api.instance = 0; - api.message = 0; api.safi = safi; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.nexthop = NULL; - api.label_num = 0; - api.label = NULL; - api.ifindex_num = 0; - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = info->attr->med; - api.tag = 0; - - if (info->attr->tag != 0) { - SET_FLAG(api.message, ZAPI_MESSAGE_TAG); - api.tag = info->attr->tag; - } + api.prefix = *p; if (bgp_debug_zebra(p)) { char buf[2][INET_ADDRSTRLEN]; - zlog_debug( - "Tx IPv4 route delete VRF %u %s/%d metric %u tag %" ROUTE_TAG_PRI, - peer->bgp->vrf_id, - inet_ntop(AF_INET, &p->u.prefix4, buf[0], - sizeof(buf[0])), - p->prefixlen, api.metric, api.tag); + zlog_debug("Tx IPv4 route delete VRF %u %s/%d", + peer->bgp->vrf_id, + inet_ntop(AF_INET, &p->u.prefix4, buf[0], + sizeof(buf[0])), + p->prefixlen); } - zapi_ipv4_route(ZEBRA_IPV4_ROUTE_DELETE, zclient, - (struct prefix_ipv4 *)p, &api); + zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); } /* We have to think about a IPv6 link-local address curse. */ if (p->family == AF_INET6) { - struct zapi_ipv6 api; + struct zapi_route api; + memset(&api, 0, sizeof(api)); api.vrf_id = peer->bgp->vrf_id; api.flags = flags; api.type = ZEBRA_ROUTE_BGP; - api.instance = 0; - api.message = 0; api.safi = safi; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.nexthop = NULL; - api.ifindex_num = 0; - api.label_num = 0; - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = info->attr->med; - api.tag = 0; - - if (info->attr->tag != 0) { - SET_FLAG(api.message, ZAPI_MESSAGE_TAG); - api.tag = info->attr->tag; - } + api.prefix = *p; if (bgp_debug_zebra(p)) { char buf[2][INET6_ADDRSTRLEN]; - zlog_debug( - "Tx IPv6 route delete VRF %u %s/%d metric %u tag %" ROUTE_TAG_PRI, - peer->bgp->vrf_id, - inet_ntop(AF_INET6, &p->u.prefix6, buf[0], - sizeof(buf[0])), - p->prefixlen, api.metric, api.tag); + zlog_debug("Tx IPv6 route delete VRF %u %s/%d", + peer->bgp->vrf_id, + inet_ntop(AF_INET6, &p->u.prefix6, buf[0], + sizeof(buf[0])), + p->prefixlen); } - zapi_ipv6_route(ZEBRA_IPV6_ROUTE_DELETE, zclient, - (struct prefix_ipv6 *)p, NULL, &api); + zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); } } @@ -2195,22 +2125,10 @@ void bgp_zebra_init(struct thread_master *master) zclient->local_vni_del = bgp_zebra_process_local_vni; zclient->local_macip_add = bgp_zebra_process_local_macip; zclient->local_macip_del = bgp_zebra_process_local_macip; - - bgp_nexthop_buf = stream_new(multipath_num * sizeof(struct in6_addr)); - bgp_ifindices_buf = stream_new(multipath_num * sizeof(unsigned int)); - bgp_label_buf = stream_new(multipath_num * sizeof(unsigned int)); } void bgp_zebra_destroy(void) { - - if (bgp_nexthop_buf) - stream_free(bgp_nexthop_buf); - if (bgp_ifindices_buf) - stream_free(bgp_ifindices_buf); - if (bgp_label_buf) - stream_free(bgp_label_buf); - if (zclient == NULL) return; zclient_stop(zclient); diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index 29652e59db..1b1a89b35f 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -501,21 +501,27 @@ static void vnc_zebra_route_msg(struct prefix *p, int nhp_count, void *nhp_ary, } if (p->family == AF_INET) { + struct zapi_route api; + struct zapi_nexthop *api_nh; + struct in_addr *nhp_ary4 = nhp_ary; + int i; - struct zapi_ipv4 api; - - api.flags = 0; + memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_VNC; - api.message = 0; - SET_FLAG(api.message, - ZAPI_MESSAGE_NEXTHOP); /* TBD what's it mean? */ - api.nexthop_num = nhp_count; - api.nexthop = nhp_ary; - api.ifindex_num = 0; - api.instance = 0; + api.prefix = *p; api.safi = SAFI_UNICAST; + /* Nexthops */ + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = nhp_count; + for (i = 0; i < nhp_count; i++) { + api_nh = &api.nexthops[i]; + memcpy(&api_nh->gate.ipv4, &nhp_ary4[i], + sizeof(api_nh->gate.ipv4)); + api_nh->type = NEXTHOP_TYPE_IPV4; + } + if (BGP_DEBUG(zebra, ZEBRA)) { char buf[INET_ADDRSTRLEN]; @@ -527,29 +533,31 @@ static void vnc_zebra_route_msg(struct prefix *p, int nhp_count, void *nhp_ary, p->prefixlen, nhp_count); } - zapi_ipv4_route((add ? ZEBRA_IPV4_ROUTE_ADD - : ZEBRA_IPV4_ROUTE_DELETE), - zclient_vnc, (struct prefix_ipv4 *)p, &api); + zclient_route_send((add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE), + zclient_vnc, &api); } else if (p->family == AF_INET6) { + struct zapi_route api; + struct zapi_nexthop *api_nh; + struct in6_addr *nhp_ary6 = nhp_ary; + int i; - struct zapi_ipv6 api; - ifindex_t ifindex = 0; - - /* Make Zebra API structure. */ - api.flags = 0; + memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_VNC; - api.message = 0; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); /* TBD means? */ - api.nexthop_num = nhp_count; - api.nexthop = nhp_ary; - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); - api.ifindex_num = 1; - api.ifindex = &ifindex; - api.instance = 0; + api.prefix = *p; api.safi = SAFI_UNICAST; + /* Nexthops */ + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = nhp_count; + for (i = 0; i < nhp_count; i++) { + api_nh = &api.nexthops[i]; + memcpy(&api_nh->gate.ipv6, &nhp_ary6[i], + sizeof(api_nh->gate.ipv6)); + api_nh->type = NEXTHOP_TYPE_IPV6; + } + if (BGP_DEBUG(zebra, ZEBRA)) { char buf[INET6_ADDRSTRLEN]; @@ -561,10 +569,8 @@ static void vnc_zebra_route_msg(struct prefix *p, int nhp_count, void *nhp_ary, p->prefixlen, nhp_count); } - zapi_ipv6_route((add ? ZEBRA_IPV6_ROUTE_ADD - : ZEBRA_IPV6_ROUTE_DELETE), - zclient_vnc, (struct prefix_ipv6 *)p, NULL, - &api); + zclient_route_send((add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE), + zclient_vnc, &api); } else { vnc_zlog_debug_verbose( "%s: unknown prefix address family, skipping", From f80dd32b13cf5b5a0559e2660de2e54f04b100c8 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 20 Aug 2017 21:29:35 -0300 Subject: [PATCH 43/79] isisd: unify ipv4/ipv6 zebra-tx functions Signed-off-by: Renato Westphal --- isisd/isis_zebra.c | 129 ++++++++++++++------------------------------- 1 file changed, 39 insertions(+), 90 deletions(-) diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 35b2091e98..e3537e2a0c 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -245,75 +245,12 @@ static int isis_zebra_link_params(int command, struct zclient *zclient, return 0; } -static void isis_zebra_route_add_ipv4(struct prefix *prefix, - struct isis_route_info *route_info) +static void isis_zebra_route_add_route(struct prefix *prefix, + struct isis_route_info *route_info) { struct zapi_route api; struct zapi_nexthop *api_nh; struct isis_nexthop *nexthop; - struct listnode *node; - int count = 0; - - if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) - return; - - memset(&api, 0, sizeof(api)); - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_ISIS; - api.safi = SAFI_UNICAST; - api.prefix = *prefix; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = route_info->cost; -#if 0 - SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); - api.distance = route_info->depth; -#endif - - /* Nexthop, ifindex, distance and metric information */ - for (ALL_LIST_ELEMENTS_RO(route_info->nexthops, node, nexthop)) { - api_nh = &api.nexthops[count]; - /* FIXME: can it be ? */ - if (nexthop->ip.s_addr != INADDR_ANY) { - api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; - api_nh->gate.ipv4 = nexthop->ip; - } else { - api_nh->type = NEXTHOP_TYPE_IFINDEX; - } - api_nh->ifindex = nexthop->ifindex; - count++; - } - if (!count) - return; - - api.nexthop_num = count; - - zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); - SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); -} - -static void isis_zebra_route_del_ipv4(struct prefix *prefix, - struct isis_route_info *route_info) -{ - struct zapi_route api; - - UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); - - memset(&api, 0, sizeof(api)); - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_ISIS; - api.safi = SAFI_UNICAST; - api.prefix = *prefix; - - zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); -} - -static void isis_zebra_route_add_ipv6(struct prefix *prefix, - struct isis_route_info *route_info) -{ - struct zapi_route api; - struct zapi_nexthop *api_nh; struct isis_nexthop6 *nexthop6; struct listnode *node; int count = 0; @@ -325,6 +262,7 @@ static void isis_zebra_route_add_ipv6(struct prefix *prefix, api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_ISIS; api.safi = SAFI_UNICAST; + api.prefix = *prefix; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); api.metric = route_info->cost; @@ -332,20 +270,39 @@ static void isis_zebra_route_add_ipv6(struct prefix *prefix, SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); api.distance = route_info->depth; #endif - api.prefix = *prefix; - /* for each nexthop */ - for (ALL_LIST_ELEMENTS_RO(route_info->nexthops6, node, nexthop6)) { - if (!IN6_IS_ADDR_LINKLOCAL(&nexthop6->ip6) - && !IN6_IS_ADDR_UNSPECIFIED(&nexthop6->ip6)) { - continue; + /* Nexthops */ + switch (prefix->family) { + case AF_INET: + for (ALL_LIST_ELEMENTS_RO(route_info->nexthops, node, + nexthop)) { + api_nh = &api.nexthops[count]; + /* FIXME: can it be ? */ + if (nexthop->ip.s_addr != INADDR_ANY) { + api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; + api_nh->gate.ipv4 = nexthop->ip; + } else { + api_nh->type = NEXTHOP_TYPE_IFINDEX; + } + api_nh->ifindex = nexthop->ifindex; + count++; } + break; + case AF_INET6: + for (ALL_LIST_ELEMENTS_RO(route_info->nexthops6, node, + nexthop6)) { + if (!IN6_IS_ADDR_LINKLOCAL(&nexthop6->ip6) + && !IN6_IS_ADDR_UNSPECIFIED(&nexthop6->ip6)) { + continue; + } - api_nh = &api.nexthops[count]; - api_nh->gate.ipv6 = nexthop6->ip6; - api_nh->ifindex = nexthop6->ifindex; - api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; - count++; + api_nh = &api.nexthops[count]; + api_nh->gate.ipv6 = nexthop6->ip6; + api_nh->ifindex = nexthop6->ifindex; + api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; + count++; + } + break; } if (!count) return; @@ -357,8 +314,8 @@ static void isis_zebra_route_add_ipv6(struct prefix *prefix, UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); } -static void isis_zebra_route_del_ipv6(struct prefix *prefix, - struct isis_route_info *route_info) +static void isis_zebra_route_del_route(struct prefix *prefix, + struct isis_route_info *route_info) { struct zapi_route api; @@ -381,18 +338,10 @@ void isis_zebra_route_update(struct prefix *prefix, if (zclient->sock < 0) return; - if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ACTIVE)) { - if (prefix->family == AF_INET) - isis_zebra_route_add_ipv4(prefix, route_info); - else if (prefix->family == AF_INET6) - isis_zebra_route_add_ipv6(prefix, route_info); - } else { - if (prefix->family == AF_INET) - isis_zebra_route_del_ipv4(prefix, route_info); - else if (prefix->family == AF_INET6) - isis_zebra_route_del_ipv6(prefix, route_info); - } - return; + if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ACTIVE)) + isis_zebra_route_add_route(prefix, route_info); + else + isis_zebra_route_del_route(prefix, route_info); } static int isis_zebra_read_ipv4(int command, struct zclient *zclient, From 9350687dc46509d0eadf26476d1a69070af90435 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 20 Aug 2017 21:36:35 -0300 Subject: [PATCH 44/79] nhrpd: unify ipv4/ipv6 zebra-tx functions Signed-off-by: Renato Westphal --- nhrpd/nhrp_route.c | 99 +++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 63 deletions(-) diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index 3062b23a6d..b744218c9a 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -86,14 +86,20 @@ void nhrp_route_update_nhrp(const struct prefix *p, struct interface *ifp) void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix *p, struct interface *ifp, const union sockunion *nexthop, uint32_t mtu) { - int flags = 0; + struct zapi_route api; + struct zapi_nexthop *api_nh; if (zclient->sock < 0) return; + memset(&api, 0, sizeof(api)); + api.type = ZEBRA_ROUTE_NHRP; + api.safi = SAFI_UNICAST; + api.prefix = *p; + switch (type) { case NHRP_CACHE_NEGATIVE: - SET_FLAG(flags, ZEBRA_FLAG_REJECT); + SET_FLAG(api.flags, ZEBRA_FLAG_REJECT); break; case NHRP_CACHE_DYNAMIC: case NHRP_CACHE_NHS: @@ -102,23 +108,17 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix * to other routing daemons */ break; default: - SET_FLAG(flags, ZEBRA_FLAG_FIB_OVERRIDE); + SET_FLAG(api.flags, ZEBRA_FLAG_FIB_OVERRIDE); break; } - SET_FLAG(flags, ZEBRA_FLAG_INTERNAL); + SET_FLAG(api.flags, ZEBRA_FLAG_INTERNAL); - if (p->family == AF_INET) { - struct zapi_route api; - struct zapi_nexthop *api_nh = &api.nexthops[0];; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 1; + api_nh = &api.nexthops[0]; - memset(&api, 0, sizeof(api)); - api.flags = flags; - api.type = ZEBRA_ROUTE_NHRP; - api.safi = SAFI_UNICAST; - api.prefix = *p; - - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 1; + switch (api.prefix.family) { + case AF_INET: if (nexthop) { api_nh->gate.ipv4 = nexthop->sin.sin_addr; api_nh->type = NEXTHOP_TYPE_IPV4; @@ -130,36 +130,8 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix else api_nh->type = NEXTHOP_TYPE_IFINDEX; } - if (mtu) { - SET_FLAG(api.message, ZAPI_MESSAGE_MTU); - api.mtu = mtu; - } - - if (unlikely(debug_flags & NHRP_DEBUG_ROUTE)) { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug("Zebra send: IPv4 route %s %s/%d nexthop %s metric %u" - " count %d dev %s", - add ? "add" : "del", - inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])), - p->prefixlen, - nexthop ? inet_ntop(AF_INET, &api_nh->gate.ipv4, buf[1], sizeof(buf[1])) : "", - api.metric, api.nexthop_num, ifp->name); - } - - zclient_route_send(add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, - zclient, &api); - } else if (p->family == AF_INET6) { - struct zapi_route api; - struct zapi_nexthop *api_nh = &api.nexthops[0];; - - memset(&api, 0, sizeof(api)); - api.flags = flags; - api.type = ZEBRA_ROUTE_NHRP; - api.safi = SAFI_UNICAST; - api.prefix = *p; - - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 1; + break; + case AF_INET6: if (nexthop) { api_nh->gate.ipv6 = nexthop->sin6.sin6_addr; api_nh->type = NEXTHOP_TYPE_IPV6; @@ -171,25 +143,26 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix else api_nh->type = NEXTHOP_TYPE_IFINDEX; } - if (mtu) { - SET_FLAG(api.message, ZAPI_MESSAGE_MTU); - api.mtu = mtu; - } - - if (unlikely(debug_flags & NHRP_DEBUG_ROUTE)) { - char buf[2][INET6_ADDRSTRLEN]; - zlog_debug("Zebra send: IPv6 route %s %s/%d nexthop %s metric %u" - " count %d dev %s", - add ? "add" : "del", - inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])), - p->prefixlen, - nexthop ? inet_ntop(AF_INET6, &api_nh->gate.ipv6, buf[1], sizeof(buf[1])) : "", - api.metric, api.nexthop_num, ifp->name); - } - - zclient_route_send(add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, - zclient, &api); + break; } + if (mtu) { + SET_FLAG(api.message, ZAPI_MESSAGE_MTU); + api.mtu = mtu; + } + + if (unlikely(debug_flags & NHRP_DEBUG_ROUTE)) { + char buf[2][PREFIX_STRLEN]; + + prefix2str(&api.prefix, buf[0], sizeof(buf[0])); + zlog_debug("Zebra send: route %s %s nexthop %s metric %u" + " count %d dev %s", + add ? "add" : "del", buf[0], + nexthop ? inet_ntop(api.prefix.family, &api_nh->gate, buf[1], sizeof(buf[1])) : "", + api.metric, api.nexthop_num, ifp->name); + } + + zclient_route_send(add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, zclient, + &api); } int nhrp_route_read(int cmd, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) From 2ad4f0933c56483fd7a37e96beab1e02fd22afc8 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 20 Aug 2017 21:36:44 -0300 Subject: [PATCH 45/79] bgpd: unify ipv4/ipv6 zebra-tx functions Signed-off-by: Renato Westphal --- bgpd/bgp_zebra.c | 340 +++++++++++------------------------------ bgpd/rfapi/vnc_zebra.c | 102 +++++-------- 2 files changed, 120 insertions(+), 322 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 2e8188b537..1796975ad3 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1150,8 +1150,9 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, { struct zapi_route api; struct zapi_nexthop *api_nh; + int nh_family; int valid_nh_count = 0; - + int has_valid_label = 0; u_char distance; struct peer *peer; struct bgp_info *mpinfo; @@ -1200,20 +1201,25 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, SET_FLAG(api.flags, ZEBRA_FLAG_INTERNAL); - if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(info->attr)) { - struct in_addr *nexthop; - char buf[2][INET_ADDRSTRLEN]; - int has_valid_label = 0; + /* Get nexthop address-family */ + if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(info->attr)) + nh_family = AF_INET; + else if (p->family == AF_INET6 + || (p->family == AF_INET + && BGP_ATTR_NEXTHOP_AFI_IP6(info->attr))) + nh_family = AF_INET6; + else + return; - nexthop = NULL; + if (bgp->table_map[afi][safi].name) + BGP_INFO_ATTR_BUF_INIT(); - if (bgp->table_map[afi][safi].name) - BGP_INFO_ATTR_BUF_INIT(); + /* Metric is currently based on the best-path only */ + metric = info->attr->med; + for (mpinfo = info; mpinfo; mpinfo = bgp_info_mpath_next(mpinfo)) { + if (nh_family == AF_INET) { + struct in_addr *nexthop; - /* Metric is currently based on the best-path only */ - metric = info->attr->med; - for (mpinfo = info; mpinfo; - mpinfo = bgp_info_mpath_next(mpinfo)) { nexthop = NULL; if (bgp->table_map[afi][safi].name) { @@ -1225,8 +1231,6 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, bgp->table_map[afi][safi].map, p, info_cp)) { if (mpinfo == info) { - /* Metric is currently based on - * the best-path only */ metric = info_cp->attr->med; tag = info_cp->attr->tag; } @@ -1242,98 +1246,10 @@ 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->type = NEXTHOP_TYPE_IPV4; + } else { + ifindex_t ifindex; + struct in6_addr *nexthop; - if (mpinfo->extra - && bgp_is_valid_label(&mpinfo->extra->label)) { - has_valid_label = 1; - label = label_pton(&mpinfo->extra->label); - - api_nh->label_num = 1; - api_nh->labels[0] = label; - } - valid_nh_count++; - } - - if (has_valid_label) - SET_FLAG(api.message, ZAPI_MESSAGE_LABEL); - - /* Note that this currently only applies to Null0 routes for - * aggregates. - * ZEBRA_FLAG_BLACKHOLE signals zapi_ipv4_route to encode a - * special - * BLACKHOLE nexthop. We want to set api.nexthop_num to zero - * since we - * do not want to also encode the 0.0.0.0 nexthop for the - * aggregate route. - */ - if (CHECK_FLAG(api.flags, ZEBRA_FLAG_BLACKHOLE)) - api.nexthop_num = 0; - else - api.nexthop_num = valid_nh_count; - - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = metric; - - api.tag = 0; - if (tag) { - SET_FLAG(api.message, ZAPI_MESSAGE_TAG); - api.tag = tag; - } - - distance = bgp_distance_apply(p, info, afi, safi, bgp); - if (distance) { - SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); - api.distance = distance; - } - - if (bgp_debug_zebra(p)) { - int i; - char label_buf[20]; - zlog_debug( - "Tx IPv4 route %s VRF %u %s/%d metric %u tag %" ROUTE_TAG_PRI - " count %d", - (valid_nh_count ? "add" : "delete"), - bgp->vrf_id, inet_ntop(AF_INET, &p->u.prefix4, - buf[0], sizeof(buf[0])), - p->prefixlen, api.metric, api.tag, - api.nexthop_num); - for (i = 0; i < api.nexthop_num; i++) { - api_nh = &api.nexthops[i]; - - label_buf[0] = '\0'; - if (has_valid_label) - sprintf(label_buf, "label %u", - api_nh->labels[0]); - zlog_debug(" nhop [%d]: %s %s", i + 1, - inet_ntop(AF_INET, - &api_nh->gate.ipv4, buf[1], - sizeof(buf[1])), - label_buf); - } - } - - zclient_route_send(valid_nh_count ? ZEBRA_ROUTE_ADD - : ZEBRA_ROUTE_DELETE, - zclient, &api); - } - - /* We have to think about a IPv6 link-local address curse. */ - if (p->family == AF_INET6 - || (p->family == AF_INET && BGP_ATTR_NEXTHOP_AFI_IP6(info->attr))) { - ifindex_t ifindex; - struct in6_addr *nexthop; - char buf[2][INET6_ADDRSTRLEN]; - int has_valid_label = 0; - - ifindex = 0; - nexthop = NULL; - - if (bgp->table_map[afi][safi].name) - BGP_INFO_ATTR_BUF_INIT(); - - metric = info->attr->med; - for (mpinfo = info; mpinfo; - mpinfo = bgp_info_mpath_next(mpinfo)) { ifindex = 0; nexthop = NULL; @@ -1385,123 +1301,68 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, api_nh->gate.ipv6 = *nexthop; api_nh->ifindex = ifindex; api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; - - if (mpinfo->extra - && bgp_is_valid_label(&mpinfo->extra->label)) { - has_valid_label = 1; - label = label_pton(&mpinfo->extra->label); - - api_nh->label_num = 1; - api_nh->labels[0] = label; - } - valid_nh_count++; } - if (has_valid_label) - SET_FLAG(api.message, ZAPI_MESSAGE_LABEL); + if (mpinfo->extra + && bgp_is_valid_label(&mpinfo->extra->label)) { + has_valid_label = 1; + label = label_pton(&mpinfo->extra->label); - /* Note that this currently only applies to Null0 routes for - * aggregates. - * ZEBRA_FLAG_BLACKHOLE signals zapi_ipv6_route to encode a - * special - * BLACKHOLE nexthop. We want to set api.nexthop_num to zero - * since we - * do not want to also encode the :: nexthop for the aggregate - * route. - */ - if (CHECK_FLAG(api.flags, ZEBRA_FLAG_BLACKHOLE)) - api.nexthop_num = 0; - else - api.nexthop_num = valid_nh_count; - - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = metric; - - api.tag = 0; - if (tag) { - SET_FLAG(api.message, ZAPI_MESSAGE_TAG); - api.tag = tag; + api_nh->label_num = 1; + api_nh->labels[0] = label; } + valid_nh_count++; + } - distance = bgp_distance_apply(p, info, afi, safi, bgp); - if (distance) { - SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); - api.distance = distance; - } + if (has_valid_label) + SET_FLAG(api.message, ZAPI_MESSAGE_LABEL); - if (p->family == AF_INET) { - if (bgp_debug_zebra(p)) { - int i; - char label_buf[20]; - zlog_debug( - "Tx IPv4 route %s VRF %u %s/%d metric %u tag %" ROUTE_TAG_PRI, - valid_nh_count ? "add" : "delete", - bgp->vrf_id, - inet_ntop(AF_INET, &p->u.prefix4, - buf[0], sizeof(buf[0])), - p->prefixlen, api.metric, api.tag); - for (i = 0; i < api.nexthop_num; i++) { - api_nh = &api.nexthops[i]; + if (!CHECK_FLAG(api.flags, ZEBRA_FLAG_BLACKHOLE)) + api.nexthop_num = valid_nh_count; - label_buf[0] = '\0'; - if (has_valid_label) - sprintf(label_buf, "label %u", - api_nh->labels[0]); - zlog_debug( - " nhop [%d]: %s if %s %s", - i + 1, - inet_ntop(AF_INET6, - &api_nh->gate.ipv6, - buf[1], - sizeof(buf[1])), - ifindex2ifname(api_nh->ifindex, - bgp->vrf_id), - label_buf); - } - } + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = metric; - if (valid_nh_count) - zclient_route_send(ZEBRA_ROUTE_ADD, zclient, - &api); - else - zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, - &api); - } else { - if (bgp_debug_zebra(p)) { - int i; - char label_buf[20]; - zlog_debug( - "Tx IPv6 route %s VRF %u %s/%d metric %u tag %" ROUTE_TAG_PRI, - valid_nh_count ? "add" : "delete", - bgp->vrf_id, - inet_ntop(AF_INET6, &p->u.prefix6, - buf[0], sizeof(buf[0])), - p->prefixlen, api.metric, api.tag); - for (i = 0; i < api.nexthop_num; i++) { - api_nh = &api.nexthops[i]; + if (tag) { + SET_FLAG(api.message, ZAPI_MESSAGE_TAG); + api.tag = tag; + } - label_buf[0] = '\0'; - if (has_valid_label) - sprintf(label_buf, "label %u", - api_nh->labels[0]); - zlog_debug( - " nhop [%d]: %s if %s %s", - i + 1, - inet_ntop(AF_INET6, - &api_nh->gate.ipv6, - buf[1], - sizeof(buf[1])), - ifindex2ifname(api_nh->ifindex, - bgp->vrf_id), - label_buf); - } - } + distance = bgp_distance_apply(p, info, afi, safi, bgp); + if (distance) { + SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); + api.distance = distance; + } - zclient_route_send(valid_nh_count ? ZEBRA_ROUTE_ADD - : ZEBRA_ROUTE_DELETE, - zclient, &api); + if (bgp_debug_zebra(p)) { + char prefix_buf[PREFIX_STRLEN]; + char nh_buf[INET6_ADDRSTRLEN]; + char label_buf[20]; + int i; + + prefix2str(&api.prefix, prefix_buf, sizeof(prefix_buf)); + zlog_debug("Tx route %s VRF %u %s metric %u tag %" ROUTE_TAG_PRI + " count %d", + valid_nh_count ? "add" : "delete", bgp->vrf_id, + prefix_buf, api.metric, api.tag, api.nexthop_num); + for (i = 0; i < api.nexthop_num; i++) { + api_nh = &api.nexthops[i]; + + inet_ntop(nh_family, &api_nh->gate, nh_buf, + sizeof(nh_buf)); + + label_buf[0] = '\0'; + if (has_valid_label) + sprintf(label_buf, "label %u", + api_nh->labels[0]); + zlog_debug(" nhop [%d]: %s %s", i + 1, nh_buf, + label_buf); } } + + zclient_route_send(valid_nh_count ? ZEBRA_ROUTE_ADD + : ZEBRA_ROUTE_DELETE, + zclient, &api); } /* Announce all routes of a table to zebra */ @@ -1532,7 +1393,7 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi) void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info, safi_t safi) { - u_int32_t flags; + struct zapi_route api; struct peer *peer; peer = info->peer; @@ -1544,61 +1405,30 @@ void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info, safi_t safi) if (!bgp_install_info_to_zebra(peer->bgp)) return; - flags = 0; + memset(&api, 0, sizeof(api)); + api.vrf_id = peer->bgp->vrf_id; + api.type = ZEBRA_ROUTE_BGP; + api.safi = safi; + api.prefix = *p; if (peer->sort == BGP_PEER_IBGP) { - SET_FLAG(flags, ZEBRA_FLAG_INTERNAL); - SET_FLAG(flags, ZEBRA_FLAG_IBGP); + SET_FLAG(api.flags, ZEBRA_FLAG_INTERNAL); + SET_FLAG(api.flags, ZEBRA_FLAG_IBGP); } if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1) || CHECK_FLAG(peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK) || bgp_flag_check(peer->bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK)) - SET_FLAG(flags, ZEBRA_FLAG_INTERNAL); + SET_FLAG(api.flags, ZEBRA_FLAG_INTERNAL); - if (p->family == AF_INET) { - struct zapi_route api; + if (bgp_debug_zebra(p)) { + char buf[PREFIX_STRLEN]; - memset(&api, 0, sizeof(api)); - api.vrf_id = peer->bgp->vrf_id; - api.flags = flags; - api.type = ZEBRA_ROUTE_BGP; - api.safi = safi; - api.prefix = *p; - - if (bgp_debug_zebra(p)) { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug("Tx IPv4 route delete VRF %u %s/%d", - peer->bgp->vrf_id, - inet_ntop(AF_INET, &p->u.prefix4, buf[0], - sizeof(buf[0])), - p->prefixlen); - } - - zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); + prefix2str(&api.prefix, buf, sizeof(buf)); + zlog_debug("Tx route delete VRF %u %s", peer->bgp->vrf_id, buf); } - /* We have to think about a IPv6 link-local address curse. */ - if (p->family == AF_INET6) { - struct zapi_route api; - memset(&api, 0, sizeof(api)); - api.vrf_id = peer->bgp->vrf_id; - api.flags = flags; - api.type = ZEBRA_ROUTE_BGP; - api.safi = safi; - api.prefix = *p; - - if (bgp_debug_zebra(p)) { - char buf[2][INET6_ADDRSTRLEN]; - zlog_debug("Tx IPv6 route delete VRF %u %s/%d", - peer->bgp->vrf_id, - inet_ntop(AF_INET6, &p->u.prefix6, buf[0], - sizeof(buf[0])), - p->prefixlen); - } - - zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); - } + zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); } struct bgp_redist *bgp_redist_lookup(struct bgp *bgp, afi_t afi, u_char type, diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index 1b1a89b35f..06dff27b58 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -494,89 +494,57 @@ static int vnc_zebra_read_ipv6(int command, struct zclient *zclient, static void vnc_zebra_route_msg(struct prefix *p, int nhp_count, void *nhp_ary, int add) /* 1 = add, 0 = del */ { + struct zapi_route api; + struct zapi_nexthop *api_nh; + int i; + if (!nhp_count) { vnc_zlog_debug_verbose("%s: empty nexthop list, skipping", __func__); return; } - if (p->family == AF_INET) { - struct zapi_route api; - struct zapi_nexthop *api_nh; - struct in_addr *nhp_ary4 = nhp_ary; - int i; + memset(&api, 0, sizeof(api)); + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_VNC; + api.safi = SAFI_UNICAST; + api.prefix = *p; - memset(&api, 0, sizeof(api)); - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_VNC; - api.prefix = *p; - api.safi = SAFI_UNICAST; + /* Nexthops */ + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = nhp_count; + for (i = 0; i < nhp_count; i++) { + struct in_addr *nhp_ary4; + struct in6_addr *nhp_ary6; - /* Nexthops */ - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = nhp_count; - for (i = 0; i < nhp_count; i++) { - api_nh = &api.nexthops[i]; + api_nh = &api.nexthops[i]; + switch (p->family) { + case AF_INET: + nhp_ary4 = nhp_ary; memcpy(&api_nh->gate.ipv4, &nhp_ary4[i], sizeof(api_nh->gate.ipv4)); api_nh->type = NEXTHOP_TYPE_IPV4; - } - - if (BGP_DEBUG(zebra, ZEBRA)) { - - char buf[INET_ADDRSTRLEN]; - vnc_zlog_debug_verbose( - "%s: Zebra send: IPv4 route %s %s/%d, nhp_count=%d", - __func__, (add ? "add" : "del"), - inet_ntop(AF_INET, &p->u.prefix4, buf, - sizeof(buf)), - p->prefixlen, nhp_count); - } - - zclient_route_send((add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE), - zclient_vnc, &api); - - } else if (p->family == AF_INET6) { - struct zapi_route api; - struct zapi_nexthop *api_nh; - struct in6_addr *nhp_ary6 = nhp_ary; - int i; - - memset(&api, 0, sizeof(api)); - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_VNC; - api.prefix = *p; - api.safi = SAFI_UNICAST; - - /* Nexthops */ - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = nhp_count; - for (i = 0; i < nhp_count; i++) { - api_nh = &api.nexthops[i]; + break; + case AF_INET6: + nhp_ary6 = nhp_ary; memcpy(&api_nh->gate.ipv6, &nhp_ary6[i], sizeof(api_nh->gate.ipv6)); api_nh->type = NEXTHOP_TYPE_IPV6; + break; } - - if (BGP_DEBUG(zebra, ZEBRA)) { - - char buf[INET6_ADDRSTRLEN]; - vnc_zlog_debug_verbose( - "%s: Zebra send: IPv6 route %s %s/%d nhp_count=%d", - __func__, (add ? "add" : "del"), - inet_ntop(AF_INET6, &p->u.prefix6, buf, - sizeof(buf)), - p->prefixlen, nhp_count); - } - - zclient_route_send((add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE), - zclient_vnc, &api); - } else { - vnc_zlog_debug_verbose( - "%s: unknown prefix address family, skipping", - __func__); - return; } + + if (BGP_DEBUG(zebra, ZEBRA)) { + char buf[PREFIX_STRLEN]; + + prefix2str(&api.prefix, buf, sizeof(buf)); + vnc_zlog_debug_verbose( + "%s: Zebra send: route %s %s, nhp_count=%d", __func__, + (add ? "add" : "del"), buf, nhp_count); + } + + zclient_route_send((add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE), + zclient_vnc, &api); } From 744899219f4214398a3078874a341000a372e29d Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 20 Aug 2017 22:10:50 -0300 Subject: [PATCH 46/79] *: use zapi_route to send/receive redistributed routes as well Some differences compared to the old API: * Now the redistributed routes are sent using address-family independent messages (ZEBRA_REDISTRIBUTE_ROUTE_ADD and ZEBRA_REDISTRIBUTE_ROUTE_DEL). This allows us to unify the ipv4/ipv6 zclient callbacks in the client daemons and thus remove a lot of duplicate code; * Now zebra sends all nexthops of the redistributed routes to the client daemons, not only the first one. This shouldn't have any noticeable performance implications and will allow us to remove an ugly exception we had for ldpd (which needs to know all nexthops of the redistributed routes). The other client daemons can simply ignore the nexthops if they want or consult just the first one (e.g. ospfd/ospf6d/ripd/ripngd). Signed-off-by: Renato Westphal --- babeld/babel_zebra.c | 123 +++------------------ babeld/xroute.c | 77 ++++++------- babeld/xroute.h | 10 +- bgpd/bgp_route.c | 20 ++-- bgpd/bgp_route.h | 4 +- bgpd/bgp_zebra.c | 239 +++++++---------------------------------- bgpd/rfapi/vnc_zebra.c | 171 ++++------------------------- eigrpd/eigrp_zebra.c | 52 +++------ isisd/isis_zebra.c | 122 +++------------------ ldpd/ldp_zebra.c | 106 +++++++----------- lib/log.c | 6 +- lib/zclient.c | 26 ++--- lib/zclient.h | 33 +++--- nhrpd/nhrp_route.c | 97 +++++------------ ospf6d/ospf6_zebra.c | 86 ++++----------- ospfd/ospf_zebra.c | 69 ++++-------- ripd/rip_zebra.c | 69 ++++-------- ripngd/ripng_zebra.c | 74 +++---------- zebra/redistribute.c | 17 +-- zebra/zserv.c | 221 +++++++++---------------------------- 20 files changed, 371 insertions(+), 1251 deletions(-) diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c index 2b998940d7..337b7b3927 100644 --- a/babeld/babel_zebra.c +++ b/babeld/babel_zebra.c @@ -54,119 +54,24 @@ static struct { {0, 0, NULL} }; -/* Zebra route add and delete treatment (ipv6). */ +/* Zebra route add and delete treatment. */ static int -babel_zebra_read_ipv6 (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf) +babel_zebra_read_route (int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf) { - struct stream *s; - struct zapi_ipv6 api; - unsigned long ifindex = -1; - struct in6_addr nexthop; - struct prefix_ipv6 prefix, src_p; + struct zapi_route api; - s = zclient->ibuf; - ifindex = 0; - memset (&nexthop, 0, sizeof (struct in6_addr)); - memset (&api, 0, sizeof(struct zapi_ipv6)); - memset (&prefix, 0, sizeof (struct prefix_ipv6)); + if (zapi_route_decode(zclient->ibuf, &api) < 0) + return -1; - /* Type, flags, message. */ - api.type = stream_getc (s); - api.instance = stream_getw (s); - api.flags = stream_getl (s); - api.message = stream_getc (s); - - /* IPv6 prefix. */ - prefix.family = AF_INET6; - prefix.prefixlen = MIN (IPV6_MAX_PREFIXLEN, stream_getc (s)); - stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen)); - - memset(&src_p, 0, sizeof(src_p)); - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { - src_p.family = AF_INET6; - src_p.prefixlen = stream_getc(s); - stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); - } - if (src_p.prefixlen) - /* we completely ignore srcdest routes for now. */ + /* we completely ignore srcdest routes for now. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) return 0; - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { - api.nexthop_num = stream_getc (s); - stream_get (&nexthop, s, sizeof(nexthop)); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) { - api.ifindex_num = stream_getc (s); - ifindex = stream_getl (s); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc (s); - else - api.distance = 0; - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl (s); - else - api.metric = 0; - - if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) - babel_ipv6_route_add(&api, &prefix, ifindex, &nexthop); - else - babel_ipv6_route_delete(&api, &prefix, ifindex); - - return 0; -} - -static int -babel_zebra_read_ipv4 (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf) -{ - struct stream *s; - struct zapi_ipv4 api; - unsigned long ifindex = -1; - struct in_addr nexthop; - struct prefix_ipv4 prefix; - - s = zclient->ibuf; - ifindex = 0; - memset (&nexthop, 0, sizeof (struct in_addr)); - memset (&api, 0, sizeof(struct zapi_ipv4)); - memset (&prefix, 0, sizeof (struct prefix_ipv4)); - - /* Type, flags, message. */ - api.type = stream_getc (s); - api.instance = stream_getw (s); - api.flags = stream_getl (s); - api.message = stream_getc (s); - - /* IPv4 prefix. */ - prefix.family = AF_INET; - prefix.prefixlen = MIN (IPV4_MAX_PREFIXLEN, stream_getc (s)); - stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen)); - - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { - api.nexthop_num = stream_getc (s); - stream_get (&nexthop, s, sizeof(nexthop)); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) { - api.ifindex_num = stream_getc (s); - ifindex = stream_getl (s); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc (s); - else - api.distance = 0; - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl (s); - else - api.metric = 0; - - if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) { - babel_ipv4_route_add(&api, &prefix, ifindex, &nexthop); + if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) { + babel_route_add(&api); } else { - babel_ipv4_route_delete(&api, &prefix, ifindex); + babel_route_delete(&api); } return 0; @@ -342,10 +247,8 @@ void babelz_zebra_init(void) zclient->interface_down = babel_interface_down; zclient->interface_address_add = babel_interface_address_add; zclient->interface_address_delete = babel_interface_address_delete; - zclient->redistribute_route_ipv4_add = babel_zebra_read_ipv4; - zclient->redistribute_route_ipv4_del = babel_zebra_read_ipv4; - zclient->redistribute_route_ipv6_add = babel_zebra_read_ipv6; - zclient->redistribute_route_ipv6_del = babel_zebra_read_ipv6; + zclient->redistribute_route_add = babel_zebra_read_route; + zclient->redistribute_route_del = babel_zebra_read_route; install_element(BABEL_NODE, &babel_redistribute_type_cmd); install_element(ENABLE_NODE, &debug_babel_cmd); diff --git a/babeld/xroute.c b/babeld/xroute.c index 2e123564ea..88e9479e4b 100644 --- a/babeld/xroute.c +++ b/babeld/xroute.c @@ -43,63 +43,54 @@ static int numxroutes = 0, maxxroutes = 0; /* Add redistributed route to Babel table. */ int -babel_ipv4_route_add (struct zapi_ipv4 *api, struct prefix_ipv4 *prefix, - unsigned int ifindex, struct in_addr *nexthop) +babel_route_add (struct zapi_route *api) { unsigned char uchar_prefix[16]; - inaddr_to_uchar(uchar_prefix, &prefix->prefix); - debugf(BABEL_DEBUG_ROUTE, "Adding new ipv4 route coming from Zebra."); - xroute_add_new_route(uchar_prefix, prefix->prefixlen + 96, - api->metric, ifindex, 0, 1); + switch (api->prefix.family) { + case AF_INET: + inaddr_to_uchar(uchar_prefix, &api->prefix.u.prefix4); + debugf(BABEL_DEBUG_ROUTE, "Adding new ipv4 route coming from Zebra."); + xroute_add_new_route(uchar_prefix, api->prefix.prefixlen + 96, + api->metric, api->nexthops[0].ifindex, 0, 1); + break; + case AF_INET6: + in6addr_to_uchar(uchar_prefix, &api->prefix.u.prefix6); + debugf(BABEL_DEBUG_ROUTE, "Adding new ipv6 route coming from Zebra."); + xroute_add_new_route(uchar_prefix, api->prefix.prefixlen, + api->metric, api->nexthops[0].ifindex, 0, 1); + break; + } + return 0; } /* Remove redistributed route from Babel table. */ int -babel_ipv4_route_delete (struct zapi_ipv4 *api, struct prefix_ipv4 *prefix, - unsigned int ifindex) +babel_route_delete (struct zapi_route *api) { unsigned char uchar_prefix[16]; struct xroute *xroute = NULL; - inaddr_to_uchar(uchar_prefix, &prefix->prefix); - xroute = find_xroute(uchar_prefix, prefix->prefixlen + 96); - if (xroute != NULL) { - debugf(BABEL_DEBUG_ROUTE, "Removing ipv4 route (from zebra)."); - flush_xroute(xroute); + switch (api->prefix.family) { + case AF_INET: + inaddr_to_uchar(uchar_prefix, &api->prefix.u.prefix4); + xroute = find_xroute(uchar_prefix, api->prefix.prefixlen + 96); + if (xroute != NULL) { + debugf(BABEL_DEBUG_ROUTE, "Removing ipv4 route (from zebra)."); + flush_xroute(xroute); + } + break; + case AF_INET6: + in6addr_to_uchar(uchar_prefix, &api->prefix.u.prefix6); + xroute = find_xroute(uchar_prefix, api->prefix.prefixlen); + if (xroute != NULL) { + debugf(BABEL_DEBUG_ROUTE, "Removing ipv6 route (from zebra)."); + flush_xroute(xroute); + } + break; } - return 0; -} -/* Add redistributed route to Babel table. */ -int -babel_ipv6_route_add (struct zapi_ipv6 *api, struct prefix_ipv6 *prefix, - unsigned int ifindex, struct in6_addr *nexthop) -{ - unsigned char uchar_prefix[16]; - - in6addr_to_uchar(uchar_prefix, &prefix->prefix); - debugf(BABEL_DEBUG_ROUTE, "Adding new route coming from Zebra."); - xroute_add_new_route(uchar_prefix, prefix->prefixlen, api->metric, ifindex, - 0, 1); - return 0; -} - -/* Remove redistributed route from Babel table. */ -int -babel_ipv6_route_delete (struct zapi_ipv6 *api, struct prefix_ipv6 *prefix, - unsigned int ifindex) -{ - unsigned char uchar_prefix[16]; - struct xroute *xroute = NULL; - - in6addr_to_uchar(uchar_prefix, &prefix->prefix); - xroute = find_xroute(uchar_prefix, prefix->prefixlen); - if (xroute != NULL) { - debugf(BABEL_DEBUG_ROUTE, "Removing route (from zebra)."); - flush_xroute(xroute); - } return 0; } diff --git a/babeld/xroute.h b/babeld/xroute.h index 27899e62a1..59afccb590 100644 --- a/babeld/xroute.h +++ b/babeld/xroute.h @@ -36,14 +36,8 @@ struct xroute_stream; struct xroute *find_xroute(const unsigned char *prefix, unsigned char plen); void flush_xroute(struct xroute *xroute); -int babel_ipv4_route_add (struct zapi_ipv4 *api, struct prefix_ipv4 *prefix, - unsigned int ifindex, struct in_addr *nexthop); -int babel_ipv4_route_delete (struct zapi_ipv4 *api, struct prefix_ipv4 *prefix, - unsigned int ifindex); -int babel_ipv6_route_add (struct zapi_ipv6 *api, struct prefix_ipv6 *prefix, - unsigned int ifindex, struct in6_addr *nexthop); -int babel_ipv6_route_delete (struct zapi_ipv6 *api, struct prefix_ipv6 *prefix, - unsigned int ifindex); +int babel_route_add (struct zapi_route *api); +int babel_route_delete (struct zapi_route *api); int xroutes_estimate(void); struct xroute_stream *xroute_stream(void); struct xroute *xroute_stream_next(struct xroute_stream *stream); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index bb204b01f1..2256b069cb 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -6086,8 +6086,7 @@ DEFUN (no_ipv6_aggregate_address, /* Redistribute route treatment. */ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, - const struct in_addr *nexthop, - const struct in6_addr *nexthop6, unsigned int ifindex, + const union g_addr *nexthop, unsigned int ifindex, u_int32_t metric, u_char type, u_short instance, route_tag_t tag) { @@ -6103,14 +6102,17 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, /* Make default attribute. */ bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE); - if (nexthop) - attr.nexthop = *nexthop; - attr.nh_ifindex = ifindex; - - if (nexthop6) { - attr.mp_nexthop_global = *nexthop6; - attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL; + if (nexthop) { + switch (p->family) { + case AF_INET: + attr.nexthop = nexthop->ipv4; + break; + case AF_INET6: + attr.mp_nexthop_global = nexthop->ipv6; + attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL; + } } + attr.nh_ifindex = ifindex; attr.med = metric; attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 1a1817bad3..55f812d4a0 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -22,6 +22,7 @@ #define _QUAGGA_BGP_ROUTE_H #include "queue.h" +#include "nexthop.h" #include "bgp_table.h" struct bgp_nexthop_cache; @@ -326,8 +327,7 @@ extern int bgp_nlri_parse_ip(struct peer *, struct attr *, struct bgp_nlri *); extern int bgp_maximum_prefix_overflow(struct peer *, afi_t, safi_t, int); extern void bgp_redistribute_add(struct bgp *, struct prefix *, - const struct in_addr *, - const struct in6_addr *, unsigned int ifindex, + const union g_addr *, unsigned int ifindex, u_int32_t, u_char, u_short, route_tag_t); extern void bgp_redistribute_delete(struct bgp *, struct prefix *, u_char, u_short); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 1796975ad3..9a092404d5 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -554,75 +554,36 @@ static int bgp_interface_vrf_update(int command, struct zclient *zclient, } /* Zebra route add and delete treatment. */ -static int zebra_read_ipv4(int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int zebra_read_route(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct stream *s; - struct zapi_ipv4 api; - struct in_addr nexthop; - struct prefix_ipv4 p; + struct zapi_route api; + union g_addr nexthop; unsigned int ifindex; - int i; + int add, i; struct bgp *bgp; bgp = bgp_lookup_by_vrf_id(vrf_id); if (!bgp) return 0; - s = zclient->ibuf; - nexthop.s_addr = 0; + if (zapi_route_decode(zclient->ibuf, &api) < 0) + return -1; - /* Type, flags, message. */ - api.type = stream_getc(s); - api.instance = stream_getw(s); - api.flags = stream_getl(s); - api.message = stream_getc(s); + /* we completely ignore srcdest routes for now. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) + return 0; - /* IPv4 prefix. */ - memset(&p, 0, sizeof(struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s)); - stream_get(&p.prefix, s, PSIZE(p.prefixlen)); + /* ignore link-local address. */ + if (api.prefix.family == AF_INET6 + && IN6_IS_ADDR_LINKLOCAL(&api.prefix.u.prefix6)) + return 0; - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { - api.nexthop_num = stream_getc(s); - nexthop.s_addr = stream_get_ipv4(s); - } - - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { - api.ifindex_num = stream_getc(s); - ifindex = stream_getl(s); /* ifindex, unused */ - } else { - ifindex = 0; - } - - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(s); - - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(s); - else - api.metric = 0; - - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl(s); - else - api.tag = 0; - - if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) { - if (bgp_debug_zebra((struct prefix *)&p)) { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug( - "Rx IPv4 route add VRF %u %s[%d] %s/%d nexthop %s metric %u tag %" ROUTE_TAG_PRI, - vrf_id, zebra_route_string(api.type), - api.instance, inet_ntop(AF_INET, &p.prefix, - buf[0], sizeof(buf[0])), - p.prefixlen, inet_ntop(AF_INET, &nexthop, - buf[1], sizeof(buf[1])), - api.metric, api.tag); - } + nexthop = api.nexthops[0].gate; + ifindex = api.nexthops[0].ifindex; + add = (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD); + if (add) { /* * The ADD message is actually an UPDATE and there is no * explicit DEL @@ -634,156 +595,30 @@ static int zebra_read_ipv4(int command, struct zclient *zclient, */ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { if (i != api.type) - bgp_redistribute_delete(bgp, - (struct prefix *)&p, i, + bgp_redistribute_delete(bgp, &api.prefix, i, api.instance); } /* Now perform the add/update. */ - bgp_redistribute_add(bgp, (struct prefix *)&p, &nexthop, NULL, - ifindex, api.metric, api.type, - api.instance, api.tag); - } else if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL) { - if (bgp_debug_zebra((struct prefix *)&p)) { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug( - "Rx IPv4 route delete VRF %u %s[%d] %s/%d " - "nexthop %s metric %u tag %" ROUTE_TAG_PRI, - vrf_id, zebra_route_string(api.type), - api.instance, inet_ntop(AF_INET, &p.prefix, - buf[0], sizeof(buf[0])), - p.prefixlen, inet_ntop(AF_INET, &nexthop, - buf[1], sizeof(buf[1])), - api.metric, api.tag); - } - bgp_redistribute_delete(bgp, (struct prefix *)&p, api.type, - api.instance); - } - - return 0; -} - -/* Zebra route add and delete treatment. */ -static int zebra_read_ipv6(int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) -{ - struct stream *s; - struct zapi_ipv6 api; - struct in6_addr nexthop; - struct prefix_ipv6 p, src_p; - unsigned int ifindex; - int i; - struct bgp *bgp; - - bgp = bgp_lookup_by_vrf_id(vrf_id); - if (!bgp) - return 0; - - s = zclient->ibuf; - memset(&nexthop, 0, sizeof(struct in6_addr)); - - /* Type, flags, message. */ - api.type = stream_getc(s); - api.instance = stream_getw(s); - api.flags = stream_getl(s); - api.message = stream_getc(s); - - /* IPv6 prefix. */ - memset(&p, 0, sizeof(struct prefix_ipv6)); - p.family = AF_INET6; - p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc(s)); - stream_get(&p.prefix, s, PSIZE(p.prefixlen)); - - memset(&src_p, 0, sizeof(struct prefix_ipv6)); - src_p.family = AF_INET6; - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { - src_p.prefixlen = stream_getc(s); - stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); - } - - if (src_p.prefixlen) - /* we completely ignore srcdest routes for now. */ - return 0; - - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { - api.nexthop_num = stream_getc(s); - stream_get(&nexthop, s, 16); - } - - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { - api.ifindex_num = stream_getc(s); - ifindex = stream_getl(s); /* ifindex, unused */ + bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex, + api.metric, api.type, api.instance, + api.tag); } else { - ifindex = 0; + bgp_redistribute_delete(bgp, &api.prefix, api.type, + api.instance); } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(s); - else - api.distance = 0; + if (bgp_debug_zebra(&api.prefix)) { + char buf[2][PREFIX_STRLEN]; - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(s); - else - api.metric = 0; - - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl(s); - else - api.tag = 0; - - /* Simply ignore link-local address. */ - if (IN6_IS_ADDR_LINKLOCAL(&p.prefix)) - return 0; - - if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) { - if (bgp_debug_zebra((struct prefix *)&p)) { - char buf[2][INET6_ADDRSTRLEN]; - zlog_debug( - "Rx IPv6 route add VRF %u %s[%d] %s/%d nexthop %s metric %u tag %" ROUTE_TAG_PRI, - vrf_id, zebra_route_string(api.type), - api.instance, inet_ntop(AF_INET6, &p.prefix, - buf[0], sizeof(buf[0])), - p.prefixlen, inet_ntop(AF_INET, &nexthop, - buf[1], sizeof(buf[1])), - api.metric, api.tag); - } - - /* - * The ADD message is actually an UPDATE and there is no - * explicit DEL - * for a prior redistributed route, if any. So, perform an - * implicit - * DEL processing for the same redistributed route from any - * other - * source type. - */ - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { - if (i != api.type) - bgp_redistribute_delete(bgp, - (struct prefix *)&p, i, - api.instance); - } - - bgp_redistribute_add(bgp, (struct prefix *)&p, NULL, &nexthop, - ifindex, api.metric, api.type, - api.instance, api.tag); - } else if (command == ZEBRA_REDISTRIBUTE_IPV6_DEL) { - if (bgp_debug_zebra((struct prefix *)&p)) { - char buf[2][INET6_ADDRSTRLEN]; - zlog_debug( - "Rx IPv6 route delete VRF %u %s[%d] %s/%d " - "nexthop %s metric %u tag %" ROUTE_TAG_PRI, - vrf_id, zebra_route_string(api.type), - api.instance, inet_ntop(AF_INET6, &p.prefix, - buf[0], sizeof(buf[0])), - p.prefixlen, inet_ntop(AF_INET6, &nexthop, - buf[1], sizeof(buf[1])), - api.metric, api.tag); - } - bgp_redistribute_delete(bgp, (struct prefix *)&p, api.type, - api.instance); + prefix2str(&api.prefix, buf[0], sizeof(buf[0])); + inet_ntop(api.prefix.family, &nexthop, buf[1], sizeof(buf[1])); + zlog_debug( + "Rx route %s VRF %u %s[%d] %s " + "nexthop %s metric %u tag %" ROUTE_TAG_PRI, + (add) ? "add" : "delete", vrf_id, + zebra_route_string(api.type), api.instance, buf[0], + buf[1], api.metric, api.tag); } return 0; @@ -1942,12 +1777,10 @@ void bgp_zebra_init(struct thread_master *master) zclient->interface_nbr_address_delete = bgp_interface_nbr_address_delete; zclient->interface_vrf_update = bgp_interface_vrf_update; - zclient->redistribute_route_ipv4_add = zebra_read_ipv4; - zclient->redistribute_route_ipv4_del = zebra_read_ipv4; + zclient->redistribute_route_add = zebra_read_route; + zclient->redistribute_route_del = zebra_read_route; zclient->interface_up = bgp_interface_up; zclient->interface_down = bgp_interface_down; - zclient->redistribute_route_ipv6_add = zebra_read_ipv6; - zclient->redistribute_route_ipv6_del = zebra_read_ipv6; zclient->nexthop_update = bgp_read_nexthop_update; zclient->import_check_update = bgp_read_import_check_update; zclient->fec_update = bgp_read_fec_update; diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index 06dff27b58..d472e06fa5 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -57,8 +57,8 @@ static struct zclient *zclient_vnc = NULL; /* * Routes coming from zebra get added to VNC here */ -static void vnc_redistribute_add(struct prefix *p, struct in_addr *nexthop, - u_int32_t metric, uint8_t type) +static void vnc_redistribute_add(struct prefix *p, u_int32_t metric, + uint8_t type) { struct bgp *bgp = bgp_get_default(); struct prefix_rd prd; @@ -329,156 +329,33 @@ static void vnc_redistribute_withdraw(struct bgp *bgp, afi_t afi, uint8_t type) * * Assumes 1 nexthop */ -static int vnc_zebra_read_ipv4(int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int vnc_zebra_read_route(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct stream *s; - struct zapi_ipv4 api; - struct in_addr nexthop; - struct prefix_ipv4 p; + struct zapi_route api; + int add; - s = zclient->ibuf; - nexthop.s_addr = 0; + if (zapi_route_decode(zclient->ibuf, &api) < 0) + return -1; - /* Type, flags, message. */ - api.type = stream_getc(s); - api.flags = stream_getc(s); - api.message = stream_getc(s); - - /* IPv4 prefix. */ - memset(&p, 0, sizeof(struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = stream_getc(s); - stream_get(&p.prefix, s, PSIZE(p.prefixlen)); - - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { - api.nexthop_num = stream_getc(s); - nexthop.s_addr = stream_get_ipv4(s); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { - api.ifindex_num = stream_getc(s); - stream_getl(s); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(s); - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(s); - else - api.metric = 0; - - if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) { - if (BGP_DEBUG(zebra, ZEBRA)) { - char buf[2][INET_ADDRSTRLEN]; - vnc_zlog_debug_verbose( - "%s: Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u", - __func__, zebra_route_string(api.type), - inet_ntop(AF_INET, &p.prefix, buf[0], - sizeof(buf[0])), - p.prefixlen, inet_ntop(AF_INET, &nexthop, - buf[1], sizeof(buf[1])), - api.metric); - } - vnc_redistribute_add((struct prefix *)&p, &nexthop, api.metric, - api.type); - } else { - if (BGP_DEBUG(zebra, ZEBRA)) { - char buf[2][INET_ADDRSTRLEN]; - vnc_zlog_debug_verbose( - "%s: Zebra rcvd: IPv4 route delete %s %s/%d " - "nexthop %s metric %u", - __func__, zebra_route_string(api.type), - inet_ntop(AF_INET, &p.prefix, buf[0], - sizeof(buf[0])), - p.prefixlen, inet_ntop(AF_INET, &nexthop, - buf[1], sizeof(buf[1])), - api.metric); - } - vnc_redistribute_delete((struct prefix *)&p, api.type); - } - - return 0; -} - -/* Zebra route add and delete treatment. */ -static int vnc_zebra_read_ipv6(int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) -{ - struct stream *s; - struct zapi_ipv6 api; - struct in6_addr nexthop; - struct prefix_ipv6 p, src_p; - - s = zclient->ibuf; - memset(&nexthop, 0, sizeof(struct in6_addr)); - - /* Type, flags, message. */ - api.type = stream_getc(s); - api.flags = stream_getc(s); - api.message = stream_getc(s); - - /* IPv6 prefix. */ - memset(&p, 0, sizeof(struct prefix_ipv6)); - p.family = AF_INET6; - p.prefixlen = stream_getc(s); - stream_get(&p.prefix, s, PSIZE(p.prefixlen)); - - memset(&src_p, 0, sizeof(struct prefix_ipv6)); - src_p.family = AF_INET6; - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { - src_p.prefixlen = stream_getc(s); - stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); - } - - if (src_p.prefixlen) - /* we completely ignore srcdest routes for now. */ + /* we completely ignore srcdest routes for now. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) return 0; - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { - api.nexthop_num = stream_getc(s); - stream_get(&nexthop, s, 16); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { - api.ifindex_num = stream_getc(s); - stream_getl(s); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(s); + add = (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD); + if (add) + vnc_redistribute_add(&api.prefix, api.metric, api.type); else - api.distance = 0; - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(s); - else - api.metric = 0; + vnc_redistribute_delete(&api.prefix, api.type); - /* Simply ignore link-local address. */ - if (IN6_IS_ADDR_LINKLOCAL(&p.prefix)) - return 0; + if (BGP_DEBUG(zebra, ZEBRA)) { + char buf[PREFIX_STRLEN]; - if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) { - if (BGP_DEBUG(zebra, ZEBRA)) { - char buf[INET6_ADDRSTRLEN]; - vnc_zlog_debug_verbose( - "Zebra rcvd: IPv6 route add %s %s/%d metric %u", - zebra_route_string(api.type), - inet_ntop(AF_INET6, &p.prefix, buf, - sizeof(buf)), - p.prefixlen, api.metric); - } - vnc_redistribute_add((struct prefix *)&p, NULL, api.metric, - api.type); - } else { - if (BGP_DEBUG(zebra, ZEBRA)) { - char buf[INET6_ADDRSTRLEN]; - vnc_zlog_debug_verbose( - "Zebra rcvd: IPv6 route delete %s %s/%d metric %u", - zebra_route_string(api.type), - inet_ntop(AF_INET6, &p.prefix, buf, - sizeof(buf)), - p.prefixlen, api.metric); - } - vnc_redistribute_delete((struct prefix *)&p, api.type); + prefix2str(&api.prefix, buf, sizeof(buf)); + vnc_zlog_debug_verbose( + "%s: Zebra rcvd: route delete %s %s metric %u", + __func__, zebra_route_string(api.type), buf, + api.metric); } return 0; @@ -1016,10 +893,8 @@ void vnc_zebra_init(struct thread_master *master) zclient_vnc = zclient_new(master); zclient_init(zclient_vnc, ZEBRA_ROUTE_VNC, 0); - zclient_vnc->redistribute_route_ipv4_add = vnc_zebra_read_ipv4; - zclient_vnc->redistribute_route_ipv4_del = vnc_zebra_read_ipv4; - zclient_vnc->redistribute_route_ipv6_add = vnc_zebra_read_ipv6; - zclient_vnc->redistribute_route_ipv6_del = vnc_zebra_read_ipv6; + zclient_vnc->redistribute_route_add = vnc_zebra_read_route; + zclient_vnc->redistribute_route_del = vnc_zebra_read_route; } void vnc_zebra_destroy(void) diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index 2e386fbf2e..5aa7821e18 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -66,8 +66,8 @@ static int eigrp_interface_state_down(int, struct zclient *, zebra_size_t, vrf_id_t vrf_id); static struct interface *zebra_interface_if_lookup(struct stream *); -static int eigrp_zebra_read_ipv4(int, struct zclient *, zebra_size_t, - vrf_id_t vrf_id); +static int eigrp_zebra_read_route(int, struct zclient *, zebra_size_t, + vrf_id_t vrf_id); /* Zebra structure to hold current status. */ struct zclient *zclient = NULL; @@ -112,59 +112,31 @@ void eigrp_zebra_init(void) zclient->interface_down = eigrp_interface_state_down; zclient->interface_address_add = eigrp_interface_address_add; zclient->interface_address_delete = eigrp_interface_address_delete; - zclient->redistribute_route_ipv4_add = eigrp_zebra_read_ipv4; - zclient->redistribute_route_ipv4_del = eigrp_zebra_read_ipv4; + zclient->redistribute_route_add = eigrp_zebra_read_route; + zclient->redistribute_route_del = eigrp_zebra_read_route; } /* Zebra route add and delete treatment. */ -static int eigrp_zebra_read_ipv4(int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int eigrp_zebra_read_route(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct stream *s; - struct zapi_ipv4 api; - struct prefix_ipv4 p; + struct zapi_route api; struct eigrp *eigrp; - s = zclient->ibuf; + if (zapi_route_decode(zclient->ibuf, &api) < 0) + return -1; - /* Type, flags, message. */ - api.type = stream_getc(s); - api.instance = stream_getw(s); - api.flags = stream_getc(s); - api.message = stream_getc(s); - - /* IPv4 prefix. */ - memset(&p, 0, sizeof(struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s)); - stream_get(&p.prefix, s, PSIZE(p.prefixlen)); - - if (IPV4_NET127(ntohl(p.prefix.s_addr))) + if (IPV4_NET127(ntohl(api.prefix.u.prefix4.s_addr))) return 0; - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { - api.nexthop_num = stream_getc(s); - stream_get_ipv4(s); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { - api.ifindex_num = stream_getc(s); - /* XXX assert(api.ifindex_num == 1); */ - stream_getl(s); /* ifindex, unused */ - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(s); - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(s); - eigrp = eigrp_lookup(); if (eigrp == NULL) return 0; - if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) { + if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) { - } else /* if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL) */ + } else /* if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */ { } diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index e3537e2a0c..ed96bd31c2 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -344,122 +344,32 @@ void isis_zebra_route_update(struct prefix *prefix, isis_zebra_route_del_route(prefix, route_info); } -static int isis_zebra_read_ipv4(int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int isis_zebra_read(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct stream *stream; - struct zapi_ipv4 api; - struct prefix_ipv4 p; - struct prefix *p_generic = (struct prefix *)&p; + struct zapi_route api; - stream = zclient->ibuf; - memset(&api, 0, sizeof(api)); - memset(&p, 0, sizeof(struct prefix_ipv4)); + if (zapi_route_decode(zclient->ibuf, &api) < 0) + return -1; - api.type = stream_getc(stream); - api.instance = stream_getw(stream); - api.flags = stream_getl(stream); - api.message = stream_getc(stream); - - p.family = AF_INET; - p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(stream)); - stream_get(&p.prefix, stream, PSIZE(p.prefixlen)); - - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { - api.nexthop_num = stream_getc(stream); - (void)stream_get_ipv4(stream); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { - api.ifindex_num = stream_getc(stream); - stream_getl(stream); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(stream); - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(stream); - - /* - * Avoid advertising a false default reachability. (A default - * route installed by IS-IS gets redistributed from zebra back - * into IS-IS causing us to start advertising default reachabity - * without this check) - */ - if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS) - command = ZEBRA_REDISTRIBUTE_IPV4_DEL; - - if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) - isis_redist_add(api.type, p_generic, api.distance, api.metric); - else - isis_redist_delete(api.type, p_generic); - - return 0; -} - -static int isis_zebra_read_ipv6(int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) -{ - struct stream *stream; - struct zapi_ipv6 api; - struct prefix_ipv6 p; - struct prefix src_p; - struct prefix *p_generic = (struct prefix *)&p; - struct in6_addr nexthop; - unsigned long ifindex __attribute__((unused)); - - stream = zclient->ibuf; - memset(&api, 0, sizeof(api)); - memset(&p, 0, sizeof(struct prefix_ipv6)); - memset(&nexthop, 0, sizeof(nexthop)); - ifindex = 0; - - api.type = stream_getc(stream); - api.instance = stream_getw(stream); - api.flags = stream_getl(stream); - api.message = stream_getc(stream); - - p.family = AF_INET6; - p.prefixlen = stream_getc(stream); - stream_get(&p.prefix, stream, PSIZE(p.prefixlen)); - - memset(&src_p, 0, sizeof(struct prefix)); - src_p.family = AF_INET6; - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { - src_p.prefixlen = stream_getc(stream); - stream_get(&src_p.u.prefix6, stream, PSIZE(src_p.prefixlen)); - } - - if (src_p.prefixlen) - /* we completely ignore srcdest routes for now. */ + /* we completely ignore srcdest routes for now. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) return 0; - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { - api.nexthop_num = stream_getc(stream); /* this is always 1 */ - stream_get(&nexthop, stream, sizeof(nexthop)); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { - api.ifindex_num = stream_getc(stream); - ifindex = stream_getl(stream); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(stream); - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(stream); - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl(stream); - /* * Avoid advertising a false default reachability. (A default * route installed by IS-IS gets redistributed from zebra back * into IS-IS causing us to start advertising default reachabity * without this check) */ - if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS) - command = ZEBRA_REDISTRIBUTE_IPV6_DEL; + if (api.prefix.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS) + command = ZEBRA_REDISTRIBUTE_ROUTE_DEL; - if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) - isis_redist_add(api.type, p_generic, api.distance, api.metric); + if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) + isis_redist_add(api.type, &api.prefix, api.distance, + api.metric); else - isis_redist_delete(api.type, p_generic); + isis_redist_delete(api.type, &api.prefix); return 0; } @@ -507,10 +417,8 @@ void isis_zebra_init(struct thread_master *master) zclient->interface_address_add = isis_zebra_if_address_add; zclient->interface_address_delete = isis_zebra_if_address_del; zclient->interface_link_params = isis_zebra_link_params; - zclient->redistribute_route_ipv4_add = isis_zebra_read_ipv4; - zclient->redistribute_route_ipv4_del = isis_zebra_read_ipv4; - zclient->redistribute_route_ipv6_add = isis_zebra_read_ipv6; - zclient->redistribute_route_ipv6_del = isis_zebra_read_ipv6; + zclient->redistribute_route_add = isis_zebra_read; + zclient->redistribute_route_del = isis_zebra_read; return; } diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c index 54c5af62a4..c50cc0fda2 100644 --- a/ldpd/ldp_zebra.c +++ b/ldpd/ldp_zebra.c @@ -396,19 +396,34 @@ static int ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { - struct stream *s; - u_char type; - u_char message_flags; + struct zapi_route api; + struct zapi_nexthop *api_nh; struct kroute kr; - int nhnum = 0, nhlen; - size_t nhmark; - int add = 0; + int i, add = 0; + + if (zapi_route_decode(zclient->ibuf, &api) < 0) + return -1; + + /* we completely ignore srcdest routes for now. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) + return (0); memset(&kr, 0, sizeof(kr)); - s = zclient->ibuf; + kr.af = api.prefix.family; + switch (kr.af) { + case AF_INET: + kr.prefix.v4 = api.prefix.u.prefix4; + break; + case AF_INET6: + kr.prefix.v6 = api.prefix.u.prefix6; + break; + default: + break; + } + kr.prefixlen = api.prefix.prefixlen; + kr.priority = api.distance; - type = stream_getc(s); - switch (type) { + switch (api.type) { case ZEBRA_ROUTE_CONNECT: kr.flags |= F_CONNECTED; break; @@ -419,85 +434,38 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length, break; } - stream_getl(s); /* flags, unused */ - stream_getw(s); /* instance, unused */ - message_flags = stream_getc(s); - - switch (command) { - case ZEBRA_REDISTRIBUTE_IPV4_ADD: - case ZEBRA_REDISTRIBUTE_IPV4_DEL: - kr.af = AF_INET; - kr.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s)); - nhlen = sizeof(struct in_addr); - break; - case ZEBRA_REDISTRIBUTE_IPV6_ADD: - case ZEBRA_REDISTRIBUTE_IPV6_DEL: - kr.af = AF_INET6; - kr.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc(s)); - nhlen = sizeof(struct in6_addr); - break; - default: - fatalx("ldp_zebra_read_route: unknown command"); - } - stream_get(&kr.prefix, s, PSIZE(kr.prefixlen)); - if (bad_addr(kr.af, &kr.prefix) || (kr.af == AF_INET6 && IN6_IS_SCOPE_EMBED(&kr.prefix.v6))) return (0); - if (kr.af == AF_INET6 && - CHECK_FLAG(message_flags, ZAPI_MESSAGE_SRCPFX)) { - uint8_t src_prefixlen; - - src_prefixlen = stream_getc(s); - - /* we completely ignore srcdest routes for now. */ - if (src_prefixlen) - return (0); - } - - if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP)) { - nhnum = stream_getc(s); - nhmark = stream_get_getp(s); - stream_set_getp(s, nhmark + nhnum * (nhlen + 5)); - } - - if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_DISTANCE)) - kr.priority = stream_getc(s); - if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_METRIC)) - stream_getl(s); /* metric, not used */ - - if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP)) - stream_set_getp(s, nhmark); - - if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD || - command == ZEBRA_REDISTRIBUTE_IPV6_ADD) + if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) add = 1; - if (nhnum == 0) + if (api.nexthop_num == 0) debug_zebra_in("route %s %s/%d (%s)", (add) ? "add" : "delete", log_addr(kr.af, &kr.prefix), kr.prefixlen, - zebra_route_string(type)); + zebra_route_string(api.type)); /* loop through all the nexthops */ - for (; nhnum > 0; nhnum--) { + for (i = 0; i < api.nexthop_num; i++) { + api_nh = &api.nexthops[i]; + switch (kr.af) { case AF_INET: - kr.nexthop.v4.s_addr = stream_get_ipv4(s); + kr.nexthop.v4 = api_nh->gate.ipv4; break; case AF_INET6: - stream_get(&kr.nexthop.v6, s, sizeof(kr.nexthop.v6)); + kr.nexthop.v6 = api_nh->gate.ipv6; break; default: break; } - stream_getc(s); /* ifindex_num, unused. */ - kr.ifindex = stream_getl(s); + kr.ifindex = api_nh->ifindex;; debug_zebra_in("route %s %s/%d nexthop %s ifindex %u (%s)", (add) ? "add" : "delete", log_addr(kr.af, &kr.prefix), kr.prefixlen, log_addr(kr.af, &kr.nexthop), kr.ifindex, - zebra_route_string(type)); + zebra_route_string(api.type)); if (add) main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr, @@ -554,10 +522,8 @@ ldp_zebra_init(struct thread_master *master) zclient->interface_down = ldp_interface_status_change; zclient->interface_address_add = ldp_interface_address_add; zclient->interface_address_delete = ldp_interface_address_delete; - zclient->redistribute_route_ipv4_add = ldp_zebra_read_route; - zclient->redistribute_route_ipv4_del = ldp_zebra_read_route; - zclient->redistribute_route_ipv6_add = ldp_zebra_read_route; - zclient->redistribute_route_ipv6_del = ldp_zebra_read_route; + zclient->redistribute_route_add = ldp_zebra_read_route; + zclient->redistribute_route_del = ldp_zebra_read_route; zclient->pw_status_update = ldp_zebra_read_pw_status_update; } diff --git a/lib/log.c b/lib/log.c index 92b2d3b66b..0ea52ed401 100644 --- a/lib/log.c +++ b/lib/log.c @@ -895,10 +895,8 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_BFD_DEST_DEREGISTER), DESC_ENTRY(ZEBRA_BFD_DEST_UPDATE), DESC_ENTRY(ZEBRA_BFD_DEST_REPLAY), - DESC_ENTRY(ZEBRA_REDISTRIBUTE_IPV4_ADD), - DESC_ENTRY(ZEBRA_REDISTRIBUTE_IPV4_DEL), - DESC_ENTRY(ZEBRA_REDISTRIBUTE_IPV6_ADD), - DESC_ENTRY(ZEBRA_REDISTRIBUTE_IPV6_DEL), + DESC_ENTRY(ZEBRA_REDISTRIBUTE_ROUTE_ADD), + DESC_ENTRY(ZEBRA_REDISTRIBUTE_ROUTE_DEL), DESC_ENTRY(ZEBRA_VRF_UNREGISTER), DESC_ENTRY(ZEBRA_VRF_ADD), DESC_ENTRY(ZEBRA_VRF_DELETE), diff --git a/lib/zclient.c b/lib/zclient.c index e063c7151f..75005d656b 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -2112,25 +2112,15 @@ static int zclient_read(struct thread *thread) (*zclient->bfd_dest_replay)(command, zclient, length, vrf_id); break; - case ZEBRA_REDISTRIBUTE_IPV4_ADD: - if (zclient->redistribute_route_ipv4_add) - (*zclient->redistribute_route_ipv4_add)( - command, zclient, length, vrf_id); + case ZEBRA_REDISTRIBUTE_ROUTE_ADD: + if (zclient->redistribute_route_add) + (*zclient->redistribute_route_add)(command, zclient, + length, vrf_id); break; - case ZEBRA_REDISTRIBUTE_IPV4_DEL: - if (zclient->redistribute_route_ipv4_del) - (*zclient->redistribute_route_ipv4_del)( - command, zclient, length, vrf_id); - break; - case ZEBRA_REDISTRIBUTE_IPV6_ADD: - if (zclient->redistribute_route_ipv6_add) - (*zclient->redistribute_route_ipv6_add)( - command, zclient, length, vrf_id); - break; - case ZEBRA_REDISTRIBUTE_IPV6_DEL: - if (zclient->redistribute_route_ipv6_del) - (*zclient->redistribute_route_ipv6_del)( - command, zclient, length, vrf_id); + case ZEBRA_REDISTRIBUTE_ROUTE_DEL: + if (zclient->redistribute_route_del) + (*zclient->redistribute_route_del)(command, zclient, + length, vrf_id); break; case ZEBRA_INTERFACE_LINK_PARAMS: if (zclient->interface_link_params) diff --git a/lib/zclient.h b/lib/zclient.h index 40ddbf62df..f454a9d8ac 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -21,7 +21,7 @@ #ifndef _ZEBRA_ZCLIENT_H #define _ZEBRA_ZCLIENT_H -/* For struct zapi_ipv{4,6}. */ +/* For struct zapi_route. */ #include "prefix.h" /* For struct interface and struct connected. */ @@ -87,10 +87,8 @@ typedef enum { ZEBRA_BFD_DEST_DEREGISTER, ZEBRA_BFD_DEST_UPDATE, ZEBRA_BFD_DEST_REPLAY, - ZEBRA_REDISTRIBUTE_IPV4_ADD, - ZEBRA_REDISTRIBUTE_IPV4_DEL, - ZEBRA_REDISTRIBUTE_IPV6_ADD, - ZEBRA_REDISTRIBUTE_IPV6_DEL, + ZEBRA_REDISTRIBUTE_ROUTE_ADD, + ZEBRA_REDISTRIBUTE_ROUTE_DEL, ZEBRA_VRF_UNREGISTER, ZEBRA_VRF_ADD, ZEBRA_VRF_DELETE, @@ -188,14 +186,10 @@ struct zclient { int (*nexthop_update)(int, struct zclient *, uint16_t, vrf_id_t); int (*import_check_update)(int, struct zclient *, uint16_t, vrf_id_t); int (*bfd_dest_replay)(int, struct zclient *, uint16_t, vrf_id_t); - int (*redistribute_route_ipv4_add)(int, struct zclient *, uint16_t, - vrf_id_t); - int (*redistribute_route_ipv4_del)(int, struct zclient *, uint16_t, - vrf_id_t); - int (*redistribute_route_ipv6_add)(int, struct zclient *, uint16_t, - vrf_id_t); - int (*redistribute_route_ipv6_del)(int, struct zclient *, uint16_t, - vrf_id_t); + int (*redistribute_route_add)(int, struct zclient *, uint16_t, + vrf_id_t); + int (*redistribute_route_del)(int, struct zclient *, uint16_t, + vrf_id_t); int (*fec_update)(int, struct zclient *, uint16_t); int (*local_vni_add)(int, struct zclient *, uint16_t, vrf_id_t); int (*local_vni_del)(int, struct zclient *, uint16_t, vrf_id_t); @@ -206,13 +200,12 @@ struct zclient { /* Zebra API message flag. */ #define ZAPI_MESSAGE_NEXTHOP 0x01 -#define ZAPI_MESSAGE_IFINDEX 0x02 -#define ZAPI_MESSAGE_DISTANCE 0x04 -#define ZAPI_MESSAGE_METRIC 0x08 -#define ZAPI_MESSAGE_TAG 0x10 -#define ZAPI_MESSAGE_MTU 0x20 -#define ZAPI_MESSAGE_SRCPFX 0x40 -#define ZAPI_MESSAGE_LABEL 0x80 +#define ZAPI_MESSAGE_DISTANCE 0x02 +#define ZAPI_MESSAGE_METRIC 0x04 +#define ZAPI_MESSAGE_TAG 0x08 +#define ZAPI_MESSAGE_MTU 0x10 +#define ZAPI_MESSAGE_SRCPFX 0x20 +#define ZAPI_MESSAGE_LABEL 0x40 /* Zserv protocol message header */ struct zserv_header { diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index b744218c9a..4b86bca5f7 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -167,83 +167,47 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix int nhrp_route_read(int cmd, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { - struct stream *s; + struct zapi_route api; + struct zapi_nexthop *api_nh; struct interface *ifp = NULL; - struct prefix prefix; - struct prefix_ipv6 src_p; union sockunion nexthop_addr; - unsigned char message, nexthop_num, ifindex_num; - unsigned ifindex; char buf[2][PREFIX_STRLEN]; - int i, afaddrlen, added; + int added; - s = zclient->ibuf; - memset(&prefix, 0, sizeof(prefix)); - sockunion_family(&nexthop_addr) = AF_UNSPEC; - - /* Type, flags, message. */ - /*type =*/ stream_getc(s); - /*instance =*/ stream_getw(s); - /*flags =*/ stream_getl(s); - message = stream_getc(s); - - /* Prefix */ - switch (cmd) { - case ZEBRA_REDISTRIBUTE_IPV4_ADD: - case ZEBRA_REDISTRIBUTE_IPV4_DEL: - prefix.family = AF_INET; - prefix.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s)); - break; - case ZEBRA_REDISTRIBUTE_IPV6_ADD: - case ZEBRA_REDISTRIBUTE_IPV6_DEL: - prefix.family = AF_INET6; - prefix.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc(s)); - break; - default: + if (zapi_route_decode(zclient->ibuf, &api) < 0) return -1; - } - afaddrlen = family2addrsize(prefix.family); - stream_get(&prefix.u.val, s, PSIZE(prefix.prefixlen)); - memset(&src_p, 0, sizeof(src_p)); - if (prefix.family == AF_INET6 && - CHECK_FLAG(message, ZAPI_MESSAGE_SRCPFX)) { - src_p.family = AF_INET6; - src_p.prefixlen = stream_getc(s); - stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); - } - if (src_p.prefixlen) - /* we completely ignore srcdest routes for now. */ + /* we completely ignore srcdest routes for now. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) return 0; - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX)) { - nexthop_num = stream_getc(s); - for (i = 0; i < nexthop_num; i++) { - stream_get(buf[0], s, afaddrlen); - if (i == 0) sockunion_set(&nexthop_addr, prefix.family, (u_char*) buf[0], afaddrlen); - } - ifindex_num = stream_getc(s); - for (i = 0; i < ifindex_num; i++) { - ifindex = stream_getl(s); - if (i == 0 && ifindex != IFINDEX_INTERNAL) - ifp = if_lookup_by_index(ifindex, VRF_DEFAULT); - } - } - if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) - /*distance =*/ stream_getc(s); - if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) - /*metric =*/ stream_getl(s); + sockunion_family(&nexthop_addr) = AF_UNSPEC; + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { + api_nh = &api.nexthops[0]; - added = (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD || cmd == ZEBRA_REDISTRIBUTE_IPV6_ADD); + nexthop_addr.sa.sa_family = api.prefix.family; + switch (nexthop_addr.sa.sa_family) { + case AF_INET: + nexthop_addr.sin.sin_addr = api_nh->gate.ipv4; + break; + case AF_INET6: + nexthop_addr.sin6.sin6_addr = api_nh->gate.ipv6; + break; + } + + if (api_nh->ifindex != IFINDEX_INTERNAL) + ifp = if_lookup_by_index(api_nh->ifindex, VRF_DEFAULT); + } + + added = (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD); debugf(NHRP_DEBUG_ROUTE, "if-route-%s: %s via %s dev %s", added ? "add" : "del", - prefix2str(&prefix, buf[0], sizeof buf[0]), + prefix2str(&api.prefix, buf[0], sizeof buf[0]), sockunion2str(&nexthop_addr, buf[1], sizeof buf[1]), ifp ? ifp->name : "(none)"); - nhrp_route_update_zebra(&prefix, &nexthop_addr, ifp); - nhrp_shortcut_prefix_change(&prefix, !added); + nhrp_route_update_zebra(&api.prefix, &nexthop_addr, ifp); + nhrp_shortcut_prefix_change(&api.prefix, !added); return 0; } @@ -356,10 +320,8 @@ void nhrp_zebra_init(void) zclient->interface_down = nhrp_interface_down; zclient->interface_address_add = nhrp_interface_address_add; zclient->interface_address_delete = nhrp_interface_address_delete; - zclient->redistribute_route_ipv4_add = nhrp_route_read; - zclient->redistribute_route_ipv4_del = nhrp_route_read; - zclient->redistribute_route_ipv6_add = nhrp_route_read; - zclient->redistribute_route_ipv6_del = nhrp_route_read; + zclient->redistribute_route_add = nhrp_route_read; + zclient->redistribute_route_del = nhrp_route_read; zclient_init(zclient, ZEBRA_ROUTE_NHRP, 0); } @@ -371,4 +333,3 @@ void nhrp_zebra_terminate(void) route_table_finish(zebra_rib[AFI_IP]); route_table_finish(zebra_rib[AFI_IP6]); } - diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 5655502879..3443bc47b6 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -207,75 +207,30 @@ static int ospf6_zebra_if_address_update_delete(int command, return 0; } -static int ospf6_zebra_read_ipv6(int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf6_zebra_read_route(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct stream *s; - struct zapi_ipv6 api; + struct zapi_route api; unsigned long ifindex; - struct prefix p, src_p; struct in6_addr *nexthop; if (ospf6 == NULL) return 0; - s = zclient->ibuf; - ifindex = 0; - nexthop = NULL; - memset(&api, 0, sizeof(api)); + if (zapi_route_decode(zclient->ibuf, &api) < 0) + return -1; - /* Type, flags, message. */ - api.type = stream_getc(s); - api.instance = stream_getw(s); - api.flags = stream_getl(s); - api.message = stream_getc(s); - - /* IPv6 prefix. */ - memset(&p, 0, sizeof(struct prefix)); - p.family = AF_INET6; - p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc(s)); - stream_get(&p.u.prefix6, s, PSIZE(p.prefixlen)); - - memset(&src_p, 0, sizeof(struct prefix)); - src_p.family = AF_INET6; - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { - src_p.prefixlen = stream_getc(s); - stream_get(&src_p.u.prefix6, s, PSIZE(src_p.prefixlen)); - } - - if (src_p.prefixlen) - /* we completely ignore srcdest routes for now. */ + /* we completely ignore srcdest routes for now. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) return 0; - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { - api.nexthop_num = stream_getc(s); - nexthop = (struct in6_addr *)malloc(api.nexthop_num - * sizeof(struct in6_addr)); - stream_get(nexthop, s, - api.nexthop_num * sizeof(struct in6_addr)); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { - api.ifindex_num = stream_getc(s); - ifindex = stream_getl(s); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(s); - else - api.distance = 0; - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(s); - else - api.metric = 0; - - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl(s); - else - api.tag = 0; + ifindex = api.nexthops[0].ifindex; + nexthop = &api.nexthops[0].gate.ipv6; if (IS_OSPF6_DEBUG_ZEBRA(RECV)) { char prefixstr[PREFIX2STR_BUFFER], nexthopstr[128]; - prefix2str((struct prefix *)&p, prefixstr, sizeof(prefixstr)); + prefix2str((struct prefix *)&api.prefix, prefixstr, + sizeof(prefixstr)); if (nexthop) inet_ntop(AF_INET6, nexthop, nexthopstr, sizeof(nexthopstr)); @@ -284,20 +239,17 @@ static int ospf6_zebra_read_ipv6(int command, struct zclient *zclient, zlog_debug( "Zebra Receive route %s: %s %s nexthop %s ifindex %ld tag %" ROUTE_TAG_PRI, - (command == ZEBRA_REDISTRIBUTE_IPV6_ADD ? "add" - : "delete"), + (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD ? "add" + : "delete"), zebra_route_string(api.type), prefixstr, nexthopstr, ifindex, api.tag); } - if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) - ospf6_asbr_redistribute_add(api.type, ifindex, &p, + if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) + ospf6_asbr_redistribute_add(api.type, ifindex, &api.prefix, api.nexthop_num, nexthop, api.tag); else - ospf6_asbr_redistribute_remove(api.type, ifindex, &p); - - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) - free(nexthop); + ospf6_asbr_redistribute_remove(api.type, ifindex, &api.prefix); return 0; } @@ -646,10 +598,8 @@ void ospf6_zebra_init(struct thread_master *master) zclient->interface_address_add = ospf6_zebra_if_address_update_add; zclient->interface_address_delete = ospf6_zebra_if_address_update_delete; - zclient->redistribute_route_ipv4_add = NULL; - zclient->redistribute_route_ipv4_del = NULL; - zclient->redistribute_route_ipv6_add = ospf6_zebra_read_ipv6; - zclient->redistribute_route_ipv6_del = ospf6_zebra_read_ipv6; + zclient->redistribute_route_add = ospf6_zebra_read_route; + zclient->redistribute_route_del = ospf6_zebra_read_route; /* Install command element for zebra node. */ install_element(VIEW_NODE, &show_ospf6_zebra_cmd); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 53b68a022b..dcb392f1ad 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -873,61 +873,32 @@ void ospf_routemap_unset(struct ospf_redist *red) } /* Zebra route add and delete treatment. */ -static int ospf_zebra_read_ipv4(int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf_zebra_read_route(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct stream *s; - struct zapi_ipv4 api; + struct zapi_route api; + struct prefix_ipv4 p; unsigned long ifindex; struct in_addr nexthop; - struct prefix_ipv4 p; struct external_info *ei; struct ospf *ospf; int i; - s = zclient->ibuf; - ifindex = 0; - nexthop.s_addr = 0; - - /* Type, flags, message. */ - api.type = stream_getc(s); - api.instance = stream_getw(s); - api.flags = stream_getl(s); - api.message = stream_getc(s); - - /* IPv4 prefix. */ - memset(&p, 0, sizeof(struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s)); - stream_get(&p.prefix, s, PSIZE(p.prefixlen)); - - if (IPV4_NET127(ntohl(p.prefix.s_addr))) - return 0; - - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { - api.nexthop_num = stream_getc(s); - nexthop.s_addr = stream_get_ipv4(s); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { - api.ifindex_num = stream_getc(s); - /* XXX assert(api.ifindex_num == 1); */ - ifindex = stream_getl(s); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(s); - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(s); - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl(s); - else - api.tag = 0; - ospf = ospf_lookup(); if (ospf == NULL) return 0; - if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) { + if (zapi_route_decode(zclient->ibuf, &api) < 0) + return -1; + + ifindex = api.nexthops[0].ifindex; + nexthop = api.nexthops[0].gate.ipv4; + + memcpy(&p, &api.prefix, sizeof(p)); + if (IPV4_NET127(ntohl(p.prefix.s_addr))) + return 0; + + if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) { /* XXX|HACK|TODO|FIXME: * Maybe we should ignore reject/blackhole routes? Testing shows * that @@ -942,7 +913,7 @@ static int ospf_zebra_read_ipv4(int command, struct zclient *zclient, * return 0; */ - /* Protocol tag overwrites all other tag value send by zebra */ + /* Protocol tag overwrites all other tag value sent by zebra */ if (ospf->dtag[api.type] > 0) api.tag = ospf->dtag[api.type]; @@ -984,7 +955,7 @@ static int ospf_zebra_read_ipv4(int command, struct zclient *zclient, zebra, ZEBRA_REDISTRIBUTE)) zlog_debug( - "ospf_zebra_read_ipv4() : %s refreshing LSA", + "ospf_zebra_read_route() : %s refreshing LSA", inet_ntoa( p.prefix)); ospf_external_lsa_refresh( @@ -994,7 +965,7 @@ static int ospf_zebra_read_ipv4(int command, struct zclient *zclient, } } } - } else /* if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL) */ + } else /* if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */ { ospf_external_info_delete(api.type, api.instance, p); if (is_prefix_default(&p)) @@ -1410,8 +1381,8 @@ void ospf_zebra_init(struct thread_master *master, u_short instance) zclient->interface_address_delete = ospf_interface_address_delete; zclient->interface_link_params = ospf_interface_link_params; - zclient->redistribute_route_ipv4_add = ospf_zebra_read_ipv4; - zclient->redistribute_route_ipv4_del = ospf_zebra_read_ipv4; + zclient->redistribute_route_add = ospf_zebra_read_route; + zclient->redistribute_route_del = ospf_zebra_read_route; access_list_add_hook(ospf_filter_update); access_list_delete_hook(ospf_filter_update); diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index 9a9bac51e0..2140e8b110 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -115,64 +115,31 @@ void rip_zebra_ipv4_delete(struct route_node *rp) } /* Zebra route add and delete treatment. */ -static int rip_zebra_read_ipv4(int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int rip_zebra_read_route(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct stream *s; - struct zapi_ipv4 api; - unsigned long ifindex; + struct zapi_route api; struct in_addr nexthop; - struct prefix_ipv4 p; + unsigned long ifindex; if (!rip) return 0; - s = zclient->ibuf; - ifindex = 0; - nexthop.s_addr = 0; + if (zapi_route_decode(zclient->ibuf, &api) < 0) + return -1; - /* Type, flags, message. */ - api.type = stream_getc(s); - api.instance = stream_getw(s); - api.flags = stream_getl(s); - api.message = stream_getc(s); - - /* IPv4 prefix. */ - memset(&p, 0, sizeof(struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s)); - stream_get(&p.prefix, s, PSIZE(p.prefixlen)); - - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { - api.nexthop_num = stream_getc(s); - nexthop.s_addr = stream_get_ipv4(s); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { - api.ifindex_num = stream_getc(s); - ifindex = stream_getl(s); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(s); - else - api.distance = 255; - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(s); - else - api.metric = 0; - - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl(s); - else - api.tag = 0; + nexthop = api.nexthops[0].gate.ipv4; + ifindex = api.nexthops[0].ifindex; /* Then fetch IPv4 prefixes. */ - if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) - rip_redistribute_add(api.type, RIP_ROUTE_REDISTRIBUTE, &p, - ifindex, &nexthop, api.metric, - api.distance, api.tag); - else if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL) - rip_redistribute_delete(api.type, RIP_ROUTE_REDISTRIBUTE, &p, + if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) + rip_redistribute_add(api.type, RIP_ROUTE_REDISTRIBUTE, + (struct prefix_ipv4 *)&api.prefix, ifindex, + &nexthop, api.metric, api.distance, + api.tag); + else if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL) + rip_redistribute_delete(api.type, RIP_ROUTE_REDISTRIBUTE, + (struct prefix_ipv4 *)&api.prefix, ifindex); return 0; @@ -625,8 +592,8 @@ void rip_zclient_init(struct thread_master *master) zclient->interface_address_delete = rip_interface_address_delete; zclient->interface_up = rip_interface_up; zclient->interface_down = rip_interface_down; - zclient->redistribute_route_ipv4_add = rip_zebra_read_ipv4; - zclient->redistribute_route_ipv4_del = rip_zebra_read_ipv4; + zclient->redistribute_route_add = rip_zebra_read_route; + zclient->redistribute_route_del = rip_zebra_read_route; /* Install command elements to rip node. */ install_element(RIP_NODE, &rip_redistribute_type_cmd); diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index a5ed5c7b2c..283d8691a3 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -109,71 +109,31 @@ void ripng_zebra_ipv6_delete(struct route_node *rp) } /* Zebra route add and delete treatment. */ -static int ripng_zebra_read_ipv6(int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ripng_zebra_read_route(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct stream *s; - struct zapi_ipv6 api; - unsigned long ifindex; + struct zapi_route api; struct in6_addr nexthop; - struct prefix_ipv6 p, src_p; + unsigned long ifindex; - s = zclient->ibuf; - ifindex = 0; - memset(&nexthop, 0, sizeof(struct in6_addr)); + if (zapi_route_decode(zclient->ibuf, &api) < 0) + return -1; - /* Type, flags, message. */ - api.type = stream_getc(s); - api.instance = stream_getw(s); - api.flags = stream_getl(s); - api.message = stream_getc(s); - - /* IPv6 prefix. */ - memset(&p, 0, sizeof(struct prefix_ipv6)); - p.family = AF_INET6; - p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc(s)); - stream_get(&p.prefix, s, PSIZE(p.prefixlen)); - - memset(&src_p, 0, sizeof(struct prefix_ipv6)); - src_p.family = AF_INET6; - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { - src_p.prefixlen = stream_getc(s); - stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); - } - - if (src_p.prefixlen) - /* we completely ignore srcdest routes for now. */ + /* we completely ignore srcdest routes for now. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) return 0; - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { - api.nexthop_num = stream_getc(s); - stream_get(&nexthop, s, 16); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { - api.ifindex_num = stream_getc(s); - ifindex = stream_getl(s); - } - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc(s); - else - api.distance = 0; - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl(s); - else - api.metric = 0; + nexthop = api.nexthops[0].gate.ipv6; + ifindex = api.nexthops[0].ifindex; - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl(s); - else - api.tag = 0; - - if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) - ripng_redistribute_add(api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, + if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) + ripng_redistribute_add(api.type, RIPNG_ROUTE_REDISTRIBUTE, + (struct prefix_ipv6 *)&api.prefix, ifindex, &nexthop, api.tag); else ripng_redistribute_delete(api.type, RIPNG_ROUTE_REDISTRIBUTE, - &p, ifindex); + (struct prefix_ipv6 *)&api.prefix, + ifindex); return 0; } @@ -461,8 +421,8 @@ void zebra_init(struct thread_master *master) zclient->interface_delete = ripng_interface_delete; zclient->interface_address_add = ripng_interface_address_add; zclient->interface_address_delete = ripng_interface_address_delete; - zclient->redistribute_route_ipv6_add = ripng_zebra_read_ipv6; - zclient->redistribute_route_ipv6_del = ripng_zebra_read_ipv6; + zclient->redistribute_route_add = ripng_zebra_read_route; + zclient->redistribute_route_del = ripng_zebra_read_route; /* Install command elements to ripng node */ install_element(RIPNG_NODE, &ripng_redistribute_type_cmd); diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 410ddcd4a0..9b21eb4d8c 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -95,8 +95,8 @@ static void zebra_redistribute_default(struct zserv *client, vrf_id_t vrf_id) RNODE_FOREACH_RE(rn, newre) if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED) && newre->distance != DISTANCE_INFINITY) - zsend_redistribute_route(1, client, &rn->p, NULL, - newre); + zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD, + client, &rn->p, NULL, newre); route_unlock_node(rn); } @@ -141,8 +141,8 @@ static void zebra_redistribute(struct zserv *client, int type, u_short instance, if (!zebra_check_addr(dst_p)) continue; - zsend_redistribute_route(1, client, dst_p, src_p, - newre); + zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD, + client, dst_p, src_p, newre); } } @@ -191,7 +191,8 @@ void redistribute_update(struct prefix *p, struct prefix *src_p, send_redistribute = 1; if (send_redistribute) { - zsend_redistribute_route(1, client, p, src_p, re); + zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD, + client, p, src_p, re); } else if (prev_re && ((re->instance && redist_check_instance( @@ -201,7 +202,8 @@ void redistribute_update(struct prefix *p, struct prefix *src_p, || vrf_bitmap_check( client->redist[afi][prev_re->type], re->vrf_id))) { - zsend_redistribute_route(0, client, p, src_p, prev_re); + zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL, + client, p, src_p, prev_re); } } } @@ -242,7 +244,8 @@ void redistribute_delete(struct prefix *p, struct prefix *src_p, re->instance)) || vrf_bitmap_check(client->redist[afi][re->type], re->vrf_id)) { - zsend_redistribute_route(0, client, p, src_p, re); + zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL, + client, p, src_p, re); } } } diff --git a/zebra/zserv.c b/zebra/zserv.c index de475dccfd..56cca10654 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -592,193 +592,76 @@ int zsend_interface_update(int cmd, struct zserv *client, struct interface *ifp) return zebra_server_send_message(client); } -/* - * This is the new function to announce and withdraw redistributed routes, used - * by Zebra. This is the old zsend_route_multipath() function. That function - * was duplicating code to send a lot of information that was essentially thrown - * away or ignored by the receiver. This is the leaner function that is not a - * duplicate of the zapi_ipv4_route_add/del. - * - * The primary difference is that this function merely sends a single NH instead - * of - * all the nexthops. - */ -int zsend_redistribute_route(int add, struct zserv *client, struct prefix *p, +int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p, struct prefix *src_p, struct route_entry *re) { - afi_t afi; - int cmd; - int psize; - struct stream *s; + struct zapi_route api; + struct zapi_nexthop *api_nh; struct nexthop *nexthop; - unsigned long nhnummark = 0, messmark = 0; - int nhnum = 0; - u_char zapi_flags = 0; - struct nexthop dummy_nh; + int count = 0; - afi = family2afi(p->family); - if (add) { - switch (afi) { - case AFI_IP: - cmd = ZEBRA_REDISTRIBUTE_IPV4_ADD; - client->redist_v4_add_cnt++; - break; - case AFI_IP6: - cmd = ZEBRA_REDISTRIBUTE_IPV6_ADD; - client->redist_v6_add_cnt++; - break; - default: - return -1; - } - } else { - switch (afi) { - case AFI_IP: - cmd = ZEBRA_REDISTRIBUTE_IPV4_DEL; - client->redist_v4_del_cnt++; - break; - case AFI_IP6: - cmd = ZEBRA_REDISTRIBUTE_IPV6_DEL; - client->redist_v6_del_cnt++; - break; - default: - return -1; - } - } - - s = client->obuf; - stream_reset(s); - memset(&dummy_nh, 0, sizeof(struct nexthop)); - - zserv_create_header(s, cmd, re->vrf_id); - - /* Put type and nexthop. */ - stream_putc(s, re->type); - stream_putw(s, re->instance); - stream_putl(s, re->flags); - - /* marker for message flags field */ - messmark = stream_get_endp(s); - stream_putc(s, 0); + memset(&api, 0, sizeof(api)); + api.vrf_id = VRF_DEFAULT; + api.type = re->type; + api.instance = re->instance; + api.flags = re->flags; /* Prefix. */ - psize = PSIZE(p->prefixlen); - stream_putc(s, p->prefixlen); - stream_write(s, (u_char *)&p->u.prefix, psize); - + api.prefix = *p; if (src_p) { - SET_FLAG(zapi_flags, ZAPI_MESSAGE_SRCPFX); - psize = PSIZE(src_p->prefixlen); - stream_putc(s, src_p->prefixlen); - stream_write(s, (u_char *)&src_p->u.prefix, psize); + SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX); + memcpy(&api.src_prefix, src_p, sizeof(api.src_prefix)); } + /* Nexthops. */ + if (re->nexthop_active_num) { + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = re->nexthop_active_num; + } for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) { - /* We don't send any nexthops when there's a multipath */ - if (re->nexthop_active_num > 1 - && client->proto != ZEBRA_ROUTE_LDP) { - SET_FLAG(zapi_flags, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG(zapi_flags, ZAPI_MESSAGE_IFINDEX); + if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + continue; - stream_putc(s, 1); - if (p->family == AF_INET) { - stream_put_in_addr(s, &dummy_nh.gate.ipv4); - } else if (p->family == AF_INET6) { - stream_write(s, (u_char *)&dummy_nh.gate.ipv6, - 16); - } else { - /* We don't handle anything else now, abort */ - zlog_err( - "%s: Unable to redistribute route of unknown family, %d\n", - __func__, p->family); - return -1; - } - stream_putc(s, 1); - stream_putl(s, 0); /* dummy ifindex */ + api_nh = &api.nexthops[count]; + api_nh->type = nexthop->type; + switch (nexthop->type) { + case NEXTHOP_TYPE_BLACKHOLE: break; + case NEXTHOP_TYPE_IPV4: + api_nh->gate.ipv4 = nexthop->gate.ipv4; + break; + case NEXTHOP_TYPE_IPV4_IFINDEX: + api_nh->gate.ipv4 = nexthop->gate.ipv4; + api_nh->ifindex = nexthop->ifindex; + break; + case NEXTHOP_TYPE_IFINDEX: + api_nh->ifindex = nexthop->ifindex; + break; + case NEXTHOP_TYPE_IPV6: + api_nh->gate.ipv6 = nexthop->gate.ipv6; + break; + case NEXTHOP_TYPE_IPV6_IFINDEX: + api_nh->gate.ipv6 = nexthop->gate.ipv6; + api_nh->ifindex = nexthop->ifindex; } - - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) { - SET_FLAG(zapi_flags, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG(zapi_flags, ZAPI_MESSAGE_IFINDEX); - if (nhnummark == 0) { - nhnummark = stream_get_endp(s); - stream_putc(s, 1); /* placeholder */ - } - nhnum++; - - switch (nexthop->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - stream_put_in_addr(s, &nexthop->gate.ipv4); - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - /* Only BGP supports IPv4 prefix with IPv6 NH, - * so kill this */ - if (p->family == AF_INET) - stream_put_in_addr(s, - &dummy_nh.gate.ipv4); - else - stream_write( - s, - (u_char *)&nexthop->gate.ipv6, - 16); - break; - default: - if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD - || cmd == ZEBRA_REDISTRIBUTE_IPV4_DEL) { - struct in_addr empty; - memset(&empty, 0, - sizeof(struct in_addr)); - stream_write(s, (u_char *)&empty, - IPV4_MAX_BYTELEN); - } else { - struct in6_addr empty; - memset(&empty, 0, - sizeof(struct in6_addr)); - stream_write(s, (u_char *)&empty, - IPV6_MAX_BYTELEN); - } - } - - /* Interface index. */ - stream_putc(s, 1); - stream_putl(s, nexthop->ifindex); - - /* ldpd needs all nexthops */ - if (client->proto != ZEBRA_ROUTE_LDP) - break; - } + count++; } - /* Distance */ - SET_FLAG(zapi_flags, ZAPI_MESSAGE_DISTANCE); - stream_putc(s, re->distance); - - /* Metric */ - SET_FLAG(zapi_flags, ZAPI_MESSAGE_METRIC); - stream_putl(s, re->metric); - - /* Tag */ + /* Attributes. */ + SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); + api.distance = re->distance; + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = re->metric; if (re->tag) { - SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG); - stream_putl(s, re->tag); + SET_FLAG(api.message, ZAPI_MESSAGE_TAG); + api.tag = re->tag; } + SET_FLAG(api.message, ZAPI_MESSAGE_MTU); + api.mtu = re->mtu; - /* MTU */ - SET_FLAG(zapi_flags, ZAPI_MESSAGE_MTU); - stream_putl(s, re->mtu); - - /* write real message flags value */ - stream_putc_at(s, messmark, zapi_flags); - - /* Write next-hop number */ - if (nhnummark) - stream_putc_at(s, nhnummark, nhnum); - - /* Write packet size. */ - stream_putw_at(s, 0, stream_get_endp(s)); - + /* Encode route and send. */ + if (zapi_route_encode(cmd, client->obuf, &api) < 0) + return -1; return zebra_server_send_message(client); } From b30f3b91d4d91e5d58f2f999e2f673aeaf15d653 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Mon, 21 Aug 2017 19:43:43 -0300 Subject: [PATCH 47/79] ospf6d: fix regression detected by topotest With the old API, ospf6d always needed to send a nexthop address and a nexthop interface when advertising a route to zebra. In the case where the nexthop address didn't exist (e.g. connected route), zebra would take care of ignore it in the zread_ipv6_add() function. Now, if we have a nexthop interface but not a nexthop address, we not only can but we should send a nexthop of type NEXTHOP_TYPE_IFINDEX. zebra won't fix bad nexthops anymore because the clients have a proper API to send correct messages. Signed-off-by: Renato Westphal --- ospf6d/ospf6_route.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 03791ad7a0..e58eab2b15 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -305,14 +305,16 @@ void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route, zlog_debug(" nexthop: %s%%%.*s(%d)", buf, IFNAMSIZ, ifname, nh->ifindex); } - if (i < entries) { - nexthops[i].gate.ipv6 = nh->address; - nexthops[i].ifindex = nh->ifindex; - nexthops[i].type = NEXTHOP_TYPE_IPV6_IFINDEX; - i++; - } else { + if (i >= entries) return; - } + + nexthops[i].ifindex = nh->ifindex; + if (!IN6_IS_ADDR_UNSPECIFIED(&nh->address)) { + nexthops[i].gate.ipv6 = nh->address; + nexthops[i].type = NEXTHOP_TYPE_IPV6_IFINDEX; + } else + nexthops[i].type = NEXTHOP_TYPE_IFINDEX; + i++; } } } From f474e08be0c3c6e92bf265700d013388183f0acb Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 23 Aug 2017 19:12:48 -0300 Subject: [PATCH 48/79] lib: mark the old zebra API for route advertisement as deprecated Signed-off-by: Renato Westphal --- lib/zclient.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/zclient.h b/lib/zclient.h index f454a9d8ac..bae52a441b 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -369,7 +369,7 @@ extern struct interface *zebra_interface_vrf_update_read(struct stream *s, extern void zebra_interface_if_set_value(struct stream *, struct interface *); extern void zebra_router_id_update_read(struct stream *s, struct prefix *rid); extern int zapi_ipv4_route(u_char, struct zclient *, struct prefix_ipv4 *, - struct zapi_ipv4 *); + struct zapi_ipv4 *) __attribute__((deprecated)); extern struct interface *zebra_interface_link_params_read(struct stream *); extern size_t zebra_interface_link_params_write(struct stream *, @@ -420,10 +420,11 @@ struct zapi_ipv6 { extern int zapi_ipv6_route(u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p, struct prefix_ipv6 *src_p, - struct zapi_ipv6 *api); + struct zapi_ipv6 *api) __attribute__((deprecated)); extern int zapi_ipv4_route_ipv6_nexthop(u_char, struct zclient *, struct prefix_ipv4 *, - struct zapi_ipv6 *); + struct zapi_ipv6 *) + __attribute__((deprecated)); extern int zclient_route_send(u_char, struct zclient *, struct zapi_route *); extern int zapi_route_encode(u_char, struct stream *, struct zapi_route *); extern int zapi_route_decode(struct stream *, struct zapi_route *); From 98ca91e95a8c0dbc3febe5e2ce84e1a6640c9459 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 24 Aug 2017 08:02:27 -0400 Subject: [PATCH 49/79] zebra: Fix compiler warnings Signed-off-by: Donald Sharp --- zebra/zserv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zebra/zserv.c b/zebra/zserv.c index 56cca10654..7899a8375c 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1049,7 +1049,7 @@ static int zread_route_add(struct zserv *client, u_short length, afi_t afi; struct prefix_ipv6 *src_p = NULL; struct route_entry *re; - struct nexthop *nexthop; + struct nexthop *nexthop = NULL; int i, ret; s = client->ibuf; @@ -1364,7 +1364,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, static unsigned int ifindices[MULTIPATH_NUM]; int ret; static mpls_label_t labels[MULTIPATH_NUM]; - enum lsp_types_t label_type; + enum lsp_types_t label_type = ZEBRA_LSP_NONE; mpls_label_t label; struct nexthop *nexthop; @@ -1513,7 +1513,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length, static unsigned int ifindices[MULTIPATH_NUM]; int ret; static mpls_label_t labels[MULTIPATH_NUM]; - enum lsp_types_t label_type; + enum lsp_types_t label_type = ZEBRA_LSP_NONE; mpls_label_t label; struct nexthop *nexthop; From cd0442479369e53f3b8451163a8679a00f4c0d25 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 22 Aug 2017 14:40:24 -0400 Subject: [PATCH 50/79] eigrpd: Start split-horizon EIGRP was not handling split-horizon. This code starts down the path of properly considering it. There still exists situations where we are not properly handling it though. Signed-off-by: Donald Sharp --- eigrpd/eigrp_neighbor.c | 8 ++++++++ eigrpd/eigrp_neighbor.h | 2 ++ eigrpd/eigrp_update.c | 8 ++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/eigrpd/eigrp_neighbor.c b/eigrpd/eigrp_neighbor.c index d5fc6a2996..5d78dc375c 100644 --- a/eigrpd/eigrp_neighbor.c +++ b/eigrpd/eigrp_neighbor.c @@ -357,3 +357,11 @@ void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty) /* delete neighbor */ eigrp_nbr_delete(nbr); } + +int eigrp_nbr_split_horizon_check(struct eigrp_neighbor_entry *ne, struct eigrp_interface *ei) +{ + if (ne->distance == EIGRP_MAX_METRIC) + return 0; + + return (ne->ei == ei); +} diff --git a/eigrpd/eigrp_neighbor.h b/eigrpd/eigrp_neighbor.h index 006aa9ab75..6467fb24a9 100644 --- a/eigrpd/eigrp_neighbor.h +++ b/eigrpd/eigrp_neighbor.h @@ -53,4 +53,6 @@ extern struct eigrp_neighbor *eigrp_nbr_lookup_by_addr_process(struct eigrp *, struct in_addr); extern void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty); +extern int eigrp_nbr_split_horizon_check(struct eigrp_neighbor_entry *ne, + struct eigrp_interface *ei); #endif /* _ZEBRA_EIGRP_NEIGHBOR_H */ diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index d0c6520c4e..2934c6c652 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -610,8 +610,7 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr) for (ALL_LIST_ELEMENTS(nbr->ei->eigrp->topology_table, node, nnode, pe)) { for (ALL_LIST_ELEMENTS(pe->entries, node2, nnode2, te)) { - if ((te->ei == nbr->ei) - && (te->prefix->nt == EIGRP_TOPOLOGY_TYPE_REMOTE)) + if (eigrp_nbr_split_horizon_check(te, nbr->ei)) continue; if ((length + 0x001D) > (u_int16_t)nbr->ei->ifp->mtu) { @@ -701,10 +700,15 @@ void eigrp_update_send(struct eigrp_interface *ei) has_tlv = 0; for (ALL_LIST_ELEMENTS(ei->eigrp->topology_changes_internalIPV4, node, nnode, pe)) { + struct eigrp_neighbor_entry *ne; if (!(pe->req_action & EIGRP_FSM_NEED_UPDATE)) continue; + ne = listnode_head(pe->entries); + if (eigrp_nbr_split_horizon_check(ne, ei)) + continue; + if ((length + 0x001D) > (u_int16_t)ei->ifp->mtu) { if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { From c1c32a78034c63e149769c8b5e6799bec2040cf1 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 22 Aug 2017 14:42:43 -0400 Subject: [PATCH 51/79] eigrpd: Remove unnecessary check Signed-off-by: Donald Sharp --- eigrpd/eigrp_interface.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index 22b6fa394f..b316a22d88 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -315,9 +315,7 @@ int eigrp_if_up(struct eigrp_interface *ei) eigrp_neighbor_entry_add(pe, ne); for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei2)) { - if (ei2->nbrs->count != 0) { - eigrp_update_send(ei2); - } + eigrp_update_send(ei2); } pe->req_action &= ~EIGRP_FSM_NEED_UPDATE; From 695ff37babda771517c85a20c714d8215ece0c63 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 22 Aug 2017 14:53:14 -0400 Subject: [PATCH 52/79] eigrpd: Cleanup list accessors Signed-off-by: Donald Sharp --- eigrpd/eigrp_fsm.c | 92 +++++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 54 deletions(-) diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c index ba2d1f7e8d..178b2b0cd7 100644 --- a/eigrpd/eigrp_fsm.c +++ b/eigrpd/eigrp_fsm.c @@ -204,8 +204,7 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) switch (actual_state) { case EIGRP_FSM_STATE_PASSIVE: { struct eigrp_neighbor_entry *head = - (struct eigrp_neighbor_entry *) - entry->prefix->entries->head->data; + listnode_head(prefix->entries); if (head->reported_distance < prefix->fdistance) { return EIGRP_FSM_KEEP_STATE; @@ -226,8 +225,7 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) case EIGRP_FSM_STATE_ACTIVE_0: { if (msg->packet_type == EIGRP_OPC_REPLY) { struct eigrp_neighbor_entry *head = - (struct eigrp_neighbor_entry *) - entry->prefix->entries->head->data; + listnode_head(prefix->entries); listnode_delete(prefix->rij, entry->adv_router); if (prefix->rij->count) @@ -279,8 +277,7 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) case EIGRP_FSM_STATE_ACTIVE_2: { if (msg->packet_type == EIGRP_OPC_REPLY) { struct eigrp_neighbor_entry *head = - (struct eigrp_neighbor_entry *) - prefix->entries->head->data; + listnode_head(prefix->entries); listnode_delete(prefix->rij, entry->adv_router); if (prefix->rij->count) { @@ -350,16 +347,15 @@ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg) struct eigrp *eigrp = msg->eigrp; struct eigrp_prefix_entry *prefix = msg->prefix; struct list *successors = eigrp_topology_get_successor(prefix); + struct eigrp_neighbor_entry *ne; assert(successors); // If this is NULL we have shit the bed, fun huh? + ne = listnode_head(successors); prefix->state = EIGRP_FSM_STATE_ACTIVE_1; prefix->rdistance = prefix->distance = prefix->fdistance = - ((struct eigrp_neighbor_entry *)successors->head->data) - ->distance; - prefix->reported_metric = - ((struct eigrp_neighbor_entry *)successors->head->data) - ->total_metric; + ne->distance; + prefix->reported_metric = ne->total_metric; if (eigrp_nbr_count_get()) { prefix->req_action |= EIGRP_FSM_NEED_QUERY; @@ -379,16 +375,15 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg) struct eigrp *eigrp = msg->eigrp; struct eigrp_prefix_entry *prefix = msg->prefix; struct list *successors = eigrp_topology_get_successor(prefix); + struct eigrp_neighbor_entry *ne; assert(successors); // If this is NULL somebody poked us in the eye. + ne = listnode_head(successors); prefix->state = EIGRP_FSM_STATE_ACTIVE_3; prefix->rdistance = prefix->distance = prefix->fdistance = - ((struct eigrp_neighbor_entry *)successors->head->data) - ->distance; - prefix->reported_metric = - ((struct eigrp_neighbor_entry *)successors->head->data) - ->total_metric; + ne->distance; + prefix->reported_metric = ne->total_metric; if (eigrp_nbr_count_get()) { prefix->req_action |= EIGRP_FSM_NEED_QUERY; listnode_add(eigrp->topology_changes_internalIPV4, prefix); @@ -405,21 +400,15 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg) int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg) { struct eigrp_prefix_entry *prefix = msg->prefix; + struct eigrp_neighbor_entry *ne = listnode_head(prefix->entries); if (prefix->state == EIGRP_FSM_STATE_PASSIVE) { if (!eigrp_metrics_is_same(prefix->reported_metric, - ((struct eigrp_neighbor_entry *) - prefix->entries->head->data) - ->total_metric)) { + ne->total_metric)) { prefix->rdistance = prefix->fdistance = - prefix->distance = - ((struct eigrp_neighbor_entry *) - prefix->entries->head->data) - ->distance; + prefix->distance = ne->distance; prefix->reported_metric = - ((struct eigrp_neighbor_entry *) - prefix->entries->head->data) - ->total_metric; + ne->total_metric; if (msg->packet_type == EIGRP_OPC_QUERY) eigrp_send_reply(msg->adv_router, prefix); prefix->req_action |= EIGRP_FSM_NEED_UPDATE; @@ -441,22 +430,20 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg) { struct eigrp *eigrp = msg->eigrp; struct eigrp_prefix_entry *prefix = msg->prefix; + struct eigrp_neighbor_entry *ne = listnode_head(prefix->entries); + prefix->fdistance = prefix->distance = prefix->rdistance = - ((struct eigrp_neighbor_entry *)(prefix->entries->head->data)) - ->distance; - prefix->reported_metric = - ((struct eigrp_neighbor_entry *)(prefix->entries->head->data)) - ->total_metric; + ne->distance; + prefix->reported_metric = ne->total_metric; if (prefix->state == EIGRP_FSM_STATE_ACTIVE_3) { struct list *successors = eigrp_topology_get_successor(prefix); assert(successors); // It's like Napolean and Waterloo - eigrp_send_reply( - ((struct eigrp_neighbor_entry *)successors->head->data) - ->adv_router, - prefix); + ne = listnode_head(successors); + eigrp_send_reply(ne->adv_router, + prefix); list_delete(successors); } @@ -473,15 +460,15 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg) int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *msg) { struct list *successors = eigrp_topology_get_successor(msg->prefix); + struct eigrp_neighbor_entry *ne; assert(successors); // Trump and his big hands + ne = listnode_head(successors); msg->prefix->state = msg->prefix->state == EIGRP_FSM_STATE_ACTIVE_1 ? EIGRP_FSM_STATE_ACTIVE_0 : EIGRP_FSM_STATE_ACTIVE_2; - msg->prefix->distance = - ((struct eigrp_neighbor_entry *)successors->head->data) - ->distance; + msg->prefix->distance = ne->distance; if (!msg->prefix->rij->count) (*(NSM[msg->prefix->state][eigrp_get_fsm_event(msg)].func))( msg); @@ -495,13 +482,11 @@ int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg) { struct eigrp *eigrp = msg->eigrp; struct eigrp_prefix_entry *prefix = msg->prefix; + struct eigrp_neighbor_entry *ne = listnode_head(prefix->entries); + prefix->state = EIGRP_FSM_STATE_PASSIVE; - prefix->distance = prefix->rdistance = - ((struct eigrp_neighbor_entry *)(prefix->entries->head->data)) - ->distance; - prefix->reported_metric = - ((struct eigrp_neighbor_entry *)(prefix->entries->head->data)) - ->total_metric; + prefix->distance = prefix->rdistance = ne->distance; + prefix->reported_metric = ne->total_metric; prefix->fdistance = prefix->fdistance > prefix->distance ? prefix->distance : prefix->fdistance; @@ -510,11 +495,9 @@ int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg) assert(successors); // Having a spoon and all you need is a // knife - - eigrp_send_reply( - ((struct eigrp_neighbor_entry *)successors->head->data) - ->adv_router, - prefix); + ne = listnode_head(successors); + eigrp_send_reply(ne->adv_router, + prefix); list_delete(successors); } @@ -531,6 +514,7 @@ int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg) { struct eigrp *eigrp = msg->eigrp; struct eigrp_prefix_entry *prefix = msg->prefix; + struct eigrp_neighbor_entry *best_successor; struct list *successors = eigrp_topology_get_successor(prefix); assert(successors); // Routing without a stack @@ -538,8 +522,8 @@ int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg) prefix->state = prefix->state == EIGRP_FSM_STATE_ACTIVE_0 ? EIGRP_FSM_STATE_ACTIVE_1 : EIGRP_FSM_STATE_ACTIVE_3; - struct eigrp_neighbor_entry *best_successor = - ((struct eigrp_neighbor_entry *)(successors->head->data)); + + best_successor = listnode_head(successors); prefix->rdistance = prefix->distance = best_successor->distance; prefix->reported_metric = best_successor->total_metric; @@ -559,13 +543,13 @@ int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg) int eigrp_fsm_event_qact(struct eigrp_fsm_action_message *msg) { struct list *successors = eigrp_topology_get_successor(msg->prefix); + struct eigrp_neighbor_entry *ne; assert(successors); // Cats and no Dogs + ne = listnode_head(successors); msg->prefix->state = EIGRP_FSM_STATE_ACTIVE_2; - msg->prefix->distance = - ((struct eigrp_neighbor_entry *)(successors->head->data)) - ->distance; + msg->prefix->distance = ne->distance; list_delete(successors); return 1; From 92035b1db4a91d0fc95118a1e0ff73cfa6120b1b Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 22 Aug 2017 15:39:18 -0400 Subject: [PATCH 53/79] eigrpd: Fix memory leak in FSM The FSM was never freeing the msg. Since we do not have a special queue for it, just don't allocate the memory. In the future we can put this back. Signed-off-by: Donald Sharp --- eigrpd/eigrp_query.c | 23 ++++++-------- eigrpd/eigrp_reply.c | 22 ++++++------- eigrpd/eigrp_siaquery.c | 23 ++++++-------- eigrpd/eigrp_siareply.c | 23 ++++++-------- eigrpd/eigrp_topology.c | 23 ++++++-------- eigrpd/eigrp_update.c | 68 ++++++++++++++++++----------------------- 6 files changed, 80 insertions(+), 102 deletions(-) diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c index 00f9ee1267..c82c90589b 100644 --- a/eigrpd/eigrp_query.c +++ b/eigrpd/eigrp_query.c @@ -125,22 +125,19 @@ void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph, /* If the destination exists (it should, but one never * know)*/ if (dest != NULL) { - struct eigrp_fsm_action_message *msg; - msg = XCALLOC(MTYPE_EIGRP_FSM_MSG, - sizeof(struct - eigrp_fsm_action_message)); + struct eigrp_fsm_action_message msg; struct eigrp_neighbor_entry *entry = eigrp_prefix_entry_lookup(dest->entries, nbr); - msg->packet_type = EIGRP_OPC_QUERY; - msg->eigrp = eigrp; - msg->data_type = EIGRP_TLV_IPv4_INT; - msg->adv_router = nbr; - msg->data.ipv4_int_type = tlv; - msg->entry = entry; - msg->prefix = dest; - int event = eigrp_get_fsm_event(msg); - eigrp_fsm_event(msg, event); + msg.packet_type = EIGRP_OPC_QUERY; + msg.eigrp = eigrp; + msg.data_type = EIGRP_TLV_IPv4_INT; + msg.adv_router = nbr; + msg.data.ipv4_int_type = tlv; + msg.entry = entry; + msg.prefix = dest; + int event = eigrp_get_fsm_event(&msg); + eigrp_fsm_event(&msg, event); } eigrp_IPv4_InternalTLV_free(tlv); break; diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c index e59db80393..4e909283d6 100644 --- a/eigrpd/eigrp_reply.c +++ b/eigrpd/eigrp_reply.c @@ -196,9 +196,7 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph, */ assert(dest); - struct eigrp_fsm_action_message *msg; - msg = XCALLOC(MTYPE_EIGRP_FSM_MSG, - sizeof(struct eigrp_fsm_action_message)); + struct eigrp_fsm_action_message msg; struct eigrp_neighbor_entry *entry = eigrp_prefix_entry_lookup(dest->entries, nbr); @@ -237,15 +235,15 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph, * End of filtering */ - msg->packet_type = EIGRP_OPC_REPLY; - msg->eigrp = eigrp; - msg->data_type = EIGRP_TLV_IPv4_INT; - msg->adv_router = nbr; - msg->data.ipv4_int_type = tlv; - msg->entry = entry; - msg->prefix = dest; - int event = eigrp_get_fsm_event(msg); - eigrp_fsm_event(msg, event); + msg.packet_type = EIGRP_OPC_REPLY; + msg.eigrp = eigrp; + msg.data_type = EIGRP_TLV_IPv4_INT; + msg.adv_router = nbr; + msg.data.ipv4_int_type = tlv; + msg.entry = entry; + msg.prefix = dest; + int event = eigrp_get_fsm_event(&msg); + eigrp_fsm_event(&msg, event); eigrp_IPv4_InternalTLV_free(tlv); diff --git a/eigrpd/eigrp_siaquery.c b/eigrpd/eigrp_siaquery.c index 30f65ee87d..85b6ca9fe4 100644 --- a/eigrpd/eigrp_siaquery.c +++ b/eigrpd/eigrp_siaquery.c @@ -94,22 +94,19 @@ void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph, /* If the destination exists (it should, but one never * know)*/ if (dest != NULL) { - struct eigrp_fsm_action_message *msg; - msg = XCALLOC(MTYPE_EIGRP_FSM_MSG, - sizeof(struct - eigrp_fsm_action_message)); + struct eigrp_fsm_action_message msg; struct eigrp_neighbor_entry *entry = eigrp_prefix_entry_lookup(dest->entries, nbr); - msg->packet_type = EIGRP_OPC_SIAQUERY; - msg->eigrp = eigrp; - msg->data_type = EIGRP_TLV_IPv4_INT; - msg->adv_router = nbr; - msg->data.ipv4_int_type = tlv; - msg->entry = entry; - msg->prefix = dest; - int event = eigrp_get_fsm_event(msg); - eigrp_fsm_event(msg, event); + msg.packet_type = EIGRP_OPC_SIAQUERY; + msg.eigrp = eigrp; + msg.data_type = EIGRP_TLV_IPv4_INT; + msg.adv_router = nbr; + msg.data.ipv4_int_type = tlv; + msg.entry = entry; + msg.prefix = dest; + int event = eigrp_get_fsm_event(&msg); + eigrp_fsm_event(&msg, event); } eigrp_IPv4_InternalTLV_free(tlv); } diff --git a/eigrpd/eigrp_siareply.c b/eigrpd/eigrp_siareply.c index 3050b91032..c03a34322e 100644 --- a/eigrpd/eigrp_siareply.c +++ b/eigrpd/eigrp_siareply.c @@ -93,22 +93,19 @@ void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph, /* If the destination exists (it should, but one never * know)*/ if (dest != NULL) { - struct eigrp_fsm_action_message *msg; - msg = XCALLOC(MTYPE_EIGRP_FSM_MSG, - sizeof(struct - eigrp_fsm_action_message)); + struct eigrp_fsm_action_message msg; struct eigrp_neighbor_entry *entry = eigrp_prefix_entry_lookup(dest->entries, nbr); - msg->packet_type = EIGRP_OPC_SIAQUERY; - msg->eigrp = eigrp; - msg->data_type = EIGRP_TLV_IPv4_INT; - msg->adv_router = nbr; - msg->data.ipv4_int_type = tlv; - msg->entry = entry; - msg->prefix = dest; - int event = eigrp_get_fsm_event(msg); - eigrp_fsm_event(msg, event); + msg.packet_type = EIGRP_OPC_SIAQUERY; + msg.eigrp = eigrp; + msg.data_type = EIGRP_TLV_IPv4_INT; + msg.adv_router = nbr; + msg.data.ipv4_int_type = tlv; + msg.entry = entry; + msg.prefix = dest; + int event = eigrp_get_fsm_event(&msg); + eigrp_fsm_event(&msg, event); } eigrp_IPv4_InternalTLV_free(tlv); } diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 50d83430a8..f78a43739d 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -486,22 +486,19 @@ void eigrp_topology_neighbor_down(struct eigrp *eigrp, for (ALL_LIST_ELEMENTS(eigrp->topology_table, node1, node11, prefix)) { for (ALL_LIST_ELEMENTS(prefix->entries, node2, node22, entry)) { if (entry->adv_router == nbr) { - struct eigrp_fsm_action_message *msg; - msg = XCALLOC(MTYPE_EIGRP_FSM_MSG, - sizeof(struct - eigrp_fsm_action_message)); + struct eigrp_fsm_action_message msg; struct TLV_IPv4_Internal_type *tlv = eigrp_IPv4_InternalTLV_new(); tlv->metric.delay = EIGRP_MAX_METRIC; - msg->packet_type = EIGRP_OPC_UPDATE; - msg->eigrp = eigrp; - msg->data_type = EIGRP_TLV_IPv4_INT; - msg->adv_router = nbr; - msg->data.ipv4_int_type = tlv; - msg->entry = entry; - msg->prefix = prefix; - int event = eigrp_get_fsm_event(msg); - eigrp_fsm_event(msg, event); + msg.packet_type = EIGRP_OPC_UPDATE; + msg.eigrp = eigrp; + msg.data_type = EIGRP_TLV_IPv4_INT; + msg.adv_router = nbr; + msg.data.ipv4_int_type = tlv; + msg.entry = entry; + msg.prefix = prefix; + int event = eigrp_get_fsm_event(&msg); + eigrp_fsm_event(&msg, event); } } } diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index 2934c6c652..a3d6210e71 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -132,24 +132,22 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp, /* prepare message for FSM */ - struct eigrp_fsm_action_message *fsm_msg; - fsm_msg = XCALLOC(MTYPE_EIGRP_FSM_MSG, - sizeof(struct eigrp_fsm_action_message)); + struct eigrp_fsm_action_message fsm_msg; struct eigrp_neighbor_entry *entry = eigrp_prefix_entry_lookup(prefix->entries, nbr); - fsm_msg->packet_type = EIGRP_OPC_UPDATE; - fsm_msg->eigrp = eigrp; - fsm_msg->data_type = EIGRP_TLV_IPv4_INT; - fsm_msg->adv_router = nbr; - fsm_msg->data.ipv4_int_type = tlv_max; - fsm_msg->entry = entry; - fsm_msg->prefix = prefix; + fsm_msg.packet_type = EIGRP_OPC_UPDATE; + fsm_msg.eigrp = eigrp; + fsm_msg.data_type = EIGRP_TLV_IPv4_INT; + fsm_msg.adv_router = nbr; + fsm_msg.data.ipv4_int_type = tlv_max; + fsm_msg.entry = entry; + fsm_msg.prefix = prefix; /* send message to FSM */ - int event = eigrp_get_fsm_event(fsm_msg); - eigrp_fsm_event(fsm_msg, event); + int event = eigrp_get_fsm_event(&fsm_msg); + eigrp_fsm_event(&fsm_msg, event); /* free memory used by TLV */ eigrp_IPv4_InternalTLV_free(tlv_max); @@ -311,23 +309,20 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, remove_received_prefix_gr(nbr_prefixes, dest); - struct eigrp_fsm_action_message *msg; - msg = XCALLOC(MTYPE_EIGRP_FSM_MSG, - sizeof(struct - eigrp_fsm_action_message)); + struct eigrp_fsm_action_message msg; struct eigrp_neighbor_entry *entry = eigrp_prefix_entry_lookup(dest->entries, nbr); - msg->packet_type = EIGRP_OPC_UPDATE; - msg->eigrp = eigrp; - msg->data_type = EIGRP_TLV_IPv4_INT; - msg->adv_router = nbr; - msg->data.ipv4_int_type = tlv; - msg->entry = entry; - msg->prefix = dest; - int event = eigrp_get_fsm_event(msg); - eigrp_fsm_event(msg, event); + msg.packet_type = EIGRP_OPC_UPDATE; + msg.eigrp = eigrp; + msg.data_type = EIGRP_TLV_IPv4_INT; + msg.adv_router = nbr; + msg.data.ipv4_int_type = tlv; + msg.entry = entry; + msg.prefix = dest; + int event = eigrp_get_fsm_event(&msg); + eigrp_fsm_event(&msg, event); } else { /*Here comes topology information save*/ pe = eigrp_prefix_entry_new(); @@ -978,25 +973,22 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) pe->destination_ipv4->prefixlen; /* prepare message for FSM */ - struct eigrp_fsm_action_message *fsm_msg; - fsm_msg = XCALLOC( - MTYPE_EIGRP_FSM_MSG, - sizeof(struct eigrp_fsm_action_message)); + struct eigrp_fsm_action_message fsm_msg; struct eigrp_neighbor_entry *entry = eigrp_prefix_entry_lookup(pe->entries, nbr); - fsm_msg->packet_type = EIGRP_OPC_UPDATE; - fsm_msg->eigrp = e; - fsm_msg->data_type = EIGRP_TLV_IPv4_INT; - fsm_msg->adv_router = nbr; - fsm_msg->data.ipv4_int_type = tlv_max; - fsm_msg->entry = entry; - fsm_msg->prefix = pe; + fsm_msg.packet_type = EIGRP_OPC_UPDATE; + fsm_msg.eigrp = e; + fsm_msg.data_type = EIGRP_TLV_IPv4_INT; + fsm_msg.adv_router = nbr; + fsm_msg.data.ipv4_int_type = tlv_max; + fsm_msg.entry = entry; + fsm_msg.prefix = pe; /* send message to FSM */ - int event = eigrp_get_fsm_event(fsm_msg); - eigrp_fsm_event(fsm_msg, event); + int event = eigrp_get_fsm_event(&fsm_msg); + eigrp_fsm_event(&fsm_msg, event); /* free memory used by TLV */ eigrp_IPv4_InternalTLV_free(tlv_max); From 6118272f14f91ad4b315c6cd1ad13f4aa8e77a2d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 22 Aug 2017 15:43:30 -0400 Subject: [PATCH 54/79] eigrpd: Refactor FSM calling Signed-off-by: Donald Sharp --- eigrpd/eigrp_fsm.c | 5 +++-- eigrpd/eigrp_fsm.h | 3 +-- eigrpd/eigrp_query.c | 3 +-- eigrpd/eigrp_reply.c | 3 +-- eigrpd/eigrp_siaquery.c | 3 +-- eigrpd/eigrp_siareply.c | 3 +-- eigrpd/eigrp_topology.c | 3 +-- eigrpd/eigrp_update.c | 9 +++------ 8 files changed, 12 insertions(+), 20 deletions(-) diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c index 178b2b0cd7..47cd112cf5 100644 --- a/eigrpd/eigrp_fsm.c +++ b/eigrpd/eigrp_fsm.c @@ -178,7 +178,7 @@ struct { * Return number of occurred event (arrow in diagram). * */ -int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) +static int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) { // Loading base information from message // struct eigrp *eigrp = msg->eigrp; @@ -328,8 +328,9 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) * Function made to execute in separate thread. * Load argument from thread and execute proper NSM function */ -int eigrp_fsm_event(struct eigrp_fsm_action_message *msg, int event) +int eigrp_fsm_event(struct eigrp_fsm_action_message *msg) { + int event = eigrp_get_fsm_event(msg); zlog_info("EIGRP AS: %d State: %d Event: %d Network: %s", msg->eigrp->AS, msg->prefix->state, event, eigrp_topology_ip_string(msg->prefix)); diff --git a/eigrpd/eigrp_fsm.h b/eigrpd/eigrp_fsm.h index 97a1f49281..8fad9d1f51 100644 --- a/eigrpd/eigrp_fsm.h +++ b/eigrpd/eigrp_fsm.h @@ -28,8 +28,7 @@ #ifndef _ZEBRA_EIGRP_FSM_H #define _ZEBRA_EIGRP_FSM_H -extern int eigrp_get_fsm_event(struct eigrp_fsm_action_message *); -extern int eigrp_fsm_event(struct eigrp_fsm_action_message *, int); +extern int eigrp_fsm_event(struct eigrp_fsm_action_message *msg); #endif /* _ZEBRA_EIGRP_DUAL_H */ diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c index c82c90589b..b9351ed896 100644 --- a/eigrpd/eigrp_query.c +++ b/eigrpd/eigrp_query.c @@ -136,8 +136,7 @@ void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph, msg.data.ipv4_int_type = tlv; msg.entry = entry; msg.prefix = dest; - int event = eigrp_get_fsm_event(&msg); - eigrp_fsm_event(&msg, event); + eigrp_fsm_event(&msg); } eigrp_IPv4_InternalTLV_free(tlv); break; diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c index 4e909283d6..7015413f56 100644 --- a/eigrpd/eigrp_reply.c +++ b/eigrpd/eigrp_reply.c @@ -242,8 +242,7 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph, msg.data.ipv4_int_type = tlv; msg.entry = entry; msg.prefix = dest; - int event = eigrp_get_fsm_event(&msg); - eigrp_fsm_event(&msg, event); + eigrp_fsm_event(&msg); eigrp_IPv4_InternalTLV_free(tlv); diff --git a/eigrpd/eigrp_siaquery.c b/eigrpd/eigrp_siaquery.c index 85b6ca9fe4..9447efb2e2 100644 --- a/eigrpd/eigrp_siaquery.c +++ b/eigrpd/eigrp_siaquery.c @@ -105,8 +105,7 @@ void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph, msg.data.ipv4_int_type = tlv; msg.entry = entry; msg.prefix = dest; - int event = eigrp_get_fsm_event(&msg); - eigrp_fsm_event(&msg, event); + eigrp_fsm_event(&msg); } eigrp_IPv4_InternalTLV_free(tlv); } diff --git a/eigrpd/eigrp_siareply.c b/eigrpd/eigrp_siareply.c index c03a34322e..2cf7520a96 100644 --- a/eigrpd/eigrp_siareply.c +++ b/eigrpd/eigrp_siareply.c @@ -104,8 +104,7 @@ void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph, msg.data.ipv4_int_type = tlv; msg.entry = entry; msg.prefix = dest; - int event = eigrp_get_fsm_event(&msg); - eigrp_fsm_event(&msg, event); + eigrp_fsm_event(&msg); } eigrp_IPv4_InternalTLV_free(tlv); } diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index f78a43739d..d4d55393a8 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -497,8 +497,7 @@ void eigrp_topology_neighbor_down(struct eigrp *eigrp, msg.data.ipv4_int_type = tlv; msg.entry = entry; msg.prefix = prefix; - int event = eigrp_get_fsm_event(&msg); - eigrp_fsm_event(&msg, event); + eigrp_fsm_event(&msg); } } } diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index a3d6210e71..89b8ecd928 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -146,8 +146,7 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp, fsm_msg.prefix = prefix; /* send message to FSM */ - int event = eigrp_get_fsm_event(&fsm_msg); - eigrp_fsm_event(&fsm_msg, event); + eigrp_fsm_event(&fsm_msg); /* free memory used by TLV */ eigrp_IPv4_InternalTLV_free(tlv_max); @@ -321,8 +320,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, msg.data.ipv4_int_type = tlv; msg.entry = entry; msg.prefix = dest; - int event = eigrp_get_fsm_event(&msg); - eigrp_fsm_event(&msg, event); + eigrp_fsm_event(&msg); } else { /*Here comes topology information save*/ pe = eigrp_prefix_entry_new(); @@ -987,8 +985,7 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) fsm_msg.prefix = pe; /* send message to FSM */ - int event = eigrp_get_fsm_event(&fsm_msg); - eigrp_fsm_event(&fsm_msg, event); + eigrp_fsm_event(&fsm_msg); /* free memory used by TLV */ eigrp_IPv4_InternalTLV_free(tlv_max); From 7cfa4322558c56b5a0801b17e60598c5a49779dd Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 22 Aug 2017 16:19:23 -0400 Subject: [PATCH 55/79] eigrpd: make fsm msg data_type an enum We need to eventually be able to handle multiple data types to figure out if the distance is better worse. Signed-off-by: Donald Sharp --- eigrpd/eigrp_query.c | 2 +- eigrpd/eigrp_reply.c | 2 +- eigrpd/eigrp_siaquery.c | 2 +- eigrpd/eigrp_siareply.c | 2 +- eigrpd/eigrp_structs.h | 7 ++++- eigrpd/eigrp_topology.c | 57 +++++++++++++++++++++++++---------------- eigrpd/eigrp_update.c | 6 ++--- 7 files changed, 48 insertions(+), 30 deletions(-) diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c index b9351ed896..92aa7f9855 100644 --- a/eigrpd/eigrp_query.c +++ b/eigrpd/eigrp_query.c @@ -131,7 +131,7 @@ void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph, nbr); msg.packet_type = EIGRP_OPC_QUERY; msg.eigrp = eigrp; - msg.data_type = EIGRP_TLV_IPv4_INT; + msg.data_type = EIGRP_INT; msg.adv_router = nbr; msg.data.ipv4_int_type = tlv; msg.entry = entry; diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c index 7015413f56..92cea77305 100644 --- a/eigrpd/eigrp_reply.c +++ b/eigrpd/eigrp_reply.c @@ -237,7 +237,7 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph, msg.packet_type = EIGRP_OPC_REPLY; msg.eigrp = eigrp; - msg.data_type = EIGRP_TLV_IPv4_INT; + msg.data_type = EIGRP_INT; msg.adv_router = nbr; msg.data.ipv4_int_type = tlv; msg.entry = entry; diff --git a/eigrpd/eigrp_siaquery.c b/eigrpd/eigrp_siaquery.c index 9447efb2e2..60decc5bef 100644 --- a/eigrpd/eigrp_siaquery.c +++ b/eigrpd/eigrp_siaquery.c @@ -100,7 +100,7 @@ void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph, nbr); msg.packet_type = EIGRP_OPC_SIAQUERY; msg.eigrp = eigrp; - msg.data_type = EIGRP_TLV_IPv4_INT; + msg.data_type = EIGRP_INT; msg.adv_router = nbr; msg.data.ipv4_int_type = tlv; msg.entry = entry; diff --git a/eigrpd/eigrp_siareply.c b/eigrpd/eigrp_siareply.c index 2cf7520a96..e960940200 100644 --- a/eigrpd/eigrp_siareply.c +++ b/eigrpd/eigrp_siareply.c @@ -99,7 +99,7 @@ void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph, nbr); msg.packet_type = EIGRP_OPC_SIAQUERY; msg.eigrp = eigrp; - msg.data_type = EIGRP_TLV_IPv4_INT; + msg.data_type = EIGRP_INT; msg.adv_router = nbr; msg.data.ipv4_int_type = tlv; msg.entry = entry; diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h index 0c15436d4f..c81dfebb46 100644 --- a/eigrpd/eigrp_structs.h +++ b/eigrpd/eigrp_structs.h @@ -499,6 +499,11 @@ struct eigrp_neighbor_entry { }; //--------------------------------------------------------------------------------------------------------------------------------------------- +typedef enum { + EIGRP_CONNECTED, + EIGRP_INT, + EIGRP_EXT, +} msg_data_t; /* EIGRP Finite State Machine */ @@ -508,7 +513,7 @@ struct eigrp_fsm_action_message { struct eigrp_neighbor *adv_router; // advertising neighbor struct eigrp_neighbor_entry *entry; struct eigrp_prefix_entry *prefix; - int data_type; // internal or external tlv type + msg_data_t data_type; // internal or external tlv type union { struct TLV_IPv4_External_type *ipv4_ext_data; struct TLV_IPv4_Internal_type *ipv4_int_type; diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index d4d55393a8..d1c09d6612 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -384,32 +384,45 @@ enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_messag struct TLV_IPv4_External_type *ext_data = NULL; struct TLV_IPv4_Internal_type *int_data = NULL; - if (msg->data_type == EIGRP_TLV_IPv4_INT) { - u_int32_t new_reported_distance; + switch(msg->data_type) { + case EIGRP_CONNECTED: + break; + case EIGRP_INT: + { + u_int32_t new_reported_distance; - int_data = msg->data.ipv4_int_type; - if (eigrp_metrics_is_same(int_data->metric, - entry->reported_metric)) { - return change; // No change - } + int_data = msg->data.ipv4_int_type; + if (eigrp_metrics_is_same(int_data->metric, + entry->reported_metric)) { + return change; // No change + } - new_reported_distance = eigrp_calculate_metrics(eigrp, - int_data->metric); + new_reported_distance = eigrp_calculate_metrics(eigrp, + int_data->metric); - if (entry->reported_distance < new_reported_distance) - change = METRIC_INCREASE; - else - change = METRIC_DECREASE; + if (entry->reported_distance < new_reported_distance) + change = METRIC_INCREASE; + else + change = METRIC_DECREASE; - entry->reported_metric = int_data->metric; - entry->reported_distance = new_reported_distance; + entry->reported_metric = int_data->metric; + entry->reported_distance = new_reported_distance; eigrp_calculate_metrics(eigrp, int_data->metric); - entry->distance = eigrp_calculate_total_metrics(eigrp, entry); - } else { - ext_data = msg->data.ipv4_ext_data; - if (eigrp_metrics_is_same(ext_data->metric, - entry->reported_metric)) - return change; + entry->distance = eigrp_calculate_total_metrics(eigrp, entry); + break; + } + case EIGRP_EXT: + { + ext_data = msg->data.ipv4_ext_data; + if (eigrp_metrics_is_same(ext_data->metric, + entry->reported_metric)) + return change; + + break; + } + default: + zlog_err("%s: Please implement handler", __PRETTY_FUNCTION__); + break; } /* * Move to correct position in list according to new distance @@ -492,7 +505,7 @@ void eigrp_topology_neighbor_down(struct eigrp *eigrp, tlv->metric.delay = EIGRP_MAX_METRIC; msg.packet_type = EIGRP_OPC_UPDATE; msg.eigrp = eigrp; - msg.data_type = EIGRP_TLV_IPv4_INT; + msg.data_type = EIGRP_INT; msg.adv_router = nbr; msg.data.ipv4_int_type = tlv; msg.entry = entry; diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index 89b8ecd928..ba54fa5727 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -139,7 +139,7 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp, fsm_msg.packet_type = EIGRP_OPC_UPDATE; fsm_msg.eigrp = eigrp; - fsm_msg.data_type = EIGRP_TLV_IPv4_INT; + fsm_msg.data_type = EIGRP_INT; fsm_msg.adv_router = nbr; fsm_msg.data.ipv4_int_type = tlv_max; fsm_msg.entry = entry; @@ -315,7 +315,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, msg.packet_type = EIGRP_OPC_UPDATE; msg.eigrp = eigrp; - msg.data_type = EIGRP_TLV_IPv4_INT; + msg.data_type = EIGRP_INT; msg.adv_router = nbr; msg.data.ipv4_int_type = tlv; msg.entry = entry; @@ -978,7 +978,7 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) fsm_msg.packet_type = EIGRP_OPC_UPDATE; fsm_msg.eigrp = e; - fsm_msg.data_type = EIGRP_TLV_IPv4_INT; + fsm_msg.data_type = EIGRP_INT; fsm_msg.adv_router = nbr; fsm_msg.data.ipv4_int_type = tlv_max; fsm_msg.entry = entry; From 3aea4e507bc6c129e1bdcfbaaefca6a829ee1825 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 22 Aug 2017 16:24:23 -0400 Subject: [PATCH 56/79] eigrpd: Improve external route distance comparison If the new nexthop is external while the previous best was Internal or Connected, it should always loose. Signed-off-by: Donald Sharp --- eigrpd/eigrp_topology.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index d1c09d6612..9f62e5e899 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -414,9 +414,13 @@ enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_messag case EIGRP_EXT: { ext_data = msg->data.ipv4_ext_data; - if (eigrp_metrics_is_same(ext_data->metric, - entry->reported_metric)) - return change; + + if (prefix->nt == EIGRP_TOPOLOGY_TYPE_REMOTE_EXTERNAL) { + if (eigrp_metrics_is_same(ext_data->metric, + entry->reported_metric)) + return change; + } else + change = METRIC_INCREASE; break; } From db6ec9ff6e8e1641c586ce32b4422b6e0c896500 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 22 Aug 2017 19:19:10 -0400 Subject: [PATCH 57/79] eigrpd: Remove union from FSM msg Remove the union of passing the TLV and just pass the metric in. Signed-off-by: Donald Sharp --- eigrpd/eigrp_query.c | 2 +- eigrpd/eigrp_reply.c | 2 +- eigrpd/eigrp_siaquery.c | 2 +- eigrpd/eigrp_siareply.c | 2 +- eigrpd/eigrp_structs.h | 5 +--- eigrpd/eigrp_topology.c | 65 +++++++++++++++++++---------------------- eigrpd/eigrp_update.c | 6 ++-- 7 files changed, 38 insertions(+), 46 deletions(-) diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c index 92aa7f9855..4757097315 100644 --- a/eigrpd/eigrp_query.c +++ b/eigrpd/eigrp_query.c @@ -133,7 +133,7 @@ void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph, msg.eigrp = eigrp; msg.data_type = EIGRP_INT; msg.adv_router = nbr; - msg.data.ipv4_int_type = tlv; + msg.metrics = tlv->metric; msg.entry = entry; msg.prefix = dest; eigrp_fsm_event(&msg); diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c index 92cea77305..304a1a5242 100644 --- a/eigrpd/eigrp_reply.c +++ b/eigrpd/eigrp_reply.c @@ -239,7 +239,7 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph, msg.eigrp = eigrp; msg.data_type = EIGRP_INT; msg.adv_router = nbr; - msg.data.ipv4_int_type = tlv; + msg.metrics = tlv->metric; msg.entry = entry; msg.prefix = dest; eigrp_fsm_event(&msg); diff --git a/eigrpd/eigrp_siaquery.c b/eigrpd/eigrp_siaquery.c index 60decc5bef..cd04f88595 100644 --- a/eigrpd/eigrp_siaquery.c +++ b/eigrpd/eigrp_siaquery.c @@ -102,7 +102,7 @@ void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph, msg.eigrp = eigrp; msg.data_type = EIGRP_INT; msg.adv_router = nbr; - msg.data.ipv4_int_type = tlv; + msg.metrics = tlv->metric; msg.entry = entry; msg.prefix = dest; eigrp_fsm_event(&msg); diff --git a/eigrpd/eigrp_siareply.c b/eigrpd/eigrp_siareply.c index e960940200..5e83549488 100644 --- a/eigrpd/eigrp_siareply.c +++ b/eigrpd/eigrp_siareply.c @@ -101,7 +101,7 @@ void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph, msg.eigrp = eigrp; msg.data_type = EIGRP_INT; msg.adv_router = nbr; - msg.data.ipv4_int_type = tlv; + msg.metrics = tlv->metric; msg.entry = entry; msg.prefix = dest; eigrp_fsm_event(&msg); diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h index c81dfebb46..6bb0c5cc2b 100644 --- a/eigrpd/eigrp_structs.h +++ b/eigrpd/eigrp_structs.h @@ -514,10 +514,7 @@ struct eigrp_fsm_action_message { struct eigrp_neighbor_entry *entry; struct eigrp_prefix_entry *prefix; msg_data_t data_type; // internal or external tlv type - union { - struct TLV_IPv4_External_type *ipv4_ext_data; - struct TLV_IPv4_Internal_type *ipv4_int_type; - } data; + struct eigrp_metrics metrics; }; #endif /* _ZEBRA_EIGRP_STRUCTURES_H_ */ diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 9f62e5e899..4555ced477 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -380,50 +380,45 @@ enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_messag struct eigrp_prefix_entry *prefix = msg->prefix; struct eigrp_neighbor_entry *entry = msg->entry; enum metric_change change = METRIC_SAME; + u_int32_t new_reported_distance; + assert(entry); - struct TLV_IPv4_External_type *ext_data = NULL; - struct TLV_IPv4_Internal_type *int_data = NULL; switch(msg->data_type) { case EIGRP_CONNECTED: + if (prefix->nt == EIGRP_TOPOLOGY_TYPE_CONNECTED) + return change; + + change = METRIC_DECREASE; break; case EIGRP_INT: - { - u_int32_t new_reported_distance; - - int_data = msg->data.ipv4_int_type; - if (eigrp_metrics_is_same(int_data->metric, - entry->reported_metric)) { - return change; // No change - } - - new_reported_distance = eigrp_calculate_metrics(eigrp, - int_data->metric); - - if (entry->reported_distance < new_reported_distance) - change = METRIC_INCREASE; - else - change = METRIC_DECREASE; - - entry->reported_metric = int_data->metric; - entry->reported_distance = new_reported_distance; - eigrp_calculate_metrics(eigrp, int_data->metric); - entry->distance = eigrp_calculate_total_metrics(eigrp, entry); - break; + if (eigrp_metrics_is_same(msg->metrics, + entry->reported_metric)) { + return change; // No change } + + new_reported_distance = eigrp_calculate_metrics(eigrp, + msg->metrics); + + if (entry->reported_distance < new_reported_distance) + change = METRIC_INCREASE; + else + change = METRIC_DECREASE; + + entry->reported_metric = msg->metrics; + entry->reported_distance = new_reported_distance; + eigrp_calculate_metrics(eigrp, msg->metrics); + entry->distance = eigrp_calculate_total_metrics(eigrp, entry); + break; case EIGRP_EXT: - { - ext_data = msg->data.ipv4_ext_data; - - if (prefix->nt == EIGRP_TOPOLOGY_TYPE_REMOTE_EXTERNAL) { - if (eigrp_metrics_is_same(ext_data->metric, - entry->reported_metric)) - return change; - } else - change = METRIC_INCREASE; + if (prefix->nt == EIGRP_TOPOLOGY_TYPE_REMOTE_EXTERNAL) { + if (eigrp_metrics_is_same(msg->metrics, + entry->reported_metric)) + return change; + } else + change = METRIC_INCREASE; break; - } default: zlog_err("%s: Please implement handler", __PRETTY_FUNCTION__); break; @@ -511,7 +506,7 @@ void eigrp_topology_neighbor_down(struct eigrp *eigrp, msg.eigrp = eigrp; msg.data_type = EIGRP_INT; msg.adv_router = nbr; - msg.data.ipv4_int_type = tlv; + msg.metrics = tlv->metric; msg.entry = entry; msg.prefix = prefix; eigrp_fsm_event(&msg); diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index ba54fa5727..98bfc95e4d 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -141,7 +141,7 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp, fsm_msg.eigrp = eigrp; fsm_msg.data_type = EIGRP_INT; fsm_msg.adv_router = nbr; - fsm_msg.data.ipv4_int_type = tlv_max; + fsm_msg.metrics = tlv_max->metric; fsm_msg.entry = entry; fsm_msg.prefix = prefix; @@ -317,7 +317,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, msg.eigrp = eigrp; msg.data_type = EIGRP_INT; msg.adv_router = nbr; - msg.data.ipv4_int_type = tlv; + msg.metrics = tlv->metric; msg.entry = entry; msg.prefix = dest; eigrp_fsm_event(&msg); @@ -980,7 +980,7 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) fsm_msg.eigrp = e; fsm_msg.data_type = EIGRP_INT; fsm_msg.adv_router = nbr; - fsm_msg.data.ipv4_int_type = tlv_max; + fsm_msg.metrics = tlv_max->metric; fsm_msg.entry = entry; fsm_msg.prefix = pe; From 5ca6df7822a8cddd1a10b27760f6b6e274aced5d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 22 Aug 2017 19:48:23 -0400 Subject: [PATCH 58/79] eigrpd: No need to create TLV type There is no need to create a TLV type to pass in for the FSM message. Signed-off-by: Donald Sharp --- eigrpd/eigrp_packet.c | 20 ++++++++++---------- eigrpd/eigrp_packet.h | 1 - eigrpd/eigrp_topology.c | 27 +++++++++++++-------------- eigrpd/eigrp_update.c | 38 ++++++-------------------------------- 4 files changed, 29 insertions(+), 57 deletions(-) diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c index 72aaef1b37..d4e8264f20 100644 --- a/eigrpd/eigrp_packet.c +++ b/eigrpd/eigrp_packet.c @@ -1101,6 +1101,16 @@ struct eigrp_packet *eigrp_packet_duplicate(struct eigrp_packet *old, return new; } +static struct TLV_IPv4_Internal_type *eigrp_IPv4_InternalTLV_new() +{ + struct TLV_IPv4_Internal_type *new; + + new = XCALLOC(MTYPE_EIGRP_IPV4_INT_TLV, + sizeof(struct TLV_IPv4_Internal_type)); + + return new; +} + struct TLV_IPv4_Internal_type *eigrp_read_ipv4_tlv(struct stream *s) { struct TLV_IPv4_Internal_type *tlv; @@ -1332,16 +1342,6 @@ void eigrp_authTLV_SHA256_free(struct TLV_SHA256_Authentication_Type *authTLV) XFREE(MTYPE_EIGRP_AUTH_SHA256_TLV, authTLV); } -struct TLV_IPv4_Internal_type *eigrp_IPv4_InternalTLV_new() -{ - struct TLV_IPv4_Internal_type *new; - - new = XCALLOC(MTYPE_EIGRP_IPV4_INT_TLV, - sizeof(struct TLV_IPv4_Internal_type)); - - return new; -} - void eigrp_IPv4_InternalTLV_free( struct TLV_IPv4_Internal_type *IPv4_InternalTLV) { diff --git a/eigrpd/eigrp_packet.h b/eigrpd/eigrp_packet.h index e72048ecc3..e52fd268fa 100644 --- a/eigrpd/eigrp_packet.h +++ b/eigrpd/eigrp_packet.h @@ -152,7 +152,6 @@ extern int eigrp_check_sha256_digest(struct stream *, struct eigrp_neighbor *, u_char); -extern struct TLV_IPv4_Internal_type *eigrp_IPv4_InternalTLV_new(void); extern void eigrp_IPv4_InternalTLV_free(struct TLV_IPv4_Internal_type *); extern struct TLV_Sequence_Type *eigrp_SequenceTLV_new(void); diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 4555ced477..3ba8c5b5fd 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -497,20 +497,19 @@ void eigrp_topology_neighbor_down(struct eigrp *eigrp, for (ALL_LIST_ELEMENTS(eigrp->topology_table, node1, node11, prefix)) { for (ALL_LIST_ELEMENTS(prefix->entries, node2, node22, entry)) { - if (entry->adv_router == nbr) { - struct eigrp_fsm_action_message msg; - struct TLV_IPv4_Internal_type *tlv = - eigrp_IPv4_InternalTLV_new(); - tlv->metric.delay = EIGRP_MAX_METRIC; - msg.packet_type = EIGRP_OPC_UPDATE; - msg.eigrp = eigrp; - msg.data_type = EIGRP_INT; - msg.adv_router = nbr; - msg.metrics = tlv->metric; - msg.entry = entry; - msg.prefix = prefix; - eigrp_fsm_event(&msg); - } + struct eigrp_fsm_action_message msg; + + if (entry->adv_router != nbr) + continue; + + msg.metrics.delay = EIGRP_MAX_METRIC; + msg.packet_type = EIGRP_OPC_UPDATE; + msg.eigrp = eigrp; + msg.data_type = EIGRP_INT; + msg.adv_router = nbr; + msg.entry = entry; + msg.prefix = prefix; + eigrp_fsm_event(&msg); } } diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index 98bfc95e4d..e4b7883741 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -112,7 +112,7 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp, { struct listnode *node1; struct eigrp_prefix_entry *prefix; - struct TLV_IPv4_Internal_type *tlv_max; + struct eigrp_fsm_action_message fsm_msg; /* iterate over all prefixes which weren't advertised by neighbor */ for (ALL_LIST_ELEMENTS_RO(nbr_prefixes, node1, prefix)) { @@ -120,19 +120,9 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp, inet_ntoa(prefix->destination_ipv4->prefix), prefix->destination_ipv4->prefixlen); - /* create internal IPv4 TLV with infinite delay */ - tlv_max = eigrp_IPv4_InternalTLV_new(); - tlv_max->type = EIGRP_TLV_IPv4_INT; - tlv_max->length = 28U; - tlv_max->metric = prefix->reported_metric; + fsm_msg.metrics = prefix->reported_metric; /* set delay to MAX */ - tlv_max->metric.delay = EIGRP_MAX_METRIC; - tlv_max->destination = prefix->destination_ipv4->prefix; - tlv_max->prefix_length = prefix->destination_ipv4->prefixlen; - - - /* prepare message for FSM */ - struct eigrp_fsm_action_message fsm_msg; + fsm_msg.metrics.delay = EIGRP_MAX_METRIC; struct eigrp_neighbor_entry *entry = eigrp_prefix_entry_lookup(prefix->entries, nbr); @@ -141,15 +131,11 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp, fsm_msg.eigrp = eigrp; fsm_msg.data_type = EIGRP_INT; fsm_msg.adv_router = nbr; - fsm_msg.metrics = tlv_max->metric; fsm_msg.entry = entry; fsm_msg.prefix = prefix; /* send message to FSM */ eigrp_fsm_event(&fsm_msg); - - /* free memory used by TLV */ - eigrp_IPv4_InternalTLV_free(tlv_max); } } @@ -845,7 +831,6 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) struct list *prefixes; u_int32_t flags; unsigned int send_prefixes; - struct TLV_IPv4_Internal_type *tlv_max; /* get prefixes to send to neighbor */ prefixes = nbr->nbr_gr_prefixes_send; @@ -960,16 +945,6 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) zlog_info("Filtered prefix %s will be removed.", inet_ntoa(dest_addr->prefix)); - tlv_max = eigrp_IPv4_InternalTLV_new(); - tlv_max->type = EIGRP_TLV_IPv4_INT; - tlv_max->length = 28U; - tlv_max->metric = pe->reported_metric; - /* set delay to MAX */ - tlv_max->metric.delay = EIGRP_MAX_METRIC; - tlv_max->destination = pe->destination_ipv4->prefix; - tlv_max->prefix_length = - pe->destination_ipv4->prefixlen; - /* prepare message for FSM */ struct eigrp_fsm_action_message fsm_msg; @@ -980,15 +955,14 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) fsm_msg.eigrp = e; fsm_msg.data_type = EIGRP_INT; fsm_msg.adv_router = nbr; - fsm_msg.metrics = tlv_max->metric; + fsm_msg.metrics = pe->reported_metric; + /* Set delay to MAX */ + fsm_msg.metrics.delay = EIGRP_MAX_METRIC; fsm_msg.entry = entry; fsm_msg.prefix = pe; /* send message to FSM */ eigrp_fsm_event(&fsm_msg); - - /* free memory used by TLV */ - eigrp_IPv4_InternalTLV_free(tlv_max); } /* * End of filtering From 348addb4e7e44f614f84d75d41a0af1a8ad2e6c1 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 23 Aug 2017 13:26:50 -0400 Subject: [PATCH 59/79] eigrpd: Use FSM for interface pe already known. There exists a case where a switch already has a eigrp_prefix_entry for a interface that is coming up. In this situation, we need to use the FSM to let the connected route take precedence instead of blindly just updating the world about it. Signed-off-by: Donald Sharp --- eigrpd/eigrp_interface.c | 49 +++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index b316a22d88..207001778d 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -53,6 +53,7 @@ #include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_memory.h" +#include "eigrpd/eigrp_fsm.h" static void eigrp_delete_from_if(struct interface *, struct eigrp_interface *); @@ -279,6 +280,15 @@ int eigrp_if_up(struct eigrp_interface *ei) /*Add connected entry to topology table*/ + ne = eigrp_neighbor_entry_new(); + ne->ei = ei; + ne->reported_metric = metric; + ne->total_metric = metric; + ne->distance = eigrp_calculate_metrics(eigrp, metric); + ne->reported_distance = 0; + ne->adv_router = eigrp->neighbor_self; + ne->flags = EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG; + struct prefix_ipv4 dest_addr; dest_addr.family = AF_INET; @@ -297,29 +307,36 @@ int eigrp_if_up(struct eigrp_interface *ei) pe->af = AF_INET; pe->nt = EIGRP_TOPOLOGY_TYPE_CONNECTED; + ne->prefix = pe; pe->state = EIGRP_FSM_STATE_PASSIVE; pe->fdistance = eigrp_calculate_metrics(eigrp, metric); pe->req_action |= EIGRP_FSM_NEED_UPDATE; eigrp_prefix_entry_add(eigrp->topology_table, pe); listnode_add(eigrp->topology_changes_internalIPV4, pe); - } - ne = eigrp_neighbor_entry_new(); - ne->ei = ei; - ne->reported_metric = metric; - ne->total_metric = metric; - ne->distance = eigrp_calculate_metrics(eigrp, metric); - ne->reported_distance = 0; - ne->prefix = pe; - ne->adv_router = eigrp->neighbor_self; - ne->flags = EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG; - eigrp_neighbor_entry_add(pe, ne); - for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei2)) { - eigrp_update_send(ei2); - } + eigrp_neighbor_entry_add(pe, ne); - pe->req_action &= ~EIGRP_FSM_NEED_UPDATE; - listnode_delete(eigrp->topology_changes_internalIPV4, pe); + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei2)) { + eigrp_update_send(ei2); + } + + pe->req_action &= ~EIGRP_FSM_NEED_UPDATE; + listnode_delete(eigrp->topology_changes_internalIPV4, pe); + } else { + struct eigrp_fsm_action_message msg; + + ne->prefix = pe; + eigrp_neighbor_entry_add(pe, ne); + + msg.packet_type = EIGRP_OPC_UPDATE; + msg.eigrp = eigrp; + msg.data_type = EIGRP_CONNECTED; + msg.adv_router = NULL; + msg.entry = ne; + msg.prefix = pe; + + eigrp_fsm_event(&msg); + } return 1; } From 02b459988199f05c81d4353d6fd6812c196c7a5d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 23 Aug 2017 14:19:45 -0400 Subject: [PATCH 60/79] eigrpd: Convert pe->destination_ipv4 to pe->destination Convert the destination_ipv4 to a struct prefix and just call it destination. Signed-off-by: Donald Sharp --- eigrpd/eigrp_dump.c | 7 +++-- eigrpd/eigrp_interface.c | 13 ++++----- eigrpd/eigrp_packet.c | 44 ++++++++++------------------- eigrpd/eigrp_reply.c | 8 +++--- eigrpd/eigrp_structs.h | 5 +--- eigrpd/eigrp_topology.c | 60 ++++++++++++++++++---------------------- eigrpd/eigrp_update.c | 48 +++++++++++++++----------------- 7 files changed, 78 insertions(+), 107 deletions(-) diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c index 0cb1ee5876..74515c98cb 100644 --- a/eigrpd/eigrp_dump.c +++ b/eigrpd/eigrp_dump.c @@ -158,7 +158,7 @@ const char *eigrp_topology_ip_string(struct eigrp_prefix_entry *tn) static char buf[EIGRP_IF_STRING_MAXLEN] = ""; u_int32_t ifaddr; - ifaddr = ntohl(tn->destination_ipv4->prefix.s_addr); + ifaddr = ntohl(tn->destination->u.prefix4.s_addr); snprintf(buf, EIGRP_IF_STRING_MAXLEN, "%u.%u.%u.%u", (ifaddr >> 24) & 0xff, (ifaddr >> 16) & 0xff, (ifaddr >> 8) & 0xff, ifaddr & 0xff); @@ -289,11 +289,12 @@ void show_ip_eigrp_topology_header(struct vty *vty, struct eigrp *eigrp) void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn) { struct list *successors = eigrp_topology_get_successor(tn); + char buffer[PREFIX_STRLEN]; vty_out(vty, "%-3c", (tn->state > 0) ? 'A' : 'P'); - vty_out(vty, "%s/%u, ", inet_ntoa(tn->destination_ipv4->prefix), - tn->destination_ipv4->prefixlen); + vty_out(vty, "%s, ", + prefix2str(tn->destination, buffer, PREFIX_STRLEN)); vty_out(vty, "%u successors, ", successors->count); vty_out(vty, "FD is %u, serno: %" PRIu64 " \n", tn->fdistance, tn->serno); diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index 207001778d..bc9172dee6 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -289,21 +289,20 @@ int eigrp_if_up(struct eigrp_interface *ei) ne->adv_router = eigrp->neighbor_self; ne->flags = EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG; - struct prefix_ipv4 dest_addr; + struct prefix dest_addr; dest_addr.family = AF_INET; - dest_addr.prefix = ei->connected->address->u.prefix4; + dest_addr.u.prefix4 = ei->connected->address->u.prefix4; dest_addr.prefixlen = ei->connected->address->prefixlen; - apply_mask_ipv4(&dest_addr); + apply_mask(&dest_addr); pe = eigrp_topology_table_lookup_ipv4(eigrp->topology_table, - &dest_addr); + (struct prefix_ipv4 *)&dest_addr); if (pe == NULL) { pe = eigrp_prefix_entry_new(); pe->serno = eigrp->serno; - pe->destination_ipv4 = prefix_ipv4_new(); - prefix_copy((struct prefix *)pe->destination_ipv4, - (struct prefix *)&dest_addr); + pe->destination = (struct prefix *)prefix_ipv4_new(); + prefix_copy(pe->destination, &dest_addr); pe->af = AF_INET; pe->nt = EIGRP_TOPOLOGY_TYPE_CONNECTED; diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c index d4e8264f20..68e7cdcbbe 100644 --- a/eigrpd/eigrp_packet.c +++ b/eigrpd/eigrp_packet.c @@ -1167,21 +1167,21 @@ u_int16_t eigrp_add_internalTLV_to_stream(struct stream *s, u_int16_t length; stream_putw(s, EIGRP_TLV_IPv4_INT); - if (pe->destination_ipv4->prefixlen <= 8) { + if (pe->destination->prefixlen <= 8) { stream_putw(s, 0x001A); length = 0x001A; } - if ((pe->destination_ipv4->prefixlen > 8) - && (pe->destination_ipv4->prefixlen <= 16)) { + if ((pe->destination->prefixlen > 8) + && (pe->destination->prefixlen <= 16)) { stream_putw(s, 0x001B); length = 0x001B; } - if ((pe->destination_ipv4->prefixlen > 16) - && (pe->destination_ipv4->prefixlen <= 24)) { + if ((pe->destination->prefixlen > 16) + && (pe->destination->prefixlen <= 24)) { stream_putw(s, 0x001C); length = 0x001C; } - if (pe->destination_ipv4->prefixlen > 24) { + if (pe->destination->prefixlen > 24) { stream_putw(s, 0x001D); length = 0x001D; } @@ -1200,34 +1200,18 @@ u_int16_t eigrp_add_internalTLV_to_stream(struct stream *s, stream_putc(s, pe->reported_metric.tag); stream_putc(s, pe->reported_metric.flags); - stream_putc(s, pe->destination_ipv4->prefixlen); + stream_putc(s, pe->destination->prefixlen); - if (pe->destination_ipv4->prefixlen <= 8) { - stream_putc(s, pe->destination_ipv4->prefix.s_addr & 0xFF); - } - if ((pe->destination_ipv4->prefixlen > 8) - && (pe->destination_ipv4->prefixlen <= 16)) { - stream_putc(s, pe->destination_ipv4->prefix.s_addr & 0xFF); + stream_putc(s, pe->destination->u.prefix4.s_addr & 0xFF); + if (pe->destination->prefixlen > 8) stream_putc(s, - (pe->destination_ipv4->prefix.s_addr >> 8) & 0xFF); - } - if ((pe->destination_ipv4->prefixlen > 16) - && (pe->destination_ipv4->prefixlen <= 24)) { - stream_putc(s, pe->destination_ipv4->prefix.s_addr & 0xFF); + (pe->destination->u.prefix4.s_addr >> 8) & 0xFF); + if (pe->destination->prefixlen > 16) stream_putc(s, - (pe->destination_ipv4->prefix.s_addr >> 8) & 0xFF); + (pe->destination->u.prefix4.s_addr >> 16) & 0xFF); + if (pe->destination->prefixlen > 24) stream_putc(s, - (pe->destination_ipv4->prefix.s_addr >> 16) & 0xFF); - } - if (pe->destination_ipv4->prefixlen > 24) { - stream_putc(s, pe->destination_ipv4->prefix.s_addr & 0xFF); - stream_putc(s, - (pe->destination_ipv4->prefix.s_addr >> 8) & 0xFF); - stream_putc(s, - (pe->destination_ipv4->prefix.s_addr >> 16) & 0xFF); - stream_putc(s, - (pe->destination_ipv4->prefix.s_addr >> 24) & 0xFF); - } + (pe->destination->u.prefix4.s_addr >> 24) & 0xFF); return length; } diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c index 304a1a5242..cc70d1cfee 100644 --- a/eigrpd/eigrp_reply.c +++ b/eigrpd/eigrp_reply.c @@ -87,19 +87,19 @@ void eigrp_send_reply(struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe) /* Check if any list fits */ if ((alist - && access_list_apply(alist, (struct prefix *)pe2->destination_ipv4) + && access_list_apply(alist, pe2->destination) == FILTER_DENY) || (plist && prefix_list_apply(plist, - (struct prefix *)pe2->destination_ipv4) + pe2->destination) == PREFIX_DENY) || (alist_i && access_list_apply(alist_i, - (struct prefix *)pe2->destination_ipv4) + pe2->destination) == FILTER_DENY) || (plist_i && prefix_list_apply(plist_i, - (struct prefix *)pe2->destination_ipv4) + pe2->destination) == PREFIX_DENY)) { zlog_info("REPLY SEND: Setting Metric to max"); pe2->reported_metric.delay = EIGRP_MAX_METRIC; diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h index 6bb0c5cc2b..b769774a03 100644 --- a/eigrpd/eigrp_structs.h +++ b/eigrpd/eigrp_structs.h @@ -469,10 +469,7 @@ struct eigrp_prefix_entry { u_char af; // address family u_char req_action; // required action - struct prefix_ipv4 - *destination_ipv4; // pointer to struct with ipv4 address - struct prefix_ipv6 - *destination_ipv6; // pointer to struct with ipv6 address + struct prefix *destination; // If network type is REMOTE_EXTERNAL, pointer will have reference to // its external TLV diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 3ba8c5b5fd..e2f47ced31 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -81,25 +81,18 @@ static int eigrp_prefix_entry_cmp(struct eigrp_prefix_entry *node1, { if (node1->af == AF_INET) { if (node2->af == AF_INET) { - if (node1->destination_ipv4->prefix.s_addr - < node2->destination_ipv4->prefix.s_addr) { - return -1; // if it belong above node2 - } else { - if (node1->destination_ipv4->prefix.s_addr - > node2->destination_ipv4->prefix.s_addr) { - return 1; // if it belongs under node2 - } else { - return 0; // same value... ERROR...in - // case of adding same prefix - // again - } - } - } else { + if (node1->destination->u.prefix4.s_addr + < node2->destination->u.prefix4.s_addr) + return -1; + if (node1->destination->u.prefix4.s_addr + > node2->destination->u.prefix4.s_addr) + return 1; + else + return 0; + } else return 1; - } - } else { // TODO check if the prefix dont exists - return 1; // add to end - } + } else + return 1; } /* @@ -125,8 +118,7 @@ struct eigrp_prefix_entry *eigrp_prefix_entry_new() new->rij = list_new(); new->entries->cmp = (int (*)(void *, void *))eigrp_neighbor_entry_cmp; new->distance = new->fdistance = new->rdistance = EIGRP_MAX_METRIC; - new->destination_ipv4 = NULL; - new->destination_ipv6 = NULL; + new->destination = NULL; return new; } @@ -137,9 +129,8 @@ struct eigrp_prefix_entry *eigrp_prefix_entry_new() static int eigrp_neighbor_entry_cmp(struct eigrp_neighbor_entry *entry1, struct eigrp_neighbor_entry *entry2) { - if (entry1->distance - < entry2->distance) // parameter used in list_add_sort () - return -1; // actually set to sort by distance + if (entry1->distance < entry2->distance) + return -1; if (entry1->distance > entry2->distance) return 1; @@ -205,7 +196,8 @@ void eigrp_neighbor_entry_add(struct eigrp_prefix_entry *node, listnode_add_sort(node->entries, entry); entry->prefix = node; - eigrp_zebra_route_add(node->destination_ipv4, l); + eigrp_zebra_route_add((struct prefix_ipv4 *) + node->destination, l); } list_delete(l); @@ -230,7 +222,8 @@ void eigrp_prefix_entry_delete(struct list *topology, list_free(node->entries); list_free(node->rij); listnode_delete(topology, node); - eigrp_zebra_route_delete(node->destination_ipv4); + eigrp_zebra_route_delete((struct prefix_ipv4 *) + node->destination); XFREE(MTYPE_EIGRP_PREFIX_ENTRY, node); } } @@ -243,7 +236,8 @@ void eigrp_neighbor_entry_delete(struct eigrp_prefix_entry *node, { if (listnode_lookup(node->entries, entry) != NULL) { listnode_delete(node->entries, entry); - eigrp_zebra_route_delete(node->destination_ipv4); + eigrp_zebra_route_delete((struct prefix_ipv4 *) + node->destination); XFREE(MTYPE_EIGRP_NEIGHBOR_ENTRY, entry); } } @@ -275,11 +269,8 @@ eigrp_topology_table_lookup_ipv4(struct list *topology_table, struct eigrp_prefix_entry *data; struct listnode *node; for (ALL_LIST_ELEMENTS_RO(topology_table, node, data)) { - if ((data->af == AF_INET) - && (data->destination_ipv4->prefix.s_addr - == address->prefix.s_addr) - && (data->destination_ipv4->prefixlen - == address->prefixlen)) + if (prefix_same(data->destination, + (struct prefix *)address)) return data; } @@ -476,13 +467,16 @@ void eigrp_update_routing_table(struct eigrp_prefix_entry *prefix) struct eigrp_neighbor_entry *entry; if (successors) { - eigrp_zebra_route_add(prefix->destination_ipv4, successors); + eigrp_zebra_route_add((struct prefix_ipv4 *) + prefix->destination, + successors); for (ALL_LIST_ELEMENTS_RO(successors, node, entry)) entry->flags |= EIGRP_NEIGHBOR_ENTRY_INTABLE_FLAG; list_delete(successors); } else { - eigrp_zebra_route_delete(prefix->destination_ipv4); + eigrp_zebra_route_delete((struct prefix_ipv4 *) + prefix->destination); for (ALL_LIST_ELEMENTS_RO(prefix->entries, node, entry)) entry->flags &= ~EIGRP_NEIGHBOR_ENTRY_INTABLE_FLAG; } diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index e4b7883741..c59a010087 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -116,9 +116,10 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp, /* iterate over all prefixes which weren't advertised by neighbor */ for (ALL_LIST_ELEMENTS_RO(nbr_prefixes, node1, prefix)) { - zlog_debug("GR receive: Neighbor not advertised %s/%d", - inet_ntoa(prefix->destination_ipv4->prefix), - prefix->destination_ipv4->prefixlen); + char buffer[PREFIX_STRLEN]; + zlog_debug("GR receive: Neighbor not advertised %s", + prefix2str(prefix->destination, + buffer, PREFIX_STRLEN)); fsm_msg.metrics = prefix->reported_metric; /* set delay to MAX */ @@ -311,9 +312,8 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, /*Here comes topology information save*/ pe = eigrp_prefix_entry_new(); pe->serno = eigrp->serno; - pe->destination_ipv4 = prefix_ipv4_new(); - prefix_copy( - (struct prefix *)pe->destination_ipv4, + pe->destination = (struct prefix *)prefix_ipv4_new(); + prefix_copy(pe->destination, (struct prefix *)&dest_addr); pe->af = AF_INET; pe->state = EIGRP_FSM_STATE_PASSIVE; @@ -571,7 +571,7 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr) struct access_list *alist_i; struct prefix_list *plist_i; struct eigrp *e; - struct prefix_ipv4 *dest_addr; + struct prefix *dest_addr; u_int32_t seq_no = nbr->ei->eigrp->sequence_number; ep = eigrp_packet_new(nbr->ei->ifp->mtu, nbr); @@ -609,7 +609,7 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr) } } /* Get destination address from prefix */ - dest_addr = pe->destination_ipv4; + dest_addr = pe->destination; /* * Filtering @@ -656,7 +656,7 @@ void eigrp_update_send(struct eigrp_interface *ei) struct access_list *alist_i; struct prefix_list *plist_i; struct eigrp *e; - struct prefix_ipv4 *dest_addr; + struct prefix *dest_addr; u_int32_t seq_no = ei->eigrp->sequence_number; if (ei->nbrs->count == 0) @@ -714,7 +714,7 @@ void eigrp_update_send(struct eigrp_interface *ei) has_tlv = 0; } /* Get destination address from prefix */ - dest_addr = pe->destination_ipv4; + dest_addr = pe->destination; /* * Filtering @@ -824,7 +824,7 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) u_int16_t length = EIGRP_HEADER_LEN; struct listnode *node, *nnode; struct eigrp_prefix_entry *pe; - struct prefix_ipv4 *dest_addr; + struct prefix *dest_addr; struct eigrp *e; struct access_list *alist, *alist_i; struct prefix_list *plist, *plist_i; @@ -887,7 +887,7 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) /* * Filtering */ - dest_addr = pe->destination_ipv4; + dest_addr = pe->destination; /* get list from eigrp process */ e = eigrp_lookup(); /* Get access-lists and prefix-lists from process and interface @@ -899,22 +899,20 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) /* Check if any list fits */ if ((alist - && access_list_apply(alist, (struct prefix *)dest_addr) + && access_list_apply(alist, dest_addr) == FILTER_DENY) || (plist - && prefix_list_apply(plist, (struct prefix *)dest_addr) + && prefix_list_apply(plist, dest_addr) == PREFIX_DENY) || (alist_i - && access_list_apply(alist_i, - (struct prefix *)dest_addr) + && access_list_apply(alist_i, dest_addr) == FILTER_DENY) || (plist_i - && prefix_list_apply(plist_i, - (struct prefix *)dest_addr) + && prefix_list_apply(plist_i, dest_addr) == PREFIX_DENY)) { /* do not send filtered route */ zlog_info("Filtered prefix %s won't be sent out.", - inet_ntoa(dest_addr->prefix)); + inet_ntoa(dest_addr->u.prefix4)); } else { /* sending route which wasn't filtered */ length += eigrp_add_internalTLV_to_stream(ep->s, pe); @@ -928,22 +926,20 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) /* Check if any list fits */ if ((alist - && access_list_apply(alist, (struct prefix *)dest_addr) + && access_list_apply(alist, dest_addr) == FILTER_DENY) || (plist - && prefix_list_apply(plist, (struct prefix *)dest_addr) + && prefix_list_apply(plist, dest_addr) == PREFIX_DENY) || (alist_i - && access_list_apply(alist_i, - (struct prefix *)dest_addr) + && access_list_apply(alist_i, dest_addr) == FILTER_DENY) || (plist_i - && prefix_list_apply(plist_i, - (struct prefix *)dest_addr) + && prefix_list_apply(plist_i, dest_addr) == PREFIX_DENY)) { /* do not send filtered route */ zlog_info("Filtered prefix %s will be removed.", - inet_ntoa(dest_addr->prefix)); + inet_ntoa(dest_addr->u.prefix4)); /* prepare message for FSM */ struct eigrp_fsm_action_message fsm_msg; From 836aad7ee82af11cc4c014d0b2de687d43c46f46 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 23 Aug 2017 14:36:06 -0400 Subject: [PATCH 61/79] eigrpd: Refactor to use 'struct prefix' for eigrp_zebra.h Signed-off-by: Donald Sharp --- eigrpd/eigrp_topology.c | 15 +++++---------- eigrpd/eigrp_zebra.c | 21 +++++++++------------ eigrpd/eigrp_zebra.h | 4 ++-- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index e2f47ced31..0ae4788fd0 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -196,8 +196,7 @@ void eigrp_neighbor_entry_add(struct eigrp_prefix_entry *node, listnode_add_sort(node->entries, entry); entry->prefix = node; - eigrp_zebra_route_add((struct prefix_ipv4 *) - node->destination, l); + eigrp_zebra_route_add(node->destination, l); } list_delete(l); @@ -222,8 +221,7 @@ void eigrp_prefix_entry_delete(struct list *topology, list_free(node->entries); list_free(node->rij); listnode_delete(topology, node); - eigrp_zebra_route_delete((struct prefix_ipv4 *) - node->destination); + eigrp_zebra_route_delete(node->destination); XFREE(MTYPE_EIGRP_PREFIX_ENTRY, node); } } @@ -236,8 +234,7 @@ void eigrp_neighbor_entry_delete(struct eigrp_prefix_entry *node, { if (listnode_lookup(node->entries, entry) != NULL) { listnode_delete(node->entries, entry); - eigrp_zebra_route_delete((struct prefix_ipv4 *) - node->destination); + eigrp_zebra_route_delete(node->destination); XFREE(MTYPE_EIGRP_NEIGHBOR_ENTRY, entry); } } @@ -467,16 +464,14 @@ void eigrp_update_routing_table(struct eigrp_prefix_entry *prefix) struct eigrp_neighbor_entry *entry; if (successors) { - eigrp_zebra_route_add((struct prefix_ipv4 *) - prefix->destination, + eigrp_zebra_route_add(prefix->destination, successors); for (ALL_LIST_ELEMENTS_RO(successors, node, entry)) entry->flags |= EIGRP_NEIGHBOR_ENTRY_INTABLE_FLAG; list_delete(successors); } else { - eigrp_zebra_route_delete((struct prefix_ipv4 *) - prefix->destination); + eigrp_zebra_route_delete(prefix->destination); for (ALL_LIST_ELEMENTS_RO(prefix->entries, node, entry)) entry->flags &= ~EIGRP_NEIGHBOR_ENTRY_INTABLE_FLAG; } diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index 5aa7821e18..47871dfd3e 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -361,7 +361,7 @@ static struct interface *zebra_interface_if_lookup(struct stream *s) ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), VRF_DEFAULT); } -void eigrp_zebra_route_add(struct prefix_ipv4 *p, struct list *successors) +void eigrp_zebra_route_add(struct prefix *p, struct list *successors) { struct zapi_route api; struct zapi_nexthop *api_nh; @@ -395,18 +395,16 @@ void eigrp_zebra_route_add(struct prefix_ipv4 *p, struct list *successors) } if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug( - "Zebra: Route add %s/%d nexthop %s", - inet_ntop(AF_INET, &p->prefix, buf[0], sizeof(buf[0])), - p->prefixlen, inet_ntop(AF_INET, 0 /*&p->nexthop*/, - buf[1], sizeof(buf[1]))); + char buf[2][PREFIX_STRLEN]; + zlog_debug("Zebra: Route add %s nexthop %s", + prefix2str(p, buf[0], PREFIX_STRLEN), + inet_ntop(AF_INET, 0, buf[1], PREFIX_STRLEN)); } zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); } -void eigrp_zebra_route_delete(struct prefix_ipv4 *p) +void eigrp_zebra_route_delete(struct prefix *p) { struct zapi_route api; @@ -421,10 +419,9 @@ void eigrp_zebra_route_delete(struct prefix_ipv4 *p) zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[INET_ADDRSTRLEN]; - zlog_debug("Zebra: Route del %s/%d", - inet_ntop(AF_INET, &p->prefix, buf, sizeof(buf)), - p->prefixlen); + char buf[PREFIX_STRLEN]; + zlog_debug("Zebra: Route del %s", + prefix2str(p, buf, PREFIX_STRLEN)); } return; diff --git a/eigrpd/eigrp_zebra.h b/eigrpd/eigrp_zebra.h index 3281c47018..1c418dddef 100644 --- a/eigrpd/eigrp_zebra.h +++ b/eigrpd/eigrp_zebra.h @@ -33,8 +33,8 @@ extern void eigrp_zebra_init(void); -extern void eigrp_zebra_route_add(struct prefix_ipv4 *, struct list *); -extern void eigrp_zebra_route_delete(struct prefix_ipv4 *); +extern void eigrp_zebra_route_add(struct prefix *, struct list *); +extern void eigrp_zebra_route_delete(struct prefix *); extern int eigrp_redistribute_set(struct eigrp *, int, struct eigrp_metrics); extern int eigrp_redistribute_unset(struct eigrp *, int); extern int eigrp_is_type_redistributed(int); From 476a146963c960a28c044d89840d9f0cbb41c62e Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 23 Aug 2017 15:31:02 -0400 Subject: [PATCH 62/79] eigrpd: Refactor eigrp_topoloy_table_lookup_ipv4 Allow eigrp_topology_table_lookup_ipv4 to use 'struct prefix' Signed-off-by: Donald Sharp --- eigrpd/eigrp_interface.c | 10 ++++------ eigrpd/eigrp_query.c | 4 ++-- eigrpd/eigrp_reply.c | 4 ++-- eigrpd/eigrp_siaquery.c | 4 ++-- eigrpd/eigrp_siareply.c | 4 ++-- eigrpd/eigrp_topology.c | 5 ++--- eigrpd/eigrp_topology.h | 2 +- eigrpd/eigrp_update.c | 42 ++++++++++++++++++---------------------- 8 files changed, 34 insertions(+), 41 deletions(-) diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index bc9172dee6..9f54b62353 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -296,7 +296,7 @@ int eigrp_if_up(struct eigrp_interface *ei) dest_addr.prefixlen = ei->connected->address->prefixlen; apply_mask(&dest_addr); pe = eigrp_topology_table_lookup_ipv4(eigrp->topology_table, - (struct prefix_ipv4 *)&dest_addr); + &dest_addr); if (pe == NULL) { pe = eigrp_prefix_entry_new(); @@ -430,7 +430,7 @@ u_char eigrp_default_iftype(struct interface *ifp) void eigrp_if_free(struct eigrp_interface *ei, int source) { - struct prefix_ipv4 dest_addr; + struct prefix dest_addr; struct eigrp_prefix_entry *pe; struct eigrp *eigrp = eigrp_lookup(); @@ -439,10 +439,8 @@ void eigrp_if_free(struct eigrp_interface *ei, int source) eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL); } - dest_addr.family = AF_INET; - dest_addr.prefix = ei->connected->address->u.prefix4; - dest_addr.prefixlen = ei->connected->address->prefixlen; - apply_mask_ipv4(&dest_addr); + dest_addr = *ei->connected->address; + apply_mask(&dest_addr); pe = eigrp_topology_table_lookup_ipv4(eigrp->topology_table, &dest_addr); if (pe) diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c index 4757097315..0167c8b3c2 100644 --- a/eigrpd/eigrp_query.c +++ b/eigrpd/eigrp_query.c @@ -91,7 +91,7 @@ void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph, { struct eigrp_neighbor *nbr; struct TLV_IPv4_Internal_type *tlv; - struct prefix_ipv4 dest_addr; + struct prefix dest_addr; u_int16_t type; u_int16_t length; @@ -116,7 +116,7 @@ void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph, tlv = eigrp_read_ipv4_tlv(s); dest_addr.family = AF_INET; - dest_addr.prefix = tlv->destination; + dest_addr.u.prefix4 = tlv->destination; dest_addr.prefixlen = tlv->prefix_length; struct eigrp_prefix_entry *dest = eigrp_topology_table_lookup_ipv4( diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c index cc70d1cfee..2b5b0aa44b 100644 --- a/eigrpd/eigrp_reply.c +++ b/eigrpd/eigrp_reply.c @@ -179,14 +179,14 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph, while (s->endp > s->getp) { type = stream_getw(s); if (type == EIGRP_TLV_IPv4_INT) { - struct prefix_ipv4 dest_addr; + struct prefix dest_addr; stream_set_getp(s, s->getp - sizeof(u_int16_t)); tlv = eigrp_read_ipv4_tlv(s); dest_addr.family = AF_INET; - dest_addr.prefix = tlv->destination; + dest_addr.u.prefix4 = tlv->destination; dest_addr.prefixlen = tlv->prefix_length; struct eigrp_prefix_entry *dest = eigrp_topology_table_lookup_ipv4( diff --git a/eigrpd/eigrp_siaquery.c b/eigrpd/eigrp_siaquery.c index cd04f88595..7264e53b6b 100644 --- a/eigrpd/eigrp_siaquery.c +++ b/eigrpd/eigrp_siaquery.c @@ -78,14 +78,14 @@ void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph, while (s->endp > s->getp) { type = stream_getw(s); if (type == EIGRP_TLV_IPv4_INT) { - struct prefix_ipv4 dest_addr; + struct prefix dest_addr; stream_set_getp(s, s->getp - sizeof(u_int16_t)); tlv = eigrp_read_ipv4_tlv(s); dest_addr.family = AFI_IP; - dest_addr.prefix = tlv->destination; + dest_addr.u.prefix4 = tlv->destination; dest_addr.prefixlen = tlv->prefix_length; struct eigrp_prefix_entry *dest = eigrp_topology_table_lookup_ipv4( diff --git a/eigrpd/eigrp_siareply.c b/eigrpd/eigrp_siareply.c index 5e83549488..8496c05675 100644 --- a/eigrpd/eigrp_siareply.c +++ b/eigrpd/eigrp_siareply.c @@ -77,14 +77,14 @@ void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph, while (s->endp > s->getp) { type = stream_getw(s); if (type == EIGRP_TLV_IPv4_INT) { - struct prefix_ipv4 dest_addr; + struct prefix dest_addr; stream_set_getp(s, s->getp - sizeof(u_int16_t)); tlv = eigrp_read_ipv4_tlv(s); dest_addr.family = AFI_IP; - dest_addr.prefix = tlv->destination; + dest_addr.u.prefix4 = tlv->destination; dest_addr.prefixlen = tlv->prefix_length; struct eigrp_prefix_entry *dest = eigrp_topology_table_lookup_ipv4( diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 0ae4788fd0..6bc0987daa 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -261,13 +261,12 @@ unsigned int eigrp_topology_table_isempty(struct list *topology) struct eigrp_prefix_entry * eigrp_topology_table_lookup_ipv4(struct list *topology_table, - struct prefix_ipv4 *address) + struct prefix *address) { struct eigrp_prefix_entry *data; struct listnode *node; for (ALL_LIST_ELEMENTS_RO(topology_table, node, data)) { - if (prefix_same(data->destination, - (struct prefix *)address)) + if (prefix_same(data->destination, address)) return data; } diff --git a/eigrpd/eigrp_topology.h b/eigrpd/eigrp_topology.h index 0c9b5c60c6..8bff08b75a 100644 --- a/eigrpd/eigrp_topology.h +++ b/eigrpd/eigrp_topology.h @@ -49,7 +49,7 @@ extern void eigrp_neighbor_entry_delete(struct eigrp_prefix_entry *, extern void eigrp_topology_delete_all(struct list *); extern unsigned int eigrp_topology_table_isempty(struct list *); extern struct eigrp_prefix_entry * -eigrp_topology_table_lookup_ipv4(struct list *, struct prefix_ipv4 *); +eigrp_topology_table_lookup_ipv4(struct list *, struct prefix *); extern struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *); extern struct list * eigrp_topology_get_successor_max(struct eigrp_prefix_entry *pe, diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index c59a010087..d6a1134124 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -157,7 +157,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, u_char same; struct access_list *alist; struct prefix_list *plist; - struct prefix_ipv4 dest_addr; + struct prefix dest_addr; struct eigrp *e; u_char graceful_restart; u_char graceful_restart_final; @@ -281,7 +281,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, /*searching if destination exists */ dest_addr.family = AF_INET; - dest_addr.prefix = tlv->destination; + dest_addr.u.prefix4 = tlv->destination; dest_addr.prefixlen = tlv->prefix_length; struct eigrp_prefix_entry *dest = eigrp_topology_table_lookup_ipv4( @@ -314,7 +314,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, pe->serno = eigrp->serno; pe->destination = (struct prefix *)prefix_ipv4_new(); prefix_copy(pe->destination, - (struct prefix *)&dest_addr); + &dest_addr); pe->af = AF_INET; pe->state = EIGRP_FSM_STATE_PASSIVE; pe->nt = EIGRP_TOPOLOGY_TYPE_REMOTE; @@ -338,9 +338,8 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, /* Check if access-list fits */ if (alist - && access_list_apply( - alist, - (struct prefix *)&dest_addr) + && access_list_apply(alist, + &dest_addr) == FILTER_DENY) { /* If yes, set reported metric to Max */ ne->reported_metric.delay = @@ -355,9 +354,8 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, /* Check if prefix-list fits */ if (plist - && prefix_list_apply( - plist, - (struct prefix *)&dest_addr) + && prefix_list_apply(plist, + &dest_addr) == PREFIX_DENY) { /* If yes, set reported metric to Max */ ne->reported_metric.delay = @@ -369,9 +367,8 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, /* Check if access-list fits */ if (alist - && access_list_apply( - alist, - (struct prefix *)&dest_addr) + && access_list_apply(alist, + &dest_addr) == FILTER_DENY) { /* If yes, set reported metric to Max */ ne->reported_metric.delay = @@ -382,9 +379,8 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, /* Check if prefix-list fits */ if (plist - && prefix_list_apply( - plist, - (struct prefix *)&dest_addr) + && prefix_list_apply(plist, + &dest_addr) == PREFIX_DENY) { /* If yes, set reported metric to Max */ ne->reported_metric.delay = @@ -626,13 +622,13 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr) /* Check if any list fits */ if ((alist && access_list_apply (alist, - (struct prefix *) dest_addr) == FILTER_DENY)|| + dest_addr) == FILTER_DENY)|| (plist && prefix_list_apply (plist, - (struct prefix *) dest_addr) == PREFIX_DENY)|| + dest_addr) == PREFIX_DENY)|| (alist_i && access_list_apply (alist_i, - (struct prefix *) dest_addr) == FILTER_DENY)|| + dest_addr) == FILTER_DENY)|| (plist_i && prefix_list_apply (plist_i, - (struct prefix *) dest_addr) == PREFIX_DENY)) { + dest_addr) == PREFIX_DENY)) { //pe->reported_metric.delay = EIGRP_MAX_METRIC; continue; } else { @@ -730,19 +726,19 @@ void eigrp_update_send(struct eigrp_interface *ei) /* Check if any list fits */ if ((alist && access_list_apply(alist, - (struct prefix *)dest_addr) + dest_addr) == FILTER_DENY) || (plist && prefix_list_apply(plist, - (struct prefix *)dest_addr) + dest_addr) == PREFIX_DENY) || (alist_i && access_list_apply(alist_i, - (struct prefix *)dest_addr) + dest_addr) == FILTER_DENY) || (plist_i && prefix_list_apply(plist_i, - (struct prefix *)dest_addr) + dest_addr) == PREFIX_DENY)) { // pe->reported_metric.delay = EIGRP_MAX_METRIC; continue; From cd6c066eb3a62f7d68458a18df70a893b6f0db1d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 23 Aug 2017 15:35:27 -0400 Subject: [PATCH 63/79] eigrpd: Refactor eigrp_network_[un]set to use prefix Signed-off-by: Donald Sharp --- eigrpd/eigrp_network.c | 8 ++++---- eigrpd/eigrp_network.h | 4 ++-- eigrpd/eigrp_vty.c | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index ec8806750b..81597726e0 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -229,7 +229,7 @@ int eigrp_if_drop_allspfrouters(struct eigrp *top, struct prefix *p, return ret; } -int eigrp_network_set(struct eigrp *eigrp, struct prefix_ipv4 *p) +int eigrp_network_set(struct eigrp *eigrp, struct prefix *p) { struct route_node *rn; struct interface *ifp; @@ -334,21 +334,21 @@ void eigrp_if_update(struct interface *ifp) } } -int eigrp_network_unset(struct eigrp *eigrp, struct prefix_ipv4 *p) +int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p) { struct route_node *rn; struct listnode *node, *nnode; struct eigrp_interface *ei; struct prefix *pref; - rn = route_node_lookup(eigrp->networks, (struct prefix *)p); + rn = route_node_lookup(eigrp->networks, p); if (rn == NULL) return 0; pref = rn->info; route_unlock_node(rn); - if (!IPV4_ADDR_SAME(&pref->u.prefix4, &p->prefix)) + if (!IPV4_ADDR_SAME(&pref->u.prefix4, &p->u.prefix4)) return 0; prefix_ipv4_free(rn->info); diff --git a/eigrpd/eigrp_network.h b/eigrpd/eigrp_network.h index e38f7ded40..6ddd57eee5 100644 --- a/eigrpd/eigrp_network.h +++ b/eigrpd/eigrp_network.h @@ -32,8 +32,8 @@ extern int eigrp_sock_init(void); extern int eigrp_if_ipmulticast(struct eigrp *, struct prefix *, unsigned int); -extern int eigrp_network_set(struct eigrp *, struct prefix_ipv4 *); -extern int eigrp_network_unset(struct eigrp *eigrp, struct prefix_ipv4 *p); +extern int eigrp_network_set(struct eigrp *eigrp, struct prefix *p); +extern int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p); extern int eigrp_hello_timer(struct thread *); extern void eigrp_if_update(struct interface *); diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 465007478d..4a8842f30e 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -391,10 +391,10 @@ DEFUN (eigrp_network, "EIGRP network prefix\n") { VTY_DECLVAR_CONTEXT(eigrp, eigrp); - struct prefix_ipv4 p; + struct prefix p; int ret; - str2prefix_ipv4(argv[1]->arg, &p); + str2prefix(argv[1]->arg, &p); ret = eigrp_network_set(eigrp, &p); @@ -414,10 +414,10 @@ DEFUN (no_eigrp_network, "EIGRP network prefix\n") { VTY_DECLVAR_CONTEXT(eigrp, eigrp); - struct prefix_ipv4 p; + struct prefix p; int ret; - str2prefix_ipv4(argv[2]->arg, &p); + str2prefix(argv[2]->arg, &p); ret = eigrp_network_unset(eigrp, &p); From 0ffa840756e10b6efb83e24aeaddf3e5f28c8ef3 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 23 Aug 2017 15:38:29 -0400 Subject: [PATCH 64/79] eigrpd: Remove 'struct prefix_ipv4' from eigrp_interface.c Signed-off-by: Donald Sharp --- eigrpd/eigrp_interface.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index 9f54b62353..ae9ec293ce 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -225,14 +225,14 @@ void eigrp_del_if_params(struct eigrp_if_params *eip) struct eigrp_if_params *eigrp_lookup_if_params(struct interface *ifp, struct in_addr addr) { - struct prefix_ipv4 p; + struct prefix p; struct route_node *rn; p.family = AF_INET; p.prefixlen = IPV4_MAX_PREFIXLEN; - p.prefix = addr; + p.u.prefix4 = addr; - rn = route_node_lookup(IF_OIFS_PARAMS(ifp), (struct prefix *)&p); + rn = route_node_lookup(IF_OIFS_PARAMS(ifp), &p); if (rn) { route_unlock_node(rn); @@ -544,11 +544,11 @@ struct eigrp_interface *eigrp_if_lookup_recv_if(struct eigrp *eigrp, struct interface *ifp) { struct route_node *rn; - struct prefix_ipv4 addr; + struct prefix addr; struct eigrp_interface *ei, *match; addr.family = AF_INET; - addr.prefix = src; + addr.u.prefix4 = src; addr.prefixlen = IPV4_MAX_BITLEN; match = NULL; @@ -563,7 +563,7 @@ struct eigrp_interface *eigrp_if_lookup_recv_if(struct eigrp *eigrp, continue; if (prefix_match(CONNECTED_PREFIX(ei->connected), - (struct prefix *)&addr)) { + &addr)) { if ((match == NULL) || (match->address->prefixlen < ei->address->prefixlen)) match = ei; From a96029f8242521e0a905ae31a5ce21d57b91be67 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 23 Aug 2017 15:39:30 -0400 Subject: [PATCH 65/79] eigrpd: Remove 'struct prefix_ipv4' from eigrp_network.c Signed-off-by: Donald Sharp --- eigrpd/eigrp_network.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index 81597726e0..0cf5bd9bad 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -242,7 +242,7 @@ int eigrp_network_set(struct eigrp *eigrp, struct prefix *p) return 0; } - struct prefix_ipv4 *pref = prefix_ipv4_new(); + struct prefix *pref = prefix_new(); PREFIX_COPY_IPV4(pref, p); rn->info = (void *)pref; @@ -253,7 +253,7 @@ int eigrp_network_set(struct eigrp *eigrp, struct prefix *p) /* Get target interface. */ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { zlog_debug("Setting up %s", ifp->name); - eigrp_network_run_interface(eigrp, (struct prefix *)p, ifp); + eigrp_network_run_interface(eigrp, p, ifp); } return 1; } From 4a64eed5773e6472985a7d42599853af553e4f05 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 23 Aug 2017 20:26:19 -0400 Subject: [PATCH 66/79] eigrpd: Fix compiler warning introduced Signed-off-by: Donald Sharp --- eigrpd/eigrp_topology.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 6bc0987daa..2e8128f474 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -402,10 +402,10 @@ enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_messag if (eigrp_metrics_is_same(msg->metrics, entry->reported_metric)) return change; - } else + } else { change = METRIC_INCREASE; - - break; + } + break; default: zlog_err("%s: Please implement handler", __PRETTY_FUNCTION__); break; From 532e75e6ee1484d1940d9a918548227e920de9b5 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 24 Aug 2017 07:34:21 -0400 Subject: [PATCH 67/79] eigrpd: Fix distance comparison The distance comparison for when we received an internal and we already had an internal was overriding the metrics of the connected. Signed-off-by: Donald Sharp --- eigrpd/eigrp_topology.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 2e8128f474..64e65b694c 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -379,6 +379,10 @@ enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_messag change = METRIC_DECREASE; break; case EIGRP_INT: + if (prefix->nt == EIGRP_TOPOLOGY_TYPE_CONNECTED) { + change = METRIC_INCREASE; + goto distance_done; + } if (eigrp_metrics_is_same(msg->metrics, entry->reported_metric)) { return change; // No change @@ -387,9 +391,10 @@ enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_messag new_reported_distance = eigrp_calculate_metrics(eigrp, msg->metrics); - if (entry->reported_distance < new_reported_distance) + if (entry->reported_distance < new_reported_distance) { change = METRIC_INCREASE; - else + goto distance_done; + } else change = METRIC_DECREASE; entry->reported_metric = msg->metrics; @@ -404,12 +409,14 @@ enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_messag return change; } else { change = METRIC_INCREASE; + goto distance_done; } break; default: zlog_err("%s: Please implement handler", __PRETTY_FUNCTION__); break; } + distance_done: /* * Move to correct position in list according to new distance */ From b5f7965155038d947f733d6aee92915c3c5d581c Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 24 Aug 2017 08:30:08 -0400 Subject: [PATCH 68/79] lib: Fix nexthop num If we assign MULTIPATH_NUM to be 256, this causes issues for us since 256 is bigger than a u_char. So let's make the api's multipath_num to be a u_int16_t and pass it around as a word. Signed-off-by: Donald Sharp --- lib/zclient.c | 4 ++-- lib/zclient.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/zclient.c b/lib/zclient.c index 75005d656b..72fa2679b3 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -940,7 +940,7 @@ int zapi_route_encode(u_char cmd, struct stream *s, struct zapi_route *api) api->nexthop_num = MULTIPATH_NUM; } - stream_putc(s, api->nexthop_num); + stream_putw(s, api->nexthop_num); for (i = 0; i < api->nexthop_num; i++) { api_nh = &api->nexthops[i]; @@ -1047,7 +1047,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) /* Nexthops. */ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) { - api->nexthop_num = stream_getc(s); + api->nexthop_num = stream_getw(s); if (api->nexthop_num > MULTIPATH_NUM) { zlog_warn("%s: invalid number of nexthops (%u)", __func__, api->nexthop_num); diff --git a/lib/zclient.h b/lib/zclient.h index bae52a441b..7c4780201e 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -242,7 +242,7 @@ struct zapi_route { struct prefix prefix; struct prefix_ipv6 src_prefix; - u_char nexthop_num; + u_int16_t nexthop_num; struct zapi_nexthop nexthops[MULTIPATH_NUM]; u_char distance; From 6c65db5f990f9e6a460d592fde1b1a9b86dd2f45 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 24 Aug 2017 09:53:05 -0400 Subject: [PATCH 69/79] pimd: Cleanup a debug for vrf Signed-off-by: Donald Sharp --- pimd/pim_upstream.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 1fc952fdf8..96b9568c61 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -1624,8 +1624,9 @@ static void pim_upstream_sg_running(void *arg) // No packet can have arrived here if this is the case if (!up->channel_oil->installed) { if (PIM_DEBUG_TRACE) - zlog_debug("%s: %s is not installed in mroute", - __PRETTY_FUNCTION__, up->sg_str); + zlog_debug("%s: %s[%s] is not installed in mroute", + __PRETTY_FUNCTION__, + up->sg_str, pim->vrf->name); return; } From c206937b91fb1c50796e03ff3f35d1fd2ac81bc6 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 24 Aug 2017 09:55:19 -0400 Subject: [PATCH 70/79] pimd: Cleanup S,GRPt prune handling on Mroute Loss 1) Clean up display of S,GRPt prune state to be more meaningful 2) Upon receipt of a S,GRPt prune make sure we transition to the correct state 3) Upon loss of a S,GRPt prune make sure we transition to the correct state as well as immediately send a *,G join upstream to propagate the loss of the prune. 4) Removal of a weird S,G state being installed upon loss of a S,G RPt prune. Signed-off-by: Donald Sharp --- pimd/pim_cmd.c | 4 +- pimd/pim_ifchannel.c | 121 +++++++++++++++++++++++-------------------- pimd/pim_ifchannel.h | 3 +- pimd/pim_join.c | 9 +--- 4 files changed, 70 insertions(+), 67 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 9c79fd87e2..ae509f4a9b 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1666,7 +1666,7 @@ static void pim_show_join_helper(struct vty *vty, json_row); } else { vty_out(vty, - "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s\n", + "%-9s %-15s %-15s %-15s %-10s %8s %-6s %5s\n", ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str, pim_ifchannel_ifjoin_name(ch->ifjoin_state, @@ -1690,7 +1690,7 @@ static void pim_show_join(struct pim_instance *pim, struct vty *vty, u_char uj) json = json_object_new_object(); else vty_out(vty, - "Interface Address Source Group State Uptime Expire Prune\n"); + "Interface Address Source Group State Uptime Expire Prune\n"); for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) { pim_ifp = ifp->info; diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 39f5f2cc4b..b5d6f04948 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -42,6 +42,7 @@ #include "pim_oil.h" #include "pim_upstream.h" #include "pim_ssm.h" +#include "pim_rp.h" RB_GENERATE(pim_ifchannel_rb, pim_ifchannel, pim_ifp_rb, pim_ifchannel_compare); @@ -348,7 +349,7 @@ const char *pim_ifchannel_ifjoin_name(enum pim_ifjoin_state ifjoin_state, switch (ifjoin_state) { case PIM_IFJOIN_NOINFO: if (PIM_IF_FLAG_TEST_S_G_RPT(flags)) - return "SGRpt"; + return "SGRpt(NI)"; else return "NOINFO"; break; @@ -356,16 +357,28 @@ const char *pim_ifchannel_ifjoin_name(enum pim_ifjoin_state ifjoin_state, return "JOIN"; break; case PIM_IFJOIN_PRUNE: - return "PRUNE"; + if (PIM_IF_FLAG_TEST_S_G_RPT(flags)) + return "SGRpt(P)"; + else + return "PRUNE"; break; case PIM_IFJOIN_PRUNE_PENDING: - return "PRUNEP"; + if (PIM_IF_FLAG_TEST_S_G_RPT(flags)) + return "SGRpt(PP)"; + else + return "PRUNEP"; break; case PIM_IFJOIN_PRUNE_TMP: - return "PRUNET"; + if (PIM_IF_FLAG_TEST_S_G_RPT(flags)) + return "SGRpt(P')"; + else + return "PRUNET"; break; case PIM_IFJOIN_PRUNE_PENDING_TMP: - return "PRUNEPT"; + if (PIM_IF_FLAG_TEST_S_G_RPT(flags)) + return "SGRpt(PP')"; + else + return "PRUNEPT"; break; } @@ -628,33 +641,34 @@ static int on_ifjoin_prune_pending_timer(struct thread *t) ch = THREAD_ARG(t); if (ch->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING) { - /* Send PruneEcho(S,G) ? */ ifp = ch->interface; pim_ifp = ifp->info; - send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1); + if (!PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)) { + /* Send PruneEcho(S,G) ? */ + send_prune_echo = + (listcount(pim_ifp->pim_neighbor_list) > 1); - if (send_prune_echo) { - struct pim_rpf rpf; + if (send_prune_echo) { + struct pim_rpf rpf; - rpf.source_nexthop.interface = ifp; - rpf.rpf_addr.u.prefix4 = pim_ifp->primary_address; - pim_jp_agg_single_upstream_send(&rpf, ch->upstream, 0); - } - /* If SGRpt flag is set on ifchannel, Trigger SGRpt - message on RP path upon prune timer expiry. - */ - if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)) { + rpf.source_nexthop.interface = ifp; + rpf.rpf_addr.u.prefix4 = + pim_ifp->primary_address; + pim_jp_agg_single_upstream_send(&rpf, + ch->upstream, + 0); + } + + ifjoin_to_noinfo(ch, true); + } else { + /* If SGRpt flag is set on ifchannel, Trigger SGRpt + * message on RP path upon prune timer expiry. + */ + ch->ifjoin_state = PIM_IFJOIN_PRUNE; if (ch->upstream) pim_upstream_update_join_desired(pim_ifp->pim, ch->upstream); - /* - ch->ifjoin_state transition to NOINFO state - ch_del is set to 0 for not deleteing from here. - Holdtime expiry (ch_del set to 1) delete the entry. - */ - ifjoin_to_noinfo(ch, false); - } else - ifjoin_to_noinfo(ch, true); + } /* from here ch may have been deleted */ } else { zlog_warn( @@ -1104,7 +1118,6 @@ void pim_ifchannel_local_membership_del(struct interface *ifp, orig = ch = pim_ifchannel_find(ifp, sg); if (!ch) return; - ifmembership_set(ch, PIM_IFMEMBERSHIP_NOINFO); if (sg->src.s_addr == INADDR_ANY) { @@ -1311,11 +1324,12 @@ void pim_ifchannel_scan_forward_start(struct interface *new_ifp) * we get End of Message */ void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom, - uint8_t source_flags, uint8_t join, - uint8_t starg_alone) + uint8_t join) { struct pim_ifchannel *child; struct listnode *ch_node; + struct pim_instance *pim = + ((struct pim_interface *)ch->interface->info)->pim; if (PIM_DEBUG_PIM_TRACE) zlog_debug( @@ -1326,33 +1340,6 @@ void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom, return; for (ALL_LIST_ELEMENTS_RO(ch->sources, ch_node, child)) { - /* Only *,G Join received and no (SG-RPT) prune. - eom = 1, only (W,G) join_alone is true, WC and RPT are set. - Scan all S,G associated to G and if any SG-RPT - remove the SG-RPT flag. - */ - if (eom && starg_alone && (source_flags & PIM_RPT_BIT_MASK) - && (source_flags & PIM_WILDCARD_BIT_MASK)) { - if (PIM_IF_FLAG_TEST_S_G_RPT(child->flags)) { - struct pim_upstream *up = child->upstream; - - PIM_IF_FLAG_UNSET_S_G_RPT(child->flags); - if (up) { - if (PIM_DEBUG_TRACE) - zlog_debug( - "%s: SGRpt flag is cleared, add inherit oif to up %s", - __PRETTY_FUNCTION__, - up->sg_str); - pim_channel_add_oif( - up->channel_oil, ch->interface, - PIM_OIF_FLAG_PROTO_STAR); - pim_ifchannel_ifjoin_switch( - __PRETTY_FUNCTION__, child, - PIM_IFJOIN_JOIN); - } - } - } - if (!PIM_IF_FLAG_TEST_S_G_RPT(child->flags)) continue; @@ -1371,8 +1358,30 @@ void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom, break; case PIM_IFJOIN_PRUNE_TMP: case PIM_IFJOIN_PRUNE_PENDING_TMP: - if (eom) + if (eom) { + struct pim_upstream *parent = + child->upstream->parent; + + PIM_IF_FLAG_UNSET_S_G_RPT(child->flags); child->ifjoin_state = PIM_IFJOIN_NOINFO; + + if (I_am_RP(pim, child->sg.grp)) { + pim_channel_add_oif( + child->upstream->channel_oil, + ch->interface, + PIM_OIF_FLAG_PROTO_STAR); + pim_upstream_switch( + pim, child->upstream, + PIM_UPSTREAM_JOINED); + pim_jp_agg_single_upstream_send( + &child->upstream->rpf, + child->upstream, true); + } + if (parent) + pim_jp_agg_single_upstream_send( + &parent->rpf, + parent, true); + } break; } } diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h index cef431c30d..0b1a8ea0e8 100644 --- a/pimd/pim_ifchannel.h +++ b/pimd/pim_ifchannel.h @@ -151,8 +151,7 @@ void pim_ifchannel_update_assert_tracking_desired(struct pim_ifchannel *ch); void pim_ifchannel_scan_forward_start(struct interface *new_ifp); void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom, - uint8_t source_flags, uint8_t join, - uint8_t starg_alone); + uint8_t join); int pim_ifchannel_compare(const struct pim_ifchannel *ch1, const struct pim_ifchannel *ch2); diff --git a/pimd/pim_join.c b/pimd/pim_join.c index c60e5a65aa..9d65330e5f 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -231,7 +231,6 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, uint16_t msg_num_pruned_sources; int source; struct pim_ifchannel *starg_ch = NULL, *sg_ch = NULL; - uint8_t starg_alone = 0; memset(&sg, 0, sizeof(struct prefix_sg)); addr_offset = pim_parse_addr_group(&sg, buf, pastend - buf); @@ -289,12 +288,10 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, msg_source_flags); if (sg.src.s_addr == INADDR_ANY) { - starg_alone = 1; starg_ch = pim_ifchannel_find(ifp, &sg); if (starg_ch) pim_ifchannel_set_star_g_join_state( - starg_ch, 0, msg_source_flags, - 1, starg_alone); + starg_ch, 0, 1); } } @@ -307,7 +304,6 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, } buf += addr_offset; - starg_alone = 0; recv_prune(ifp, neigh, msg_holdtime, msg_upstream_addr.u.prefix4, &sg, msg_source_flags); @@ -340,8 +336,7 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, } } if (starg_ch) - pim_ifchannel_set_star_g_join_state( - starg_ch, 1, msg_source_flags, 0, starg_alone); + pim_ifchannel_set_star_g_join_state(starg_ch, 1, 0); starg_ch = NULL; } /* scan groups */ From 0ee0892b6645c93d0e5f757b665ed40722487f96 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 25 Aug 2017 18:54:13 +0200 Subject: [PATCH 71/79] clippy: disable unneeded autogenerated code Coverity is generating a lot of warnings about unused stuff being around. Disabling these bits is most easily done by just putting a few preprocessor directives into the template. Signed-off-by: David Lamparter --- python/clidef.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/python/clidef.py b/python/clidef.py index aa6cd18b8b..6a69986323 100644 --- a/python/clidef.py +++ b/python/clidef.py @@ -36,12 +36,14 @@ class RenderHandler(object): deref = '' drop_str = False + canfail = True class StringHandler(RenderHandler): argtype = 'const char *' decl = Template('const char *$varname = NULL;') code = Template('$varname = argv[_i]->arg;') drop_str = True + canfail = False class LongHandler(RenderHandler): argtype = 'long' @@ -130,6 +132,10 @@ handlers = { } # core template invoked for each occurence of DEFPY. +# +# the "#if $..." bits are there to keep this template unified into one +# common form, without requiring a more advanced template engine (e.g. +# jinja2) templ = Template('''/* $fnname => "$cmddef" */ DEFUN_CMD_FUNC_DECL($fnname) #define funcdecl_$fnname static int ${fnname}_magic(\\ @@ -140,20 +146,31 @@ DEFUN_CMD_FUNC_DECL($fnname) funcdecl_$fnname; DEFUN_CMD_FUNC_TEXT($fnname) { +#if $nonempty /* anything to parse? */ int _i; +#if $canfail /* anything that can fail? */ unsigned _fail = 0, _failcnt = 0; +#endif $argdecls for (_i = 0; _i < argc; _i++) { if (!argv[_i]->varname) continue; - _fail = 0;$argblocks +#if $canfail /* anything that can fail? */ + _fail = 0; +#endif +$argblocks +#if $canfail /* anything that can fail? */ if (_fail) vty_out (vty, "%% invalid input for %s: %s\\n", argv[_i]->varname, argv[_i]->arg); _failcnt += _fail; +#endif } +#if $canfail /* anything that can fail? */ if (_failcnt) return CMD_WARNING; +#endif +#endif return ${fnname}_magic(self, vty, argc, argv$arglist); } @@ -196,6 +213,7 @@ def process_file(fn, ofd, dumpfd, all_defun): arglist = [] argblocks = [] doc = [] + canfail = 0 def do_add(handler, varname, attr = ''): argdefs.append(',\\\n\t%s %s%s' % (handler.argtype, varname, attr)) @@ -213,6 +231,8 @@ def process_file(fn, ofd, dumpfd, all_defun): if handler is None: continue do_add(handler, varname) code = handler.code.substitute({'varname': varname}).replace('\n', '\n\t\t\t') + if handler.canfail: + canfail = 1 strblock = '' if not handler.drop_str: do_add(StringHandler(None), '%s_str' % (varname), ' __attribute__ ((unused))') @@ -229,6 +249,8 @@ def process_file(fn, ofd, dumpfd, all_defun): params['argdecls'] = ''.join(argdecls) params['arglist'] = ''.join(arglist) params['argblocks'] = ''.join(argblocks) + params['canfail'] = canfail + params['nonempty'] = len(argblocks) ofd.write(templ.substitute(params)) if __name__ == '__main__': From 8295b504cbd6df715b779287ff9d2374ae306421 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Fri, 25 Aug 2017 13:39:13 -0400 Subject: [PATCH 72/79] lib: fix rare bug in ambiguous command resolution In certain situations, the CLI matcher would not handle ambiguous commands properly. If it found an ambiguous result in a lower subgraph, the ambiguous result would not correctly propagate up to previous frames in the resolution DFS as ambiguous; instead it would propagate up as a non-match, which could subsequently be overridden by a partial match. Example CLI space: show ip route summary show ip route supernet-only show ipv6 route summary Entering `show ip route su` would result in an ambiguous resolution for the `show ip route` subgraph but would propagate up to the `show ip` subgraph as a no-match, allowing `ip` to partial-match `ipv6` and execute that command. In this example entering `show ip route summary` would disambiguate the `show ip` subgraph. So this bug would only appear when entering input that caused ambiguities in at least two parallel subgraphs. Signed-off-by: Quentin Young --- lib/command_match.c | 130 ++++++++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 58 deletions(-) diff --git a/lib/command_match.c b/lib/command_match.c index f07448d716..5590fce6b1 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -46,8 +46,9 @@ DEFINE_MTYPE_STATIC(LIB, CMD_MATCHSTACK, "Command Match Stack") static int add_nexthops(struct list *, struct graph_node *, struct graph_node **, size_t); -static struct list *command_match_r(struct graph_node *, vector, unsigned int, - struct graph_node **); +static enum matcher_rv command_match_r(struct graph_node *, vector, + unsigned int, struct graph_node **, + struct list **); static int score_precedence(enum cmd_token_type); @@ -87,7 +88,8 @@ enum matcher_rv command_match(struct graph *cmdgraph, vector vline, struct list **argv, const struct cmd_element **el) { struct graph_node *stack[MAXDEPTH]; - matcher_rv = MATCHER_NO_MATCH; + enum matcher_rv status; + *argv = NULL; // prepend a dummy token to match that pesky start node vector vvline = vector_init(vline->alloced + 1); @@ -97,9 +99,8 @@ enum matcher_rv command_match(struct graph *cmdgraph, vector vline, vvline->active = vline->active + 1; struct graph_node *start = vector_slot(cmdgraph->nodes, 0); - if ((*argv = command_match_r(start, vvline, 0, - stack))) // successful match - { + status = command_match_r(start, vvline, 0, stack, argv); + if (status == MATCHER_OK) { // successful match struct listnode *head = listhead(*argv); struct listnode *tail = listtail(*argv); @@ -115,6 +116,9 @@ enum matcher_rv command_match(struct graph *cmdgraph, vector vline, // input, with each cmd_token->arg holding the corresponding // input assert(*el); + } else if (*argv) { + del_arglist(*argv); + *argv = NULL; } if (!*el) { @@ -129,7 +133,7 @@ enum matcher_rv command_match(struct graph *cmdgraph, vector vline, // free vector vector_free(vvline); - return matcher_rv; + return status; } /** @@ -183,11 +187,15 @@ enum matcher_rv command_match(struct graph *cmdgraph, vector vline, * * If no match was found, the return value is NULL. */ -static struct list *command_match_r(struct graph_node *start, vector vline, - unsigned int n, struct graph_node **stack) +static enum matcher_rv command_match_r(struct graph_node *start, vector vline, + unsigned int n, + struct graph_node **stack, + struct list **currbest) { assert(n < vector_active(vline)); + enum matcher_rv status = MATCHER_NO_MATCH; + // get the minimum match level that can count as a full match struct cmd_token *token = start->data; enum match_type minmatch = min_match_level(token->type); @@ -196,11 +204,11 @@ static struct list *command_match_r(struct graph_node *start, vector vline, * this disallows matching the same one more than once if there is a * circle in the graph (used for keyword arguments) */ if (n == MAXDEPTH) - return NULL; + return MATCHER_NO_MATCH; if (!token->allowrepeat) for (size_t s = 0; s < n; s++) if (stack[s] == start) - return NULL; + return MATCHER_NO_MATCH; // get the current operating input token char *input_token = vector_slot(vline, n); @@ -231,7 +239,7 @@ static struct list *command_match_r(struct graph_node *start, vector vline, // if we don't match this node, die if (match_token(token, input_token) < minmatch) - return NULL; + return MATCHER_NO_MATCH; stack[n] = start; @@ -244,86 +252,92 @@ static struct list *command_match_r(struct graph_node *start, vector vline, add_nexthops(next, start, NULL, 0); // determine the best match - int ambiguous = 0; - struct list *currbest = NULL; for (ALL_LIST_ELEMENTS_RO(next, ln, gn)) { // if we've matched all input we're looking for END_TKN if (n + 1 == vector_active(vline)) { struct cmd_token *tok = gn->data; if (tok->type == END_TKN) { - if (currbest) // there is more than one END_TKN - // in the follow set - { - ambiguous = 1; + // if more than one END_TKN in the follow set + if (*currbest) { + status = MATCHER_AMBIGUOUS; break; + } else { + status = MATCHER_OK; } - currbest = list_new(); + *currbest = list_new(); // node should have one child node with the // element struct graph_node *leaf = vector_slot(gn->to, 0); // last node in the list will hold the - // cmd_element; - // this is important because list_delete() - // expects - // that all nodes have the same data type, so - // when - // deleting this list the last node must be - // manually deleted + // cmd_element; this is important because + // list_delete() expects that all nodes have + // the same data type, so when deleting this + // list the last node must be manually deleted struct cmd_element *el = leaf->data; - listnode_add(currbest, el); - currbest->del = + listnode_add(*currbest, el); + (*currbest)->del = (void (*)(void *)) & cmd_token_del; // do not break immediately; continue walking - // through the follow set - // to ensure that there is exactly one END_TKN + // through the follow set to ensure that there + // is exactly one END_TKN } continue; } // else recurse on candidate child node - struct list *result = command_match_r(gn, vline, n + 1, stack); + struct list *result = NULL; + enum matcher_rv rstat = + command_match_r(gn, vline, n + 1, stack, &result); // save the best match - if (result && currbest) { + if (result && *currbest) { // pick the best of two matches struct list *newbest = - disambiguate(currbest, result, vline, n + 1); - // set ambiguity flag - ambiguous = - !newbest || (ambiguous && newbest == currbest); + disambiguate(*currbest, result, vline, n + 1); + + // current best and result are ambiguous + if (!newbest) + status = MATCHER_AMBIGUOUS; + // current best is still the best, but ambiguous + else if (newbest == *currbest + && status == MATCHER_AMBIGUOUS) + status = MATCHER_AMBIGUOUS; + // result is better, but also ambiguous + else if (newbest == result + && rstat == MATCHER_AMBIGUOUS) + status = MATCHER_AMBIGUOUS; + // one or the other is superior and not ambiguous + else + status = MATCHER_OK; + // delete the unnecessary result struct list *todelete = - ((newbest && newbest == result) ? currbest + ((newbest && newbest == result) ? *currbest : result); del_arglist(todelete); - currbest = newbest ? newbest : currbest; - } else if (result) - currbest = result; - } - - if (currbest) { - if (ambiguous) { - del_arglist(currbest); - currbest = NULL; - matcher_rv = MATCHER_AMBIGUOUS; - } else { - // copy token, set arg and prepend to currbest - struct cmd_token *token = start->data; - struct cmd_token *copy = cmd_token_dup(token); - copy->arg = XSTRDUP(MTYPE_CMD_ARG, input_token); - listnode_add_before(currbest, currbest->head, copy); - matcher_rv = MATCHER_OK; + *currbest = newbest ? newbest : *currbest; + } else if (result) { + status = rstat; + *currbest = result; + } else if (!*currbest) { + status = MAX(rstat, status); } - } else if (n + 1 == vector_active(vline) - && matcher_rv == MATCHER_NO_MATCH) - matcher_rv = MATCHER_INCOMPLETE; + } + if (*currbest) { + // copy token, set arg and prepend to currbest + struct cmd_token *token = start->data; + struct cmd_token *copy = cmd_token_dup(token); + copy->arg = XSTRDUP(MTYPE_CMD_ARG, input_token); + listnode_add_before(*currbest, (*currbest)->head, copy); + } else if (n + 1 == vector_active(vline) && status == MATCHER_NO_MATCH) + status = MATCHER_INCOMPLETE; // cleanup list_delete(next); - return currbest; + return status; } static void stack_del(void *val) From 935cee3f9b84903b821c8abc17b70cbda08cb145 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Fri, 25 Aug 2017 14:08:16 -0400 Subject: [PATCH 73/79] lib: remove static variable from cli matcher Signed-off-by: Quentin Young --- lib/command_match.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/command_match.c b/lib/command_match.c index 5590fce6b1..ad3ec2492e 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -81,9 +81,6 @@ static enum match_type match_variable(struct cmd_token *, const char *); static enum match_type match_mac(const char *, bool); -/* matching functions */ -static enum matcher_rv matcher_rv; - enum matcher_rv command_match(struct graph *cmdgraph, vector vline, struct list **argv, const struct cmd_element **el) { @@ -446,12 +443,12 @@ enum matcher_rv command_complete(struct graph *graph, vector vline, * next = set of all nodes reachable from all nodes in `matched` */ - matcher_rv = idx == vector_active(vline) && next->count - ? MATCHER_OK - : MATCHER_NO_MATCH; + enum matcher_rv mrv = idx == vector_active(vline) && next->count + ? MATCHER_OK + : MATCHER_NO_MATCH; *completions = NULL; - if (!MATCHER_ERROR(matcher_rv)) { + if (!MATCHER_ERROR(mrv)) { // extract cmd_token into list *completions = list_new(); for (ALL_LIST_ELEMENTS_RO(next, node, gstack)) { @@ -462,7 +459,7 @@ enum matcher_rv command_complete(struct graph *graph, vector vline, list_delete(current); list_delete(next); - return matcher_rv; + return mrv; } /** From a97986ffba560458b2b1e88b09b31822f78d8542 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sat, 26 Aug 2017 01:14:25 +0200 Subject: [PATCH 74/79] *: fix compiler warnings Specifically, gcc 4.2.1 on OpenBSD 6.0 warns about these; they're bogus (gcc 4.2, being rather old, isn't quite as "intelligent" as newer versions; the newer ones apply more logic and less warnings.) Signed-off-by: David Lamparter --- babeld/babeld.c | 4 +-- babeld/message.c | 2 +- isisd/isisd.c | 4 +-- lib/module.c | 6 ++-- lib/spf_backoff.c | 10 +++--- lib/termtable.c | 88 +++++++++++++++++++++++++++-------------------- pimd/pim_join.c | 2 +- zebra/zserv.c | 2 +- 8 files changed, 67 insertions(+), 51 deletions(-) diff --git a/babeld/babeld.c b/babeld/babeld.c index f995745e41..207c37d9b1 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -331,8 +331,8 @@ babel_main_loop(struct thread *thread) /* if there is no timeout, we must wait. */ if(timeval_compare(&tv, &babel_now) > 0) { timeval_minus(&tv, &tv, &babel_now); - debugf(BABEL_DEBUG_TIMEOUT, "babel main loop : timeout: %ld msecs", - tv.tv_sec * 1000 + tv.tv_usec / 1000); + debugf(BABEL_DEBUG_TIMEOUT, "babel main loop : timeout: %lld msecs", + (long long)tv.tv_sec * 1000 + tv.tv_usec / 1000); /* it happens often to have less than 1 ms, it's bad. */ timeval_add_msec(&tv, &tv, 300); babel_set_timer(&tv); diff --git a/babeld/message.c b/babeld/message.c index 5990373b69..e31d5de5df 100644 --- a/babeld/message.c +++ b/babeld/message.c @@ -391,7 +391,7 @@ parse_packet(const unsigned char *from, struct interface *ifp, } else if(type == MESSAGE_HELLO) { unsigned short seqno, interval; int changed; - unsigned int timestamp; + unsigned int timestamp = 0; DO_NTOHS(seqno, message + 4); DO_NTOHS(interval, message + 6); debugf(BABEL_DEBUG_COMMON,"Received hello %d (%d) from %s on %s.", diff --git a/isisd/isisd.c b/isisd/isisd.c index f8a9df45c7..3d39a1ed52 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -1260,8 +1260,8 @@ DEFUN (show_isis_spf_ietf, if (area->spf_timer[level - 1]) { struct timeval remain = thread_timer_remain( area->spf_timer[level - 1]); - vty_out(vty, "Pending, due in %ld msec\n", - remain.tv_sec * 1000 + vty_out(vty, "Pending, due in %lld msec\n", + (long long)remain.tv_sec * 1000 + remain.tv_usec / 1000); } else { vty_out(vty, "Not scheduled\n"); diff --git a/lib/module.c b/lib/module.c index beef791093..b3ab91c4ea 100644 --- a/lib/module.c +++ b/lib/module.c @@ -42,8 +42,10 @@ static struct frrmod_info frrmod_default_info = { .description = "libfrr core module", }; union _frrmod_runtime_u frrmod_default = { - .r.info = &frrmod_default_info, - .r.finished_loading = 1, + .r = { + .info = &frrmod_default_info, + .finished_loading = 1, + }, }; // if defined(HAVE_SYS_WEAK_ALIAS_ATTRIBUTE) diff --git a/lib/spf_backoff.c b/lib/spf_backoff.c index d075e70d4e..92b7620eda 100644 --- a/lib/spf_backoff.c +++ b/lib/spf_backoff.c @@ -226,8 +226,9 @@ void spf_backoff_show(struct spf_backoff *backoff, struct vty *vty, if (backoff->t_holddown) { struct timeval remain = thread_timer_remain(backoff->t_holddown); - vty_out(vty, "%s Still runs for %ld msec\n", - prefix, remain.tv_sec * 1000 + remain.tv_usec / 1000); + vty_out(vty, "%s Still runs for %lld msec\n", + prefix, (long long)remain.tv_sec * 1000 + + remain.tv_usec / 1000); } else { vty_out(vty, "%s Inactive\n", prefix); } @@ -237,8 +238,9 @@ void spf_backoff_show(struct spf_backoff *backoff, struct vty *vty, if (backoff->t_timetolearn) { struct timeval remain = thread_timer_remain(backoff->t_timetolearn); - vty_out(vty, "%s Still runs for %ld msec\n", - prefix, remain.tv_sec * 1000 + remain.tv_usec / 1000); + vty_out(vty, "%s Still runs for %lld msec\n", + prefix, (long long)remain.tv_sec * 1000 + + remain.tv_usec / 1000); } else { vty_out(vty, "%s Inactive\n", prefix); } diff --git a/lib/termtable.c b/lib/termtable.c index f7aec43118..ba85962cc9 100644 --- a/lib/termtable.c +++ b/lib/termtable.c @@ -31,48 +31,60 @@ struct ttable_style ttable_styles[] = { .corner = '+', .rownums_on = false, .indent = 1, - .border.top = '-', - .border.bottom = '-', - .border.left = '|', - .border.right = '|', - .border.top_on = true, - .border.bottom_on = true, - .border.left_on = true, - .border.right_on = true, - .cell.lpad = 1, - .cell.rpad = 1, - .cell.align = LEFT, - .cell.border.bottom = '-', - .cell.border.bottom_on = true, - .cell.border.top = '-', - .cell.border.top_on = false, - .cell.border.right = '|', - .cell.border.right_on = true, - .cell.border.left = '|', - .cell.border.left_on = false, + .border = { + .top = '-', + .bottom = '-', + .left = '|', + .right = '|', + .top_on = true, + .bottom_on = true, + .left_on = true, + .right_on = true, + }, + .cell = { + .lpad = 1, + .rpad = 1, + .align = LEFT, + .border = { + .bottom = '-', + .bottom_on = true, + .top = '-', + .top_on = false, + .right = '|', + .right_on = true, + .left = '|', + .left_on = false, + }, + }, }, { // blank, suitable for plaintext alignment .corner = ' ', .rownums_on = false, .indent = 1, - .border.top = ' ', - .border.bottom = ' ', - .border.left = ' ', - .border.right = ' ', - .border.top_on = false, - .border.bottom_on = false, - .border.left_on = false, - .border.right_on = false, - .cell.lpad = 0, - .cell.rpad = 3, - .cell.align = LEFT, - .cell.border.bottom = ' ', - .cell.border.bottom_on = false, - .cell.border.top = ' ', - .cell.border.top_on = false, - .cell.border.right = ' ', - .cell.border.right_on = false, - .cell.border.left = ' ', - .cell.border.left_on = false, + .border = { + .top = ' ', + .bottom = ' ', + .left = ' ', + .right = ' ', + .top_on = false, + .bottom_on = false, + .left_on = false, + .right_on = false, + }, + .cell = { + .lpad = 0, + .rpad = 3, + .align = LEFT, + .border = { + .bottom = ' ', + .bottom_on = false, + .top = ' ', + .top_on = false, + .right = ' ', + .right_on = false, + .left = ' ', + .left_on = false, + }, + } } }; /* clang-format on */ diff --git a/pimd/pim_join.c b/pimd/pim_join.c index 9d65330e5f..4f5e534010 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -414,7 +414,7 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups) struct pim_jp_agg_group *group; struct pim_interface *pim_ifp = NULL; struct pim_jp_groups *grp = NULL; - struct pim_jp *msg; + struct pim_jp *msg = NULL; struct listnode *node, *nnode; uint8_t pim_msg[10000]; uint8_t *curr_ptr = pim_msg; diff --git a/zebra/zserv.c b/zebra/zserv.c index 7899a8375c..0e0cc78bbe 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1198,7 +1198,7 @@ static int zread_ipv4_add(struct zserv *client, u_short length, ifindex_t ifindex; safi_t safi; int ret; - enum lsp_types_t label_type; + enum lsp_types_t label_type = ZEBRA_LSP_NONE; mpls_label_t label; struct nexthop *nexthop; From 8c9cc7bbf657e3440d9bc758fe45aef5f43c989f Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sat, 26 Aug 2017 01:27:22 +0200 Subject: [PATCH 75/79] bgpd: encap: fix extension sizing Variably-sized struct tails are done as [0], not [1]. The latter triggers compiler warnings and mis-sizes "sizeof(struct) + n" expressions. Signed-off-by: David Lamparter --- bgpd/bgp_attr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index 324813c085..4dd38459f8 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -72,7 +72,7 @@ struct bgp_attr_encap_subtlv { unsigned long refcnt; uint16_t type; uint16_t length; - uint8_t value[1]; /* will be extended */ + uint8_t value[0]; /* will be extended */ }; #if ENABLE_BGP_VNC From d440e3dbf0180e63e461a5c2ec908d1c71327cad Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sat, 26 Aug 2017 01:38:10 +0200 Subject: [PATCH 76/79] lib: prefix: fix char value size There are 16 bytes here, not 8. Signed-off-by: David Lamparter --- lib/prefix.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/prefix.h b/lib/prefix.h index eab4ac2bb7..a27f46ba0a 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -125,7 +125,7 @@ struct prefix { struct in_addr adv_router; } lp; struct ethaddr prefix_eth; /* AF_ETHERNET */ - u_char val[8]; + u_char val[16]; uintptr_t ptr; struct evpn_addr prefix_evpn; /* AF_EVPN */ } u __attribute__((aligned(8))); From adf580f72af5885ce25cb0df44d9e5676dfc0214 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sat, 26 Aug 2017 01:41:07 +0200 Subject: [PATCH 77/79] zebra: remove RT_ROUNDUP warning This warning is at odds with how the world works. Also, the code is correct on all platforms we care about. Signed-off-by: David Lamparter --- zebra/kernel_socket.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 84d01bca6f..e2a1deb9ac 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -88,13 +88,10 @@ extern struct zebra_privs_t zserv_privs; #if !defined(ROUNDUP) /* - * It's a bug for a platform not to define rounding/alignment for - * sockaddrs on the routing socket. This warning really is - * intentional, to provoke filing bug reports with operating systems - * that don't define RT_ROUNDUP or equivalent. + * If you're porting to a platform that changed RT_ROUNDUP but doesn't + * have it in its headers, this will break rather obviously and you'll + * have to fix it here. */ -#warning \ - "net/route.h does not define RT_ROUNDUP; making unwarranted assumptions!" /* OS X (Xcode as of 2014-12) is known not to define RT_ROUNDUP */ #ifdef __APPLE__ From d9e5b009554f99230be1eee62daf098403c3cadf Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sat, 26 Aug 2017 01:52:12 +0200 Subject: [PATCH 78/79] isisd: bpf: ETHER_HDR_LEN -> ETH_ALEN Signed-off-by: David Lamparter --- isisd/isis_bpf.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/isisd/isis_bpf.c b/isisd/isis_bpf.c index 98f612f827..2c8b126088 100644 --- a/isisd/isis_bpf.c +++ b/isisd/isis_bpf.c @@ -48,14 +48,15 @@ extern struct zebra_privs_t isisd_privs; struct bpf_insn llcfilter[] = { - BPF_STMT(BPF_LD + BPF_B + BPF_ABS, - ETHER_HDR_LEN), /* check first byte */ + /* check first byte */ + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, ETH_ALEN), BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, 5), - BPF_STMT(BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 1), - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, - 3), /* check second byte */ - BPF_STMT(BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 2), - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x03, 0, 1), /* check third byte */ + /* check second byte */ + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, ETH_ALEN + 1), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, 3), + /* check third byte */ + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, ETH_ALEN + 2), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x03, 0, 1), BPF_STMT(BPF_RET + BPF_K, (u_int)-1), BPF_STMT(BPF_RET + BPF_K, 0)}; u_int readblen = 0; @@ -243,15 +244,14 @@ int isis_recv_pdu_bcast(struct isis_circuit *circuit, u_char *ssnpa) assert(bpf_hdr->bh_caplen == bpf_hdr->bh_datalen); - offset = bpf_hdr->bh_hdrlen + LLC_LEN + ETHER_HDR_LEN; + offset = bpf_hdr->bh_hdrlen + LLC_LEN + ETH_ALEN; /* then we lose the BPF, LLC and ethernet headers */ stream_write(circuit->rcv_stream, readbuff + offset, - bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN); + bpf_hdr->bh_caplen - LLC_LEN - ETH_ALEN); stream_set_getp(circuit->rcv_stream, 0); - memcpy(ssnpa, readbuff + bpf_hdr->bh_hdrlen + ETH_ALEN, - ETH_ALEN); + memcpy(ssnpa, readbuff + bpf_hdr->bh_hdrlen + ETH_ALEN, ETH_ALEN); if (ioctl(circuit->fd, BIOCFLUSH, &one) < 0) zlog_warn("Flushing failed: %s", safe_strerror(errno)); @@ -265,7 +265,7 @@ int isis_send_pdu_bcast(struct isis_circuit *circuit, int level) ssize_t written; size_t buflen; - buflen = stream_get_endp(circuit->snd_stream) + LLC_LEN + ETHER_HDR_LEN; + buflen = stream_get_endp(circuit->snd_stream) + LLC_LEN + ETH_ALEN; if (buflen > sizeof(sock_buff)) { zlog_warn( "isis_send_pdu_bcast: sock_buff size %zu is less than " @@ -291,12 +291,12 @@ int isis_send_pdu_bcast(struct isis_circuit *circuit, int level) /* * Then the LLC */ - sock_buff[ETHER_HDR_LEN] = ISO_SAP; - sock_buff[ETHER_HDR_LEN + 1] = ISO_SAP; - sock_buff[ETHER_HDR_LEN + 2] = 0x03; + sock_buff[ETH_ALEN] = ISO_SAP; + sock_buff[ETH_ALEN + 1] = ISO_SAP; + sock_buff[ETH_ALEN + 2] = 0x03; /* then we copy the data */ - memcpy(sock_buff + (LLC_LEN + ETHER_HDR_LEN), circuit->snd_stream->data, + memcpy(sock_buff + (LLC_LEN + ETH_ALEN), circuit->snd_stream->data, stream_get_endp(circuit->snd_stream)); /* now we can send this */ From cd6c573c697897dd73fb4bffeb176940af4582c2 Mon Sep 17 00:00:00 2001 From: Don Slice Date: Sat, 26 Aug 2017 15:51:43 -0400 Subject: [PATCH 79/79] eigrpd: add correct interface metrics when interface comes up Problem noticed where we were not sending the correct metric values to our peers for connected interfaces. Found that we were not storing these values on the structure used to send the update packets. Signed-off-by: Don Slice --- eigrpd/eigrp_interface.c | 1 + 1 file changed, 1 insertion(+) diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index ae9ec293ce..aa59516002 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -307,6 +307,7 @@ int eigrp_if_up(struct eigrp_interface *ei) pe->nt = EIGRP_TOPOLOGY_TYPE_CONNECTED; ne->prefix = pe; + pe->reported_metric = metric; pe->state = EIGRP_FSM_STATE_PASSIVE; pe->fdistance = eigrp_calculate_metrics(eigrp, metric); pe->req_action |= EIGRP_FSM_NEED_UPDATE;