summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2019-09-04 14:14:20 -0400
committerGitHub <noreply@github.com>2019-09-04 14:14:20 -0400
commit641adc31968f612e432b01ad6bff962d409da2e5 (patch)
tree8d7466e13538c4dd3601fac44ff45af324490d82
parentce9d312c1cb9209c2324d9c6d340552146c17e04 (diff)
parent0bbd4ff44231a0b3015abb8594068d1183a65f43 (diff)
Merge pull request #4883 from mjstapp/dplane_vteps
Zebra: use dataplane for evpn vtep programming
-rw-r--r--zebra/rt.h4
-rw-r--r--zebra/rt_netlink.c49
-rw-r--r--zebra/rt_socket.c10
-rw-r--r--zebra/zebra_dplane.c65
-rw-r--r--zebra/zebra_dplane.h15
-rw-r--r--zebra/zebra_rib.c2
-rw-r--r--zebra/zebra_vxlan.c16
7 files changed, 105 insertions, 56 deletions
diff --git a/zebra/rt.h b/zebra/rt.h
index 73708bd30a..59b42fed18 100644
--- a/zebra/rt.h
+++ b/zebra/rt.h
@@ -68,10 +68,6 @@ extern int mpls_kernel_init(void);
extern uint32_t kernel_get_speed(struct interface *ifp);
extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute);
-extern int kernel_add_vtep(vni_t vni, struct interface *ifp,
- struct in_addr *vtep_ip);
-extern int kernel_del_vtep(vni_t vni, struct interface *ifp,
- struct in_addr *vtep_ip);
/*
* Southbound Initialization routines to get initial starting
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 98d1dbbbca..5edcf9bb8a 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -1927,19 +1927,17 @@ int kernel_neigh_update(int add, int ifindex, uint32_t addr, char *lla,
* Add remote VTEP to the flood list for this VxLAN interface (VNI). This
* is done by adding an FDB entry with a MAC of 00:00:00:00:00:00.
*/
-static int netlink_vxlan_flood_list_update(struct interface *ifp,
- struct in_addr *vtep_ip, int cmd)
+static int netlink_vxlan_flood_update_ctx(const struct zebra_dplane_ctx *ctx,
+ int cmd)
{
- struct zebra_ns *zns;
struct {
struct nlmsghdr n;
struct ndmsg ndm;
char buf[256];
} req;
uint8_t dst_mac[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
- struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
+ const struct ipaddr *addr;
- zns = zvrf->zns;
memset(&req, 0, sizeof(req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg));
@@ -1953,39 +1951,14 @@ static int netlink_vxlan_flood_list_update(struct interface *ifp,
addattr_l(&req.n, sizeof(req), NDA_LLADDR, &dst_mac, 6);
- req.ndm.ndm_ifindex = ifp->ifindex;
- addattr_l(&req.n, sizeof(req), NDA_DST, &vtep_ip->s_addr, 4);
-
- return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
- 0);
-}
-
-/*
- * Add remote VTEP for this VxLAN interface (VNI). In Linux, this involves
- * adding
- * a "flood" MAC FDB entry.
- */
-int kernel_add_vtep(vni_t vni, struct interface *ifp, struct in_addr *vtep_ip)
-{
- if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("Install %s into flood list for VNI %u intf %s(%u)",
- inet_ntoa(*vtep_ip), vni, ifp->name, ifp->ifindex);
+ req.ndm.ndm_ifindex = dplane_ctx_get_ifindex(ctx);
- return netlink_vxlan_flood_list_update(ifp, vtep_ip, RTM_NEWNEIGH);
-}
+ addr = dplane_ctx_neigh_get_ipaddr(ctx);
-/*
- * Remove remote VTEP for this VxLAN interface (VNI). In Linux, this involves
- * deleting the "flood" MAC FDB entry.
- */
-int kernel_del_vtep(vni_t vni, struct interface *ifp, struct in_addr *vtep_ip)
-{
- if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug(
- "Uninstall %s from flood list for VNI %u intf %s(%u)",
- inet_ntoa(*vtep_ip), vni, ifp->name, ifp->ifindex);
+ addattr_l(&req.n, sizeof(req), NDA_DST, &(addr->ipaddr_v4), 4);
- return netlink_vxlan_flood_list_update(ifp, vtep_ip, RTM_DELNEIGH);
+ return netlink_talk_info(netlink_talk_filter, &req.n,
+ dplane_ctx_get_ns(ctx), 0);
}
#ifndef NDA_RTA
@@ -2883,6 +2856,12 @@ enum zebra_dplane_result kernel_neigh_update_ctx(struct zebra_dplane_ctx *ctx)
case DPLANE_OP_NEIGH_DELETE:
ret = netlink_neigh_update_ctx(ctx, RTM_DELNEIGH);
break;
+ case DPLANE_OP_VTEP_ADD:
+ ret = netlink_vxlan_flood_update_ctx(ctx, RTM_NEWNEIGH);
+ break;
+ case DPLANE_OP_VTEP_DELETE:
+ ret = netlink_vxlan_flood_update_ctx(ctx, RTM_DELNEIGH);
+ break;
default:
break;
}
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c
index f8ce71713a..dc0f29bdbc 100644
--- a/zebra/rt_socket.c
+++ b/zebra/rt_socket.c
@@ -382,16 +382,6 @@ extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute)
return 0;
}
-int kernel_add_vtep(vni_t vni, struct interface *ifp, struct in_addr *vtep_ip)
-{
- return 0;
-}
-
-int kernel_del_vtep(vni_t vni, struct interface *ifp, struct in_addr *vtep_ip)
-{
- return 0;
-}
-
/*
* Update MAC, using dataplane context object. No-op here for now.
*/
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 569ccfb0b1..2bf541617c 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -148,7 +148,7 @@ struct dplane_intf_info {
};
/*
- * MAC address info for the dataplane.
+ * EVPN MAC address info for the dataplane.
*/
struct dplane_mac_info {
vlanid_t vid;
@@ -508,6 +508,8 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
case DPLANE_OP_NEIGH_INSTALL:
case DPLANE_OP_NEIGH_UPDATE:
case DPLANE_OP_NEIGH_DELETE:
+ case DPLANE_OP_VTEP_ADD:
+ case DPLANE_OP_VTEP_DELETE:
case DPLANE_OP_NONE:
break;
}
@@ -684,6 +686,12 @@ const char *dplane_op2str(enum dplane_op_e op)
case DPLANE_OP_NEIGH_DELETE:
ret = "NEIGH_DELETE";
break;
+ case DPLANE_OP_VTEP_ADD:
+ ret = "VTEP_ADD";
+ break;
+ case DPLANE_OP_VTEP_DELETE:
+ ret = "VTEP_DELETE";
+ break;
}
return ret;
@@ -2243,7 +2251,7 @@ enum zebra_dplane_result dplane_neigh_update(const struct interface *ifp,
const struct ipaddr *ip,
const struct ethaddr *mac)
{
- enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
+ enum zebra_dplane_result result;
result = neigh_update_internal(DPLANE_OP_NEIGH_UPDATE,
ifp, mac, ip, 0, DPLANE_NUD_PROBE);
@@ -2257,7 +2265,7 @@ enum zebra_dplane_result dplane_neigh_update(const struct interface *ifp,
enum zebra_dplane_result dplane_neigh_delete(const struct interface *ifp,
const struct ipaddr *ip)
{
- enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
+ enum zebra_dplane_result result;
result = neigh_update_internal(DPLANE_OP_NEIGH_DELETE,
ifp, NULL, ip, 0, 0);
@@ -2266,6 +2274,55 @@ enum zebra_dplane_result dplane_neigh_delete(const struct interface *ifp,
}
/*
+ * Enqueue evpn VTEP add for the dataplane.
+ */
+enum zebra_dplane_result dplane_vtep_add(const struct interface *ifp,
+ const struct in_addr *ip,
+ vni_t vni)
+{
+ enum zebra_dplane_result result;
+ struct ethaddr mac = { {0, 0, 0, 0, 0, 0} };
+ struct ipaddr addr;
+
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug("Install %s into flood list for VNI %u intf %s(%u)",
+ inet_ntoa(*ip), vni, ifp->name, ifp->ifindex);
+
+ SET_IPADDR_V4(&addr);
+ addr.ipaddr_v4 = *ip;
+
+ result = neigh_update_internal(DPLANE_OP_VTEP_ADD,
+ ifp, &mac, &addr, 0, 0);
+
+ return result;
+}
+
+/*
+ * Enqueue evpn VTEP add for the dataplane.
+ */
+enum zebra_dplane_result dplane_vtep_delete(const struct interface *ifp,
+ const struct in_addr *ip,
+ vni_t vni)
+{
+ enum zebra_dplane_result result;
+ struct ethaddr mac = { {0, 0, 0, 0, 0, 0} };
+ struct ipaddr addr;
+
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug(
+ "Uninstall %s from flood list for VNI %u intf %s(%u)",
+ inet_ntoa(*ip), vni, ifp->name, ifp->ifindex);
+
+ SET_IPADDR_V4(&addr);
+ addr.ipaddr_v4 = *ip;
+
+ result = neigh_update_internal(DPLANE_OP_VTEP_DELETE,
+ ifp, &mac, &addr, 0, 0);
+
+ return result;
+}
+
+/*
* Common helper api for evpn neighbor updates
*/
static enum zebra_dplane_result
@@ -2910,6 +2967,8 @@ static int kernel_dplane_process_func(struct zebra_dplane_provider *prov)
case DPLANE_OP_NEIGH_INSTALL:
case DPLANE_OP_NEIGH_UPDATE:
case DPLANE_OP_NEIGH_DELETE:
+ case DPLANE_OP_VTEP_ADD:
+ case DPLANE_OP_VTEP_DELETE:
res = kernel_dplane_neigh_update(ctx);
break;
diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h
index fab241a579..31f0fc98b3 100644
--- a/zebra/zebra_dplane.h
+++ b/zebra/zebra_dplane.h
@@ -134,6 +134,10 @@ enum dplane_op_e {
DPLANE_OP_NEIGH_INSTALL,
DPLANE_OP_NEIGH_UPDATE,
DPLANE_OP_NEIGH_DELETE,
+
+ /* EVPN VTEP updates */
+ DPLANE_OP_VTEP_ADD,
+ DPLANE_OP_VTEP_DELETE,
};
/*
@@ -421,6 +425,17 @@ enum zebra_dplane_result dplane_neigh_update(const struct interface *ifp,
enum zebra_dplane_result dplane_neigh_delete(const struct interface *ifp,
const struct ipaddr *ip);
+/*
+ * Enqueue evpn VTEP updates for the dataplane.
+ */
+enum zebra_dplane_result dplane_vtep_add(const struct interface *ifp,
+ const struct in_addr *ip,
+ vni_t vni);
+enum zebra_dplane_result dplane_vtep_delete(const struct interface *ifp,
+ const struct in_addr *ip,
+ vni_t vni);
+
+
/* Retrieve the limit on the number of pending, unprocessed updates. */
uint32_t dplane_get_in_queue_limit(void);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index b85784f593..157c67fa62 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -3280,6 +3280,8 @@ static int rib_process_dplane_results(struct thread *thread)
case DPLANE_OP_NEIGH_INSTALL:
case DPLANE_OP_NEIGH_UPDATE:
case DPLANE_OP_NEIGH_DELETE:
+ case DPLANE_OP_VTEP_ADD:
+ case DPLANE_OP_VTEP_DELETE:
case DPLANE_OP_NONE:
/* Don't expect this: just return the struct? */
dplane_ctx_fini(&ctx);
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index b8dfe999da..bb8b61e7e3 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -4290,9 +4290,13 @@ static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall)
static int zvni_vtep_install(zebra_vni_t *zvni, zebra_vtep_t *zvtep)
{
if (is_vxlan_flooding_head_end() &&
- (zvtep->flood_control == VXLAN_FLOOD_HEAD_END_REPL))
- return kernel_add_vtep(zvni->vni, zvni->vxlan_if,
- &zvtep->vtep_ip);
+ (zvtep->flood_control == VXLAN_FLOOD_HEAD_END_REPL)) {
+ if (ZEBRA_DPLANE_REQUEST_FAILURE ==
+ dplane_vtep_add(zvni->vxlan_if,
+ &zvtep->vtep_ip, zvni->vni))
+ return -1;
+ }
+
return 0;
}
@@ -4307,7 +4311,11 @@ static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip)
return -1;
}
- return kernel_del_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
+ if (ZEBRA_DPLANE_REQUEST_FAILURE ==
+ dplane_vtep_delete(zvni->vxlan_if, vtep_ip, zvni->vni))
+ return -1;
+
+ return 0;
}
/*