]> git.puffer.fish Git - mirror/frr.git/commitdiff
pbrd: change the "set nexthop" command to accept interface nexthops
authorRenato Westphal <renato@opensourcerouting.org>
Thu, 14 Feb 2019 22:00:15 +0000 (20:00 -0200)
committerRenato Westphal <renato@opensourcerouting.org>
Fri, 15 Feb 2019 00:57:39 +0000 (22:57 -0200)
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 <renato@opensourcerouting.org>
pbrd/pbr_vty.c

index a4b87f99d9d0e2b8eecb6151f52a8ac5fafd3ed0..0aedb98476da355db3c42c76ea93b1229d630657 100644 (file)
@@ -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 <A.B.C.D|X:X::X:X>$addr [INTERFACE]$intf [nexthop-vrf NAME$name]",
+      "[no] set nexthop\
+        <\
+         <A.B.C.D|X:X::X:X>$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;
 }