]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib, pimd, zebra: Allow pim to set pimregX into appropriate vrf
authorDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 13 Jun 2017 12:59:32 +0000 (08:59 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 24 Jul 2017 17:51:39 +0000 (13:51 -0400)
The pimregX devices when created by the kernel are put into
the default vrf.  When pim gets the callback that the device
exists, check to see if it is a pimregX device and if so
move it into the appropriate vrf.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
lib/log.c
lib/zclient.c
lib/zclient.h
pimd/pim_zebra.c
zebra/if_netlink.c
zebra/rt.h
zebra/rt_netlink.c
zebra/rt_socket.c
zebra/zserv.c

index 28e086535412218f70dbde14dc2fed64f9cf65c5..5adb06d28cc7717f23ec65cb2f9f1e0e90d64035 100644 (file)
--- a/lib/log.c
+++ b/lib/log.c
@@ -857,6 +857,7 @@ static const struct zebra_desc_table command_types[] = {
        DESC_ENTRY(ZEBRA_INTERFACE_ADDRESS_DELETE),
        DESC_ENTRY(ZEBRA_INTERFACE_UP),
        DESC_ENTRY(ZEBRA_INTERFACE_DOWN),
+       DESC_ENTRY(ZEBRA_INTERFACE_SET_MASTER),
        DESC_ENTRY(ZEBRA_IPV4_ROUTE_ADD),
        DESC_ENTRY(ZEBRA_IPV4_ROUTE_DELETE),
        DESC_ENTRY(ZEBRA_IPV6_ROUTE_ADD),
index a54d8749a399d2b99ef6c8d0ad2ff97dfd4c6b8a..a6252af403949d63c7db80e961a2959bae80f47d 100644 (file)
@@ -2184,3 +2184,23 @@ void zclient_serv_path_set(char *path)
        /* it seems that path is unix socket */
        zclient_serv_path = path;
 }
+
+void zclient_interface_set_master(struct zclient *client,
+                                 struct interface *master,
+                                 struct interface *slave)
+{
+       struct stream *s;
+
+       s = client->obuf;
+       stream_reset(s);
+
+       zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER, master->vrf_id);
+
+       stream_putw(s, master->vrf_id);
+       stream_putl(s, master->ifindex);
+       stream_putw(s, slave->vrf_id);
+       stream_putl(s, slave->ifindex);
+
+       stream_putw_at(s, 0, stream_get_endp(s));
+       zclient_send_message(client);
+}
index efa5c32c16ef8bcecccb693d26b225c5db7907c6..435d26e2f9c28523c3142c2c81fe2fd5a1db7be9 100644 (file)
@@ -44,6 +44,7 @@ typedef enum {
        ZEBRA_INTERFACE_ADDRESS_DELETE,
        ZEBRA_INTERFACE_UP,
        ZEBRA_INTERFACE_DOWN,
+       ZEBRA_INTERFACE_SET_MASTER,
        ZEBRA_IPV4_ROUTE_ADD,
        ZEBRA_IPV4_ROUTE_DELETE,
        ZEBRA_IPV6_ROUTE_ADD,
@@ -311,6 +312,9 @@ extern int zclient_read_header(struct stream *s, int sock, u_int16_t *size,
                               u_char *marker, u_char *version,
                               vrf_id_t *vrf_id, u_int16_t *cmd);
 
+extern void zclient_interface_set_master(struct zclient *client,
+                                        struct interface *master,
+                                        struct interface *slave);
 extern struct interface *zebra_interface_add_read(struct stream *, vrf_id_t);
 extern struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t);
 extern struct connected *zebra_interface_address_read(int, struct stream *,
index 47b97339f0c78a3ba15f14f0f48443a529cb858f..b86b6839480ae759a1489d05ca1c3adb440846d6 100644 (file)
@@ -80,8 +80,8 @@ static int pim_zebra_if_add(int command, struct zclient *zclient,
 
        if (PIM_DEBUG_ZEBRA) {
                zlog_debug(
-                       "%s: %s index %d flags %ld metric %d mtu %d operative %d",
-                       __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+                       "%s: %s index %d(%d) flags %ld metric %d mtu %d operative %d",
+                       __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
                        (long)ifp->flags, ifp->metric, ifp->mtu,
                        if_is_operative(ifp));
        }
@@ -113,8 +113,8 @@ static int pim_zebra_if_del(int command, struct zclient *zclient,
 
        if (PIM_DEBUG_ZEBRA) {
                zlog_debug(
-                       "%s: %s index %d flags %ld metric %d mtu %d operative %d",
-                       __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+                       "%s: %s index %d(%d) flags %ld metric %d mtu %d operative %d",
+                       __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
                        (long)ifp->flags, ifp->metric, ifp->mtu,
                        if_is_operative(ifp));
        }
@@ -129,6 +129,7 @@ static int pim_zebra_if_state_up(int command, struct zclient *zclient,
                                 zebra_size_t length, vrf_id_t vrf_id)
 {
        struct interface *ifp;
+       uint32_t table_id;
 
        /*
          zebra api notifies interface up/down events by using the same call
@@ -140,8 +141,8 @@ static int pim_zebra_if_state_up(int command, struct zclient *zclient,
 
        if (PIM_DEBUG_ZEBRA) {
                zlog_debug(
-                       "%s: %s index %d flags %ld metric %d mtu %d operative %d",
-                       __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+                       "%s: %s index %d(%d) flags %ld metric %d mtu %d operative %d",
+                       __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
                        (long)ifp->flags, ifp->metric, ifp->mtu,
                        if_is_operative(ifp));
        }
@@ -154,6 +155,23 @@ static int pim_zebra_if_state_up(int command, struct zclient *zclient,
                pim_if_addr_add_all(ifp);
        }
 
+       /*
+        * If we have a pimreg device callback and it's for a specific
+        * table set the master appropriately
+        */
+       if (sscanf(ifp->name, "pimreg%d", &table_id) == 1) {
+               struct vrf *vrf;
+               RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
+               {
+                       if ((table_id == vrf->data.l.table_id)
+                           && (ifp->vrf_id != vrf->vrf_id)) {
+                               struct interface *master = if_lookup_by_name(
+                                       vrf->name, vrf->vrf_id);
+                               zclient_interface_set_master(zclient, master,
+                                                            ifp);
+                       }
+               }
+       }
        return 0;
 }
 
@@ -172,8 +190,8 @@ static int pim_zebra_if_state_down(int command, struct zclient *zclient,
 
        if (PIM_DEBUG_ZEBRA) {
                zlog_debug(
-                       "%s: %s index %d flags %ld metric %d mtu %d operative %d",
-                       __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+                       "%s: %s index %d(%d) flags %ld metric %d mtu %d operative %d",
+                       __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
                        (long)ifp->flags, ifp->metric, ifp->mtu,
                        if_is_operative(ifp));
        }
@@ -252,11 +270,11 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
        if (PIM_DEBUG_ZEBRA) {
                char buf[BUFSIZ];
                prefix2str(p, buf, BUFSIZ);
-               zlog_debug("%s: %s connected IP address %s flags %u %s",
-                          __PRETTY_FUNCTION__, c->ifp->name, buf, c->flags,
-                          CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
-                                  ? "secondary"
-                                  : "primary");
+               zlog_debug("%s: %s(%d) connected IP address %s flags %u %s",
+                          __PRETTY_FUNCTION__, c->ifp->name, vrf_id, buf,
+                          c->flags, CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
+                                            ? "secondary"
+                                            : "primary");
 
 #ifdef PIM_DEBUG_IFADDR_DUMP
                dump_if_address(c->ifp);
@@ -327,8 +345,8 @@ static int pim_zebra_if_address_del(int command, struct zclient *client,
                        char buf[BUFSIZ];
                        prefix2str(p, buf, BUFSIZ);
                        zlog_debug(
-                               "%s: %s disconnected IP address %s flags %u %s",
-                               __PRETTY_FUNCTION__, c->ifp->name, buf,
+                               "%s: %s(%d) disconnected IP address %s flags %u %s",
+                               __PRETTY_FUNCTION__, c->ifp->name, vrf_id, buf,
                                c->flags,
                                CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
                                        ? "secondary"
index acec2db5268002ed1fd911cb42ccc883408a6879..bd7673d6c82ac65675f3d0c3c3495d7b79a9ff04 100644 (file)
@@ -768,6 +768,33 @@ int interface_lookup_netlink(struct zebra_ns *zns)
        return 0;
 }
 
+int kernel_interface_set_master(struct interface *master,
+                               struct interface *slave)
+{
+       struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT);
+
+       struct {
+               struct nlmsghdr n;
+               struct ifinfomsg ifa;
+               char buf[NL_PKT_BUF_SIZE];
+       } req;
+
+       memset(&req, 0, sizeof req);
+
+       req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+       req.n.nlmsg_flags = NLM_F_REQUEST;
+       req.n.nlmsg_type = RTM_SETLINK;
+       req.n.nlmsg_pid = zns->netlink_cmd.snl.nl_pid;
+
+       req.ifa.ifi_index = slave->ifindex;
+
+       addattr_l(&req.n, sizeof req, IFLA_MASTER, &master->ifindex, 4);
+       addattr_l(&req.n, sizeof req, IFLA_LINK, &slave->ifindex, 4);
+
+       return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
+                           0);
+}
+
 /* Interface address modification. */
 static int netlink_address(int cmd, int family, struct interface *ifp,
                           struct connected *ifc)
index ead6a6c5084d5ecec3e5af89c940c7e9033d2791..f5f0fa195b380d83f7990f605923fe191000bf46 100644 (file)
@@ -36,7 +36,8 @@ extern int kernel_route_rib(struct prefix *, struct prefix *,
 extern int kernel_address_add_ipv4(struct interface *, struct connected *);
 extern int kernel_address_delete_ipv4(struct interface *, struct connected *);
 extern int kernel_neigh_update(int, int, uint32_t, char *, int);
-
+extern int kernel_interface_set_master(struct interface *master,
+                                      struct interface *slave);
 extern int kernel_add_lsp(zebra_lsp_t *);
 extern int kernel_upd_lsp(zebra_lsp_t *);
 extern int kernel_del_lsp(zebra_lsp_t *);
index 73054594b7fad4e09d3dcc7d6fbd2e1bda8114df..e4cf1a1261fd6de96a04a2f7c484e2273f68f8ab 100644 (file)
@@ -1525,8 +1525,7 @@ int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in)
        struct zebra_ns *zns = zvrf->zns;
 
        mroute = mr;
-       suc = netlink_request(RTNL_FAMILY_IPMR, RTM_GETROUTE,
-                             &zns->netlink_cmd);
+       suc = netlink_request_route(zns, RTNL_FAMILY_IPMR, RTM_GETROUTE);
        if (suc < 0)
                return suc;
 
index 683086f1098360a8996be64b08d0e48d2701cf00..699fe6eb24ebc19e042e444109a01e586c2ed0f1 100644 (file)
@@ -443,3 +443,9 @@ int kernel_del_neigh(struct interface *ifp, struct ipaddr *ip)
 {
        return 0;
 }
+
+extern int kernel_interface_set_master(struct interface *master,
+                                      struct interface *slave)
+{
+       return 0;
+}
index 3bc5f83f6451d68fea444fea5165d275d75f86e9..ab46a1f29fda2b8585e67ad698e74bc8932a032e 100644 (file)
@@ -55,6 +55,7 @@
 #include "zebra/zebra_mroute.h"
 #include "zebra/label_manager.h"
 #include "zebra/zebra_vxlan.h"
+#include "zebra/rt.h"
 
 /* Event list of zebra. */
 enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
@@ -2164,6 +2165,31 @@ static void zebra_client_create(int sock)
        zebra_vrf_update_all(client);
 }
 
+static int zread_interface_set_master(struct zserv *client, int sock,
+                                     u_short length)
+{
+       struct interface *master;
+       struct interface *slave;
+       struct stream *s = client->ibuf;
+       int ifindex;
+       vrf_id_t vrf_id;
+
+       vrf_id = stream_getw(s);
+       ifindex = stream_getl(s);
+       master = if_lookup_by_index(ifindex, vrf_id);
+
+       vrf_id = stream_getw(s);
+       ifindex = stream_getl(s);
+       slave = if_lookup_by_index(ifindex, vrf_id);
+
+       if (!master || !slave)
+               return 0;
+
+       kernel_interface_set_master(master, slave);
+
+       return 1;
+}
+
 /* Handler of zebra service request. */
 static int zebra_client_read(struct thread *thread)
 {
@@ -2406,6 +2432,8 @@ static int zebra_client_read(struct thread *thread)
                break;
        case ZEBRA_REMOTE_MACIP_DEL:
                zebra_vxlan_remote_macip_del(client, sock, length, zvrf);
+       case ZEBRA_INTERFACE_SET_MASTER:
+               zread_interface_set_master(client, sock, length);
                break;
        default:
                zlog_info("Zebra received unknown command %d", command);