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
* 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));
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
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;
}
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.
*/
};
/*
- * MAC address info for the dataplane.
+ * EVPN MAC address info for the dataplane.
*/
struct dplane_mac_info {
vlanid_t vid;
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;
}
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;
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);
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);
return result;
}
+/*
+ * 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
*/
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;
DPLANE_OP_NEIGH_INSTALL,
DPLANE_OP_NEIGH_UPDATE,
DPLANE_OP_NEIGH_DELETE,
+
+ /* EVPN VTEP updates */
+ DPLANE_OP_VTEP_ADD,
+ DPLANE_OP_VTEP_DELETE,
};
/*
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);
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);
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;
}
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;
}
/*