]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: receive ZAPI IPv6 source prefix
authorDavid Lamparter <equinox@opensourcerouting.org>
Thu, 24 Apr 2014 15:41:43 +0000 (17:41 +0200)
committerChristian Franke <chris@opensourcerouting.org>
Mon, 30 Jan 2017 12:47:04 +0000 (13:47 +0100)
Check and read the IPv6 source prefix on ZAPI messages, and pass it down
to the RIB functions (which do nothing with it yet.)  Since the RIB
functions now all have a new extra argument, this also updates the
kernel route read functions to supply NULL.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
lib/zclient.h
zebra/connected.c
zebra/kernel_socket.c
zebra/redistribute.c
zebra/rib.h
zebra/rt_netlink.c
zebra/rtread_getmsg.c
zebra/zebra_rib.c
zebra/zserv.c

index ccb7b0509d3ca94c1b10bf1f242161d7954e1506..7808fd804f73e5150d8abd7671d83b5f219f6a56 100644 (file)
@@ -114,6 +114,7 @@ struct zclient
 #define ZAPI_MESSAGE_METRIC   0x08
 #define ZAPI_MESSAGE_TAG      0x10
 #define ZAPI_MESSAGE_MTU      0x20
+#define ZAPI_MESSAGE_SRCPFX   0x40
 
 /* Zserv protocol message header */
 struct zserv_header
index ebd948252e4ff3d99ace4a20531c6e7ca10742e2..0ceaddc8e360eef8dce2a91bf81b61bd1248249b 100644 (file)
@@ -201,11 +201,11 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
     return;
 
   rib_add (AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
-          0, 0, &p, NULL, NULL, ifp->ifindex,
+          0, 0, &p, NULL, NULL, NULL, ifp->ifindex,
           RT_TABLE_MAIN, ifp->metric, 0, 0);
 
   rib_add (AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
-          0, 0, &p, NULL, NULL, ifp->ifindex,
+          0, 0, &p, NULL, NULL, NULL, ifp->ifindex,
           RT_TABLE_MAIN, ifp->metric, 0, 0);
 
   if (IS_ZEBRA_DEBUG_RIB_DETAILED)
@@ -331,10 +331,10 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
 
   /* Same logic as for connected_up_ipv4(): push the changes into the head. */
   rib_delete (AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
-             0, 0, &p, NULL, ifp->ifindex, 0);
+             0, 0, &p, NULL, NULL, ifp->ifindex, 0);
 
   rib_delete (AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
-             0, 0, &p, NULL, ifp->ifindex, 0);
+             0, 0, &p, NULL, NULL, ifp->ifindex, 0);
 
   if (IS_ZEBRA_DEBUG_RIB_DETAILED)
     zlog_debug ("%u: IF %s IPv4 address down, scheduling RIB processing",
@@ -407,7 +407,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
 #endif
 
   rib_add (AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
-          0, 0, &p, NULL, NULL, ifp->ifindex,
+          0, 0, &p, NULL, NULL, NULL, ifp->ifindex,
           RT_TABLE_MAIN, ifp->metric, 0, 0);
 
   if (IS_ZEBRA_DEBUG_RIB_DETAILED)
@@ -507,7 +507,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
     return;
 
   rib_delete (AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
-             0, 0, &p, NULL, ifp->ifindex, 0);
+             0, 0, &p, NULL, NULL, ifp->ifindex, 0);
 
   if (IS_ZEBRA_DEBUG_RIB_DETAILED)
     zlog_debug ("%u: IF %s IPv6 address down, scheduling RIB processing",
index fd059dfee791f9f1f4a1901530c39546f18128d7..20a0472195acf3f688b7dfe0c19c305bb5204666 100644 (file)
@@ -992,17 +992,17 @@ rtm_read (struct rt_msghdr *rtm)
        */
       if (rtm->rtm_type == RTM_CHANGE)
         rib_delete (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
-                   0, zebra_flags, &p, NULL, 0, 0);
+                   0, zebra_flags, &p, NULL, NULL, 0, 0);
       
       union g_addr ggate = { .ipv4 = gate.sin.sin_addr };
       if (rtm->rtm_type == RTM_GET 
           || rtm->rtm_type == RTM_ADD
           || rtm->rtm_type == RTM_CHANGE)
        rib_add (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
-                &p, &ggate, NULL, 0, 0, 0, 0, 0);
+                &p, NULL, &ggate, NULL, 0, 0, 0, 0, 0);
       else
        rib_delete (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
-                   0, zebra_flags, &p, &ggate, 0, 0);
+                   0, zebra_flags, &p, NULL, &ggate, 0, 0);
     }
   if (dest.sa.sa_family == AF_INET6)
     {
@@ -1034,18 +1034,18 @@ rtm_read (struct rt_msghdr *rtm)
        */
       if (rtm->rtm_type == RTM_CHANGE)
         rib_delete (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
-                   0, zebra_flags, &p, NULL, 0, 0);
+                   0, zebra_flags, &p, NULL, NULL, 0, 0);
 
       union g_addr ggate = { .ipv6 = gate.sin6.sin6_addr };
       if (rtm->rtm_type == RTM_GET 
           || rtm->rtm_type == RTM_ADD
           || rtm->rtm_type == RTM_CHANGE)
        rib_add (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
-                0, zebra_flags, &p, &ggate, NULL, ifindex,
+                0, zebra_flags, &p, NULL, &ggate, NULL, ifindex,
                 0, 0, 0, 0);
       else
        rib_delete (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
-                   0, zebra_flags, &p, &ggate, ifindex, 0);
+                   0, zebra_flags, &p, NULL, &ggate, ifindex, 0);
     }
 }
 
index 4b2aabd18615bb94c782365e854e2e704112228e..435122cfe704b440519a4343c6d9365a0c02b3bf 100644 (file)
@@ -519,7 +519,7 @@ zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char
                gate = (union g_addr *)&nhop->gate.ipv4;
 
              rib_add (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE,
-                      rib->table, 0, &p, gate, (union g_addr *)&nhop->src.ipv4,
+                      rib->table, 0, &p, NULL, gate, (union g_addr *)&nhop->src.ipv4,
                       nhop->ifindex, zebrad.rtm_table_default,
                       rib->metric, rib->mtu,
                       zebra_import_table_distance[AFI_IP][rib->table]);
@@ -541,7 +541,7 @@ zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char
              for (nhop = rib->nexthop; nhop; nhop = nhop->next)
                rib_copy_nexthops(newrib, nhop);
 
-             rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, newrib);
+             rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, NULL, newrib);
            }
         }
     }
@@ -565,7 +565,7 @@ zebra_del_import_table_entry (struct route_node *rn, struct rib *rib)
       p.u.prefix4 = rn->p.u.prefix4;
 
       rib_delete (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE,
-                 rib->table, rib->flags, &p, NULL,
+                 rib->table, rib->flags, &p, NULL, NULL,
                  0, zebrad.rtm_table_default);
     }
   /* DD: Add IPv6 code */
index d80ea6cbd86503a84b62c907294230ea117cbc47..fceab93d1a2d1165ef4d1a426aa244847f3d756b 100644 (file)
@@ -342,17 +342,17 @@ extern int rib_uninstall_kernel (struct route_node *rn, struct rib *rib);
  * also implicitly withdraw equal prefix of same type. */
 extern int rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                    u_short instance, int flags, struct prefix *p,
-                   union g_addr *gate, union g_addr *src,
+                   struct prefix_ipv6 *src_p, union g_addr *gate, union g_addr *src,
                    ifindex_t ifindex, u_int32_t table_id,
                    u_int32_t, u_int32_t, u_char);
 
 extern int rib_add_multipath (afi_t afi, safi_t safi, struct prefix *,
-                             struct rib *);
+                             struct prefix_ipv6 *src_p, struct rib *);
 
 extern int rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                       u_short instance, int flags, struct prefix *p,
-                      union g_addr *gate, ifindex_t ifindex,
-                      u_int32_t table_id);
+                      struct prefix_ipv6 *src_p, union g_addr *gate,
+                      ifindex_t ifindex, u_int32_t table_id);
 
 extern struct rib *rib_match (afi_t afi, safi_t safi, vrf_id_t, union g_addr *,
                              struct route_node **rn_out);
index d2781f4c4e60a709eace23d364007b999ceae51c..585b80f9794efad099e519ccaa9f5200f6ef8a03 100644 (file)
@@ -238,7 +238,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
 
       if (!tb[RTA_MULTIPATH])
        rib_add (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
-                0, flags, &p, gate, src, index,
+                0, flags, &p, NULL, gate, src, index,
                 table, metric, mtu, 0);
       else
         {
@@ -296,7 +296,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
           if (rib->nexthop_num == 0)
             XFREE (MTYPE_RIB, rib);
           else
-            rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, rib);
+            rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, rib);
         }
     }
   if (rtm->rtm_family == AF_INET6)
@@ -306,7 +306,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
       p.prefixlen = rtm->rtm_dst_len;
 
       rib_add (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
-              0, flags, &p, gate, src, index,
+              0, flags, &p, NULL, gate, src, index,
               table, metric, mtu, 0);
     }
 
@@ -431,7 +431,7 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
         {
           if (!tb[RTA_MULTIPATH])
             rib_add (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
-                    0, 0, &p, gate, src, index,
+                    0, 0, &p, NULL, gate, src, index,
                     table, metric, mtu, 0);
           else
             {
@@ -490,12 +490,12 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
               if (rib->nexthop_num == 0)
                 XFREE (MTYPE_RIB, rib);
               else
-                rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, rib);
+                rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, rib);
             }
         }
       else
         rib_delete (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
-                   &p, gate, index, table);
+                   &p, NULL, gate, index, table);
     }
 
   if (rtm->rtm_family == AF_INET6)
@@ -516,11 +516,11 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
 
       if (h->nlmsg_type == RTM_NEWROUTE)
         rib_add (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
-                0, 0, &p, gate, src, index,
+                0, 0, &p, NULL, gate, src, index,
                 table, metric, mtu, 0);
       else
         rib_delete (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
-                   0, zebra_flags, &p, gate, index, table);
+                   0, zebra_flags, &p, NULL, gate, index, table);
     }
 
   return 0;
index c6eee7517498dcb761782ad897ea4dfe63968dbd..1007d0ac18dbde6ceb7315571454b4b5756d199c 100644 (file)
@@ -94,7 +94,7 @@ handle_route_entry (mib2_ipRouteEntry_t *routeEntry)
   ggateway = (union g_addr *)&gateway;
 
   rib_add (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0,
-          zebra_flags, &prefix, ggateway, NULL, 0, 0, 0, 0, 0);
+          zebra_flags, &prefix, NULL, ggateway, NULL, 0, 0, 0, 0, 0);
 }
 
 void
index 59893b1a0fa2e1fdf025520a0bd5ee90cac142bf..d638ceab7f4c5f9eaaaff407d7db9683a58da841 100644 (file)
@@ -2585,7 +2585,7 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p, vrf_id_t vrf_id)
 
 int
 rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
-                  struct rib *rib)
+                  struct prefix_ipv6 *src_p, struct rib *rib)
 {
   struct route_table *table;
   struct route_node *rn;
@@ -2674,8 +2674,8 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
 
 int
 rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
-           int flags, struct prefix *p, union g_addr *gate, ifindex_t ifindex,
-           u_int32_t table_id)
+           int flags, struct prefix *p, struct prefix_ipv6 *src_p,
+           union g_addr *gate, ifindex_t ifindex, u_int32_t table_id)
 {
   struct route_table *table;
   struct route_node *rn;
@@ -2815,7 +2815,8 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
 int
 rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
         u_short instance, int flags, struct prefix *p,
-        union g_addr *gate, union g_addr *src, ifindex_t ifindex,
+        struct prefix_ipv6 *src_p, union g_addr *gate,
+        union g_addr *src, ifindex_t ifindex,
         u_int32_t table_id, u_int32_t metric, u_int32_t mtu,
         u_char distance)
 {
index 6f72ad1758f6668159677e07a707f2f2bd919c48..fd40ed123b2ab0b4b4743104a284e3bdad19a1d1 100644 (file)
@@ -1149,7 +1149,7 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
   /* Table */
   rib->table = zvrf->table_id;
 
-  ret = rib_add_multipath (AFI_IP, safi, &p, rib);
+  ret = rib_add_multipath (AFI_IP, safi, &p, NULL, rib);
 
   /* Stats */
   if (ret > 0)
@@ -1243,7 +1243,7 @@ zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
   table_id = zvrf->table_id;
 
   rib_delete (AFI_IP, api.safi, zvrf_id (zvrf), api.type, api.instance,
-             api.flags, &p, nexthop_p, ifindex, table_id);
+             api.flags, &p, NULL, nexthop_p, ifindex, table_id);
   client->v4_route_del_cnt++;
   return 0;
 }
@@ -1378,7 +1378,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
   /* Table */
   rib->table = zvrf->table_id;
 
-  ret = rib_add_multipath (AFI_IP6, safi, &p, rib);
+  ret = rib_add_multipath (AFI_IP6, safi, &p, NULL, rib);
   /* Stats */
   if (ret > 0)
     client->v4_route_add_cnt++;
@@ -1399,6 +1399,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
   u_char nexthop_num;
   u_char nexthop_type;
   struct prefix p;
+  struct prefix_ipv6 src_p, *src_pp;
   safi_t safi;
   static struct in6_addr nexthops[MULTIPATH_NUM];
   static unsigned int ifindices[MULTIPATH_NUM];
@@ -1426,6 +1427,17 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
   p.prefixlen = stream_getc (s);
   stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
 
+  if (CHECK_FLAG (message, ZAPI_MESSAGE_SRCPFX))
+    {
+      memset (&src_p, 0, sizeof (struct prefix_ipv6));
+      src_p.family = AF_INET6;
+      src_p.prefixlen = stream_getc (s);
+      stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
+      src_pp = &src_p;
+    }
+  else
+    src_pp = NULL;
+
   /* We need to give nh-addr, nh-ifindex with the same next-hop object
    * to the rib to ensure that IPv6 multipathing works; need to coalesce
    * these. Clients should send the same number of paired set of
@@ -1500,7 +1512,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
   rib->vrf_id = zvrf_id (zvrf);
   rib->table = zvrf->table_id;
 
-  ret = rib_add_multipath (AFI_IP6, safi, &p, rib);
+  ret = rib_add_multipath (AFI_IP6, safi, &p, src_pp, rib);
   /* Stats */
   if (ret > 0)
     client->v6_route_add_cnt++;
@@ -1521,6 +1533,7 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
   union g_addr *pnexthop = NULL;
   unsigned long ifindex;
   struct prefix p;
+  struct prefix_ipv6 src_p, *src_pp;
   
   s = client->ibuf;
   ifindex = 0;
@@ -1539,6 +1552,17 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
   p.prefixlen = stream_getc (s);
   stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
 
+  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
+    {
+      memset (&src_p, 0, sizeof (struct prefix_ipv6));
+      src_p.family = AF_INET6;
+      src_p.prefixlen = stream_getc (s);
+      stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
+      src_pp = &src_p;
+    }
+  else
+    src_pp = NULL;
+
   /* Nexthop, ifindex, distance, metric. */
   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
     {
@@ -1582,10 +1606,10 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
 
   if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
     rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
-               api.flags, &p, NULL, ifindex, client->rtm_table);
+               api.flags, &p, src_pp, NULL, ifindex, client->rtm_table);
   else
     rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
-               api.flags, &p, pnexthop, ifindex, client->rtm_table);
+               api.flags, &p, src_pp, pnexthop, ifindex, client->rtm_table);
 
   client->v6_route_del_cnt++;
   return 0;