]> git.puffer.fish Git - matthieu/frr.git/commitdiff
Zebra: Build nelink message for RMAC updates
authorAmeya Dharkar <adharkar@vmware.com>
Fri, 17 May 2019 00:29:08 +0000 (17:29 -0700)
committerAmeya Dharkar <adharkar@vmware.com>
Mon, 17 Jun 2019 19:05:38 +0000 (12:05 -0700)
- Function "zfpm_netlink_encode_mac()" builds a netlink message for RMAC updates.

- To build a netlink message for RMAC updates, we use "ndmsg" in rtlink.

- FPM Message structure is:
  FPM header -> nlmsg header -> ndmsg fields -> ndmsg attributes

- Netlink message will look like:
  {'ndm_type': 0, 'family': 7, '__pad': (), 'header': {'flags': 1281,
   'length':64, 'type': 28, 'pid': 0, 'sequence_number': 0}, 'state': 2,
   'flags': 22, 'attrs': [('NDA_LLADDR', 'b2:66:eb:b9:5b:d3'),
   ('NDA_DST', '10.100.0.2'), ('NDA_MASTER', 11), ('NDA_VNI', 1000)],
   'ifindex': 18}

- Message details:
  nlmsghdr.nlmsg_type = RTM_NEWNEIGH(28) or RTM_DELNEIGH(29)
  nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE for "add" ,
    "NLM_F_REQUEST" for delete.
  ndmsg.ndm_family = AF_BRIDGE
  ndmsg.ndm_ifindex = vxlan_if (ifindex)
  ndmsg.ndm_state = NUD_REACHABLE
  ndmsg.ndm_flags |= NTF_SELF | NTF_MASTER | NTF_EXT_LEARNED
  Attribute "NDA_LLADDR" for MAC address
  Attribute "NDA_DST" for remote vtep ip
  Attribute "NDA_MASTER" for bridge interface ifindex.
  Attribute "NDA_VNI" for VNI id.

Signed-off-by: Ameya Dharkar <adharkar@vmware.com>
zebra/zebra_fpm.c
zebra/zebra_fpm_netlink.c
zebra/zebra_fpm_private.h

index 83d0dba61f7becab57f20a5b3cd8d1cd25d61cdf..3e74db8111d8fe64de376c73c7993e1cdc41ed24 100644 (file)
@@ -1052,6 +1052,11 @@ static inline int zfpm_encode_mac(struct fpm_mac_info_t *mac, char *in_buf,
        case ZFPM_MSG_FORMAT_NONE:
                break;
        case ZFPM_MSG_FORMAT_NETLINK:
+#ifdef HAVE_NETLINK
+               len = zfpm_netlink_encode_mac(mac, in_buf, in_buf_len);
+               assert(fpm_msg_align(len) == len);
+               *msg_type = FPM_MSG_TYPE_NETLINK;
+#endif /* HAVE_NETLINK */
                break;
        case ZFPM_MSG_FORMAT_PROTOBUF:
                break;
@@ -1100,7 +1105,7 @@ static int zfpm_build_mac_updates(void)
                data = fpm_msg_data(hdr);
                data_len = zfpm_encode_mac(mac, (char *)data, buf_end - data,
                                                &msg_type);
-               /* assert(data_len); */
+               assert(data_len);
 
                hdr->msg_type = msg_type;
                msg_len = fpm_data_len_to_msg_len(data_len);
index 2ac79b100c3250669a3a0bba8d4dca8b5983b985..4f2013585d271992b6884320067f8c8c7f591420 100644 (file)
@@ -580,4 +580,67 @@ int zfpm_netlink_encode_route(int cmd, rib_dest_t *dest, struct route_entry *re,
        return netlink_route_info_encode(ri, in_buf, in_buf_len);
 }
 
+/*
+ * zfpm_netlink_encode_mac
+ *
+ * Create a netlink message corresponding to the given MAC.
+ *
+ * Returns the number of bytes written to the buffer. 0 or a negative
+ * value indicates an error.
+ */
+int zfpm_netlink_encode_mac(struct fpm_mac_info_t *mac, char *in_buf,
+                           size_t in_buf_len)
+{
+       char buf1[ETHER_ADDR_STRLEN];
+       size_t buf_offset;
+
+       struct {
+               struct nlmsghdr hdr;
+               struct ndmsg ndm;
+               char buf[0];
+       } *req;
+       req = (void *)in_buf;
+
+       buf_offset = ((char *)req->buf) - ((char *)req);
+       if (in_buf_len < buf_offset)
+               return 0;
+       memset(req, 0, buf_offset);
+
+       /* Construct nlmsg header */
+       req->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg));
+       req->hdr.nlmsg_type = CHECK_FLAG(mac->fpm_flags, ZEBRA_MAC_DELETE_FPM) ?
+                               RTM_DELNEIGH : RTM_NEWNEIGH;
+       req->hdr.nlmsg_flags = NLM_F_REQUEST;
+       if (req->hdr.nlmsg_type == RTM_NEWNEIGH)
+               req->hdr.nlmsg_flags |= (NLM_F_CREATE | NLM_F_REPLACE);
+
+       /* Construct ndmsg */
+       req->ndm.ndm_family = AF_BRIDGE;
+       req->ndm.ndm_ifindex = mac->vxlan_if;
+
+       req->ndm.ndm_state = NUD_REACHABLE;
+       req->ndm.ndm_flags |= NTF_SELF | NTF_MASTER;
+       if (CHECK_FLAG(mac->zebra_flags,
+               (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW)))
+               req->ndm.ndm_state |= NUD_NOARP;
+       else
+               req->ndm.ndm_flags |= NTF_EXT_LEARNED;
+
+       /* Add attributes */
+       addattr_l(&req->hdr, in_buf_len, NDA_LLADDR, &mac->macaddr, 6);
+       addattr_l(&req->hdr, in_buf_len, NDA_DST, &mac->r_vtep_ip, 4);
+       addattr32(&req->hdr, in_buf_len, NDA_MASTER, mac->svi_if);
+       addattr32(&req->hdr, in_buf_len, NDA_VNI, mac->vni);
+
+       assert(req->hdr.nlmsg_len < in_buf_len);
+
+       zfpm_debug("Tx %s family %s ifindex %u MAC %s DEST %s",
+                  nl_msg_type_to_str(req->hdr.nlmsg_type),
+                  nl_family_to_str(req->ndm.ndm_family), req->ndm.ndm_ifindex,
+                  prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)),
+                  inet_ntoa(mac->r_vtep_ip));
+
+       return req->hdr.nlmsg_len;
+}
+
 #endif /* HAVE_NETLINK */
index 3ca39c45a917cdd7998a5054900b8402087b4d8e..c169ee8c2219481a160e246919b2331fa7f919cd 100644 (file)
@@ -92,6 +92,9 @@ extern int zfpm_netlink_encode_route(int cmd, rib_dest_t *dest,
 extern int zfpm_protobuf_encode_route(rib_dest_t *dest, struct route_entry *re,
                                      uint8_t *in_buf, size_t in_buf_len);
 
+extern int zfpm_netlink_encode_mac(struct fpm_mac_info_t *mac, char *in_buf,
+                                  size_t in_buf_len);
+
 extern struct route_entry *zfpm_route_for_update(rib_dest_t *dest);
 
 #ifdef __cplusplus