From 9c0fd85360422b79e75e6ee5eeb1df5a9439e952 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Thu, 14 Feb 2019 20:00:15 -0200 Subject: [PATCH] pbrd: change the "set nexthop" command to accept interface nexthops In addition to nexthop groups, pbrd also supports the "set nexthop" command to specify the nexthop of a PBR map. This adds convenience when multiple nexthops aren't necessary. Change this command to support interface nexthops (without IP addresses) like nexthop groups do. At the end of the command, call pbr_nht_nexthop_interface_update() otherwise the interface nexthop won't be validated until we receive an interface up/down notification from zebra through the zapi protocol. Signed-off-by: Renato Westphal --- pbrd/pbr_vty.c | 80 +++++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c index a4b87f99d9..0aedb98476 100644 --- a/pbrd/pbr_vty.c +++ b/pbrd/pbr_vty.c @@ -221,13 +221,19 @@ DEFPY(pbr_map_nexthop_group, pbr_map_nexthop_group_cmd, } DEFPY(pbr_map_nexthop, pbr_map_nexthop_cmd, - "[no] set nexthop $addr [INTERFACE]$intf [nexthop-vrf NAME$name]", + "[no] set nexthop\ + <\ + $addr [INTERFACE$intf]\ + |INTERFACE$intf\ + >\ + [nexthop-vrf NAME$name]", NO_STR "Set for the PBR-MAP\n" "Specify one of the nexthops in this map\n" "v4 Address\n" "v6 Address\n" "Interface to use\n" + "Interface to use\n" "If the nexthop is in a different vrf tell us\n" "The nexthop-vrf Name\n") { @@ -255,44 +261,38 @@ DEFPY(pbr_map_nexthop, pbr_map_nexthop_cmd, memset(&nhop, 0, sizeof(nhop)); nhop.vrf_id = vrf->vrf_id; - /* - * Make SA happy. CLIPPY is not going to give us a NULL - * addr. - */ - assert(addr); - if (addr->sa.sa_family == AF_INET) { - nhop.gate.ipv4.s_addr = addr->sin.sin_addr.s_addr; - if (intf) { - nhop.type = NEXTHOP_TYPE_IPV4_IFINDEX; - nhop.ifindex = ifname2ifindex(intf, vrf->vrf_id); - if (nhop.ifindex == IFINDEX_INTERNAL) { - vty_out(vty, - "Specified Intf %s does not exist in vrf: %s\n", - intf, vrf->name); - return CMD_WARNING_CONFIG_FAILED; - } - } else - nhop.type = NEXTHOP_TYPE_IPV4; - } else { - memcpy(&nhop.gate.ipv6, &addr->sin6.sin6_addr, 16); - if (intf) { - nhop.type = NEXTHOP_TYPE_IPV6_IFINDEX; - nhop.ifindex = ifname2ifindex(intf, vrf->vrf_id); - if (nhop.ifindex == IFINDEX_INTERNAL) { - vty_out(vty, - "Specified Intf %s does not exist in vrf: %s\n", - intf, vrf->name); - return CMD_WARNING_CONFIG_FAILED; - } + if (intf) { + nhop.ifindex = ifname2ifindex(intf, vrf->vrf_id); + if (nhop.ifindex == IFINDEX_INTERNAL) { + vty_out(vty, + "Specified Intf %s does not exist in vrf: %s\n", + intf, vrf->name); + return CMD_WARNING_CONFIG_FAILED; + } + } + + if (addr) { + if (addr->sa.sa_family == AF_INET) { + nhop.gate.ipv4.s_addr = addr->sin.sin_addr.s_addr; + if (intf) + nhop.type = NEXTHOP_TYPE_IPV4_IFINDEX; + else + nhop.type = NEXTHOP_TYPE_IPV4; } else { - if (IN6_IS_ADDR_LINKLOCAL(&nhop.gate.ipv6)) { - vty_out(vty, - "Specified a v6 LL with no interface, rejecting\n"); - return CMD_WARNING_CONFIG_FAILED; + nhop.gate.ipv6 = addr->sin6.sin6_addr; + if (intf) + nhop.type = NEXTHOP_TYPE_IPV6_IFINDEX; + else { + if (IN6_IS_ADDR_LINKLOCAL(&nhop.gate.ipv6)) { + vty_out(vty, + "Specified a v6 LL with no interface, rejecting\n"); + return CMD_WARNING_CONFIG_FAILED; + } + nhop.type = NEXTHOP_TYPE_IPV6; } - nhop.type = NEXTHOP_TYPE_IPV6; } - } + } else + nhop.type = NEXTHOP_TYPE_IFINDEX; if (pbrms->nhg) nh = nexthop_exists(pbrms->nhg, &nhop); @@ -335,6 +335,14 @@ DEFPY(pbr_map_nexthop, pbr_map_nexthop_cmd, pbr_map_check(pbrms); } + if (nhop.type == NEXTHOP_TYPE_IFINDEX) { + struct interface *ifp; + + ifp = if_lookup_by_index(nhop.ifindex, nhop.vrf_id); + if (ifp) + pbr_nht_nexthop_interface_update(ifp); + } + return CMD_SUCCESS; } -- 2.39.5