]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: adapt and export rmac netlink functions
authorRafael Zalamena <rzalamena@opensourcerouting.org>
Mon, 9 Dec 2019 15:36:18 +0000 (12:36 -0300)
committerRafael Zalamena <rzalamena@opensourcerouting.org>
Tue, 14 Apr 2020 16:45:39 +0000 (13:45 -0300)
Those functions are going to be used by the new data plane plugin for
netlink FPM.

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
zebra/rt_netlink.c
zebra/rt_netlink.h
zebra/zebra_dplane.h
zebra/zebra_vxlan_private.h

index cda69045171334d7437e3db774c2939736f9278b..06da711303e012056b6a4bdde01c59ea086c4e2e 100644 (file)
@@ -2521,62 +2521,63 @@ int kernel_neigh_update(int add, int ifindex, uint32_t addr, char *lla,
  * @type:              RTN_* route type
  * @flags:             NTF_* flags
  * @state:             NUD_* states
+ * @data:              data buffer pointer
+ * @datalen:           total amount of data buffer space
  *
  * Return:             Result status
  */
-static int netlink_update_neigh_ctx_internal(const struct zebra_dplane_ctx *ctx,
-                                            int cmd, const struct ethaddr *mac,
-                                            const struct ipaddr *ip,
-                                            bool replace_obj, uint8_t family,
-                                            uint8_t type, uint8_t flags,
-                                            uint16_t state)
+static ssize_t
+netlink_update_neigh_ctx_internal(const struct zebra_dplane_ctx *ctx,
+                                 int cmd, const struct ethaddr *mac,
+                                 const struct ipaddr *ip, bool replace_obj,
+                                 uint8_t family, uint8_t type, uint8_t flags,
+                                 uint16_t state, void *data, size_t datalen)
 {
        uint8_t protocol = RTPROT_ZEBRA;
        struct {
                struct nlmsghdr n;
                struct ndmsg ndm;
-               char buf[256];
-       } req;
+               char buf[];
+       } *req = data;
        int ipa_len;
        enum dplane_op_e op;
 
-       memset(&req, 0, sizeof(req));
+       memset(req, 0, datalen);
 
        op = dplane_ctx_get_op(ctx);
 
-       req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg));
-       req.n.nlmsg_flags = NLM_F_REQUEST;
+       req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg));
+       req->n.nlmsg_flags = NLM_F_REQUEST;
        if (cmd == RTM_NEWNEIGH)
-               req.n.nlmsg_flags |=
+               req->n.nlmsg_flags |=
                        NLM_F_CREATE
                        | (replace_obj ? NLM_F_REPLACE : NLM_F_APPEND);
-       req.n.nlmsg_type = cmd;
-       req.ndm.ndm_family = family;
-       req.ndm.ndm_type = type;
-       req.ndm.ndm_state = state;
-       req.ndm.ndm_flags = flags;
-       req.ndm.ndm_ifindex = dplane_ctx_get_ifindex(ctx);
+       req->n.nlmsg_type = cmd;
+       req->ndm.ndm_family = family;
+       req->ndm.ndm_type = type;
+       req->ndm.ndm_state = state;
+       req->ndm.ndm_flags = flags;
+       req->ndm.ndm_ifindex = dplane_ctx_get_ifindex(ctx);
 
-       addattr_l(&req.n, sizeof(req),
+       addattr_l(&req->n, sizeof(req),
                  NDA_PROTOCOL, &protocol, sizeof(protocol));
        if (mac)
-               addattr_l(&req.n, sizeof(req), NDA_LLADDR, mac, 6);
+               addattr_l(&req->n, datalen, NDA_LLADDR, mac, 6);
 
        ipa_len = IS_IPADDR_V4(ip) ? IPV4_MAX_BYTELEN : IPV6_MAX_BYTELEN;
-       addattr_l(&req.n, sizeof(req), NDA_DST, &ip->ip.addr, ipa_len);
+       addattr_l(&req->n, datalen, NDA_DST, &ip->ip.addr, ipa_len);
 
        if (op == DPLANE_OP_MAC_INSTALL || op == DPLANE_OP_MAC_DELETE) {
                vlanid_t vid = dplane_ctx_mac_get_vlan(ctx);
 
                if (vid > 0)
-                       addattr16(&req.n, sizeof(req), NDA_VLAN, vid);
+                       addattr16(&req->n, datalen, NDA_VLAN, vid);
 
-               addattr32(&req.n, sizeof(req), NDA_MASTER,
+               addattr32(&req->n, datalen, NDA_MASTER,
                          dplane_ctx_mac_get_br_ifindex(ctx));
        }
 
-       return netlink_talk_info(netlink_talk_filter, &req.n,
-                                dplane_ctx_get_ns(ctx), 0);
+       return NLMSG_ALIGN(req->n.nlmsg_len);
 }
 
 /*
@@ -2587,10 +2588,16 @@ static int netlink_vxlan_flood_update_ctx(const struct zebra_dplane_ctx *ctx,
                                          int cmd)
 {
        struct ethaddr dst_mac = {.octet = {0}};
+       uint8_t nl_pkt[NL_PKT_BUF_SIZE];
 
-       return netlink_update_neigh_ctx_internal(
+        netlink_update_neigh_ctx_internal(
                ctx, cmd, &dst_mac, dplane_ctx_neigh_get_ipaddr(ctx), false,
-               PF_BRIDGE, 0, NTF_SELF, (NUD_NOARP | NUD_PERMANENT));
+               PF_BRIDGE, 0, NTF_SELF, (NUD_NOARP | NUD_PERMANENT), nl_pkt,
+               sizeof(nl_pkt));
+
+       return netlink_talk_info(netlink_talk_filter,
+                                (struct nlmsghdr *)nl_pkt,
+                                dplane_ctx_get_ns(ctx), 0);
 }
 
 #ifndef NDA_RTA
@@ -2916,12 +2923,20 @@ int netlink_macfdb_read_specific_mac(struct zebra_ns *zns,
 /*
  * Netlink-specific handler for MAC updates using dataplane context object.
  */
-static int netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx, int cmd)
+ssize_t
+netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx, uint8_t *data,
+                         size_t datalen)
 {
        struct ipaddr vtep_ip;
        vlanid_t vid;
+       ssize_t total;
+       int cmd;
        uint8_t flags;
        uint16_t state;
+       uint8_t nl_pkt[NL_PKT_BUF_SIZE];
+
+       cmd = dplane_ctx_get_op(ctx) == DPLANE_OP_MAC_INSTALL
+                         ? RTM_NEWNEIGH : RTM_DELNEIGH;
 
        flags = (NTF_SELF | NTF_MASTER);
        state = NUD_REACHABLE;
@@ -2956,10 +2971,12 @@ static int netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx, int cmd)
                           ipaddr2str(&vtep_ip, ipbuf, sizeof(ipbuf)));
        }
 
-       return netlink_update_neigh_ctx_internal(
-               ctx, cmd, dplane_ctx_mac_get_addr(ctx),
-               dplane_ctx_neigh_get_ipaddr(ctx), true, AF_BRIDGE, 0, flags,
-               state);
+       total = netlink_update_neigh_ctx_internal(
+                       ctx, cmd, dplane_ctx_mac_get_addr(ctx),
+                       dplane_ctx_neigh_get_ipaddr(ctx), true, AF_BRIDGE, 0,
+                       flags, state, nl_pkt, sizeof(nl_pkt));
+
+       return total;
 }
 
 /*
@@ -3348,6 +3365,7 @@ static int netlink_neigh_update_ctx(const struct zebra_dplane_ctx *ctx,
        uint8_t flags;
        uint16_t state;
        uint8_t family;
+       uint8_t nl_pkt[NL_PKT_BUF_SIZE];
 
        ip = dplane_ctx_neigh_get_ipaddr(ctx);
        mac = dplane_ctx_neigh_get_mac(ctx);
@@ -3372,8 +3390,12 @@ static int netlink_neigh_update_ctx(const struct zebra_dplane_ctx *ctx,
                        flags, state);
        }
 
-       return netlink_update_neigh_ctx_internal(
-               ctx, cmd, mac, ip, true, family, RTN_UNICAST, flags, state);
+       netlink_update_neigh_ctx_internal(
+                       ctx, cmd, mac, ip, true, family, RTN_UNICAST, flags,
+                       state, nl_pkt, sizeof(nl_pkt));
+
+       return netlink_talk_info(netlink_talk_filter, (struct nlmsghdr *)nl_pkt,
+                                dplane_ctx_get_ns(ctx), 0);
 }
 
 /*
@@ -3381,13 +3403,18 @@ static int netlink_neigh_update_ctx(const struct zebra_dplane_ctx *ctx,
  */
 enum zebra_dplane_result kernel_mac_update_ctx(struct zebra_dplane_ctx *ctx)
 {
-       int cmd = dplane_ctx_get_op(ctx) == DPLANE_OP_MAC_INSTALL
-                         ? RTM_NEWNEIGH
-                         : RTM_DELNEIGH;
-       int ret = netlink_macfdb_update_ctx(ctx, cmd);
+       uint8_t nl_pkt[NL_PKT_BUF_SIZE];
+       ssize_t rv;
 
-       return (ret == 0 ? ZEBRA_DPLANE_REQUEST_SUCCESS
-                        : ZEBRA_DPLANE_REQUEST_FAILURE);
+       rv = netlink_macfdb_update_ctx(ctx, nl_pkt, sizeof(nl_pkt));
+       if (rv <= 0)
+               return ZEBRA_DPLANE_REQUEST_FAILURE;
+
+       rv = netlink_talk_info(netlink_talk_filter, (struct nlmsghdr *)nl_pkt,
+                              dplane_ctx_get_ns(ctx), 0);
+
+       return rv == 0 ?
+               ZEBRA_DPLANE_REQUEST_SUCCESS : ZEBRA_DPLANE_REQUEST_FAILURE;
 }
 
 enum zebra_dplane_result kernel_neigh_update_ctx(struct zebra_dplane_ctx *ctx)
index 64109e50e6ac8cb6887b65434aff515719c1fb0f..15ef43c5389a999d6bad39ef3f302946072aecf4 100644 (file)
@@ -68,6 +68,8 @@ extern int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx);
 
 extern ssize_t netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx,
                                       uint8_t *data, size_t datalen);
+extern ssize_t netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx,
+                                        uint8_t *data, size_t datalen);
 
 extern int netlink_route_change(struct nlmsghdr *h, ns_id_t ns_id, int startup);
 extern int netlink_route_read(struct zebra_ns *zns);
index 8302758d3ffc2b1ed926a82dfcc67212b3b3c190..f01ca2e84c89b829652195b3e7a4d676b101d943 100644 (file)
@@ -444,6 +444,12 @@ enum zebra_dplane_result dplane_intf_addr_unset(const struct interface *ifp,
 /*
  * Enqueue evpn mac operations for the dataplane.
  */
+extern struct zebra_dplane_ctx *mac_update_internal(
+       enum dplane_op_e op, const struct interface *ifp,
+       const struct interface *br_ifp,
+       vlanid_t vid, const struct ethaddr *mac,
+       struct in_addr vtep_ip, bool sticky);
+
 enum zebra_dplane_result dplane_mac_add(const struct interface *ifp,
                                        const struct interface *bridge_ifp,
                                        vlanid_t vid,
index 100bb0e09318640d460107bcebf293479aa6ab82..0a46fb20758cf1d69120b03fbefd59e054adde3f 100644 (file)
@@ -301,6 +301,7 @@ struct zebra_mac_t_ {
 /* remote VTEP advertised MAC as default GW */
 #define ZEBRA_MAC_REMOTE_DEF_GW        0x40
 #define ZEBRA_MAC_DUPLICATE 0x80
+#define ZEBRA_MAC_FPM_SENT  0x100 /* whether or not this entry was sent. */
 
        /* back pointer to zvni */
        zebra_vni_t     *zvni;