From: Renato Westphal Date: Thu, 14 Feb 2019 22:00:15 +0000 (-0200) Subject: pbrd: change the "set nexthop" command to accept interface nexthops X-Git-Tag: 7.1_pulled~154^2~1 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=9c0fd85360422b79e75e6ee5eeb1df5a9439e952;p=matthieu%2Ffrr.git 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 --- 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; }