Merge pull request #2665 from chiragshah6/evpn_dev

bgpd: support evpn nd ext community
This commit is contained in:
Russ White 2018-07-24 11:55:08 -04:00 committed by GitHub
commit bbc7adf1b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 167 additions and 30 deletions

View File

@ -1890,6 +1890,16 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
/* Check if this is a Gateway MAC-IP advertisement */
attr->default_gw = bgp_attr_default_gw(attr);
/* Handle scenario where router flag ecommunity is not
* set but default gw ext community is present.
* Use default gateway, set and propogate R-bit.
*/
if (attr->default_gw)
attr->router_flag = 1;
/* Check EVPN Neighbor advertisement flags, R-bit */
bgp_attr_evpn_na_flag(attr, &attr->router_flag);
/* Extract the Rmac, if any */
bgp_attr_rmac(attr, &attr->rmac);

View File

@ -185,6 +185,9 @@ struct attr {
/* Flag for default gateway extended community in EVPN */
uint8_t default_gw;
/* NA router flag (R-bit) support in EVPN */
uint8_t router_flag;
/* route tag */
route_tag_t tag;

View File

@ -210,6 +210,39 @@ uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, uint8_t *sticky)
return 0;
}
/*
* return true if attr contains router flag extended community
*/
void bgp_attr_evpn_na_flag(struct attr *attr, uint8_t *router_flag)
{
struct ecommunity *ecom;
int i;
uint8_t val;
ecom = attr->ecommunity;
if (!ecom || !ecom->size)
return;
/* If there is a evpn na extendd community set router_flag */
for (i = 0; i < ecom->size; i++) {
uint8_t *pnt;
uint8_t type, sub_type;
pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
type = *pnt++;
sub_type = *pnt++;
if (type == ECOMMUNITY_ENCODE_EVPN &&
sub_type == ECOMMUNITY_EVPN_SUBTYPE_ND) {
val = *pnt++;
if (val & ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG) {
*router_flag = 1;
break;
}
}
}
}
/* dst prefix must be AF_INET or AF_INET6 prefix, to forge EVPN prefix */
extern int bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag,
struct prefix *dst)

View File

@ -65,4 +65,6 @@ extern uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr,
uint8_t *sticky);
extern uint8_t bgp_attr_default_gw(struct attr *attr);
extern void bgp_attr_evpn_na_flag(struct attr *attr, uint8_t *router_flag);
#endif /* _QUAGGA_BGP_ATTR_EVPN_H */

View File

@ -48,8 +48,11 @@
#define ECOMMUNITY_EVPN_SUBTYPE_ES_IMPORT_RT 0x02
#define ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC 0x03
#define ECOMMUNITY_EVPN_SUBTYPE_DEF_GW 0x0d
#define ECOMMUNITY_EVPN_SUBTYPE_ND 0x08
#define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY 0x01
#define ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG 0x01
#define ECOMMUNITY_EVPN_SUBTYPE_ND_OVERRIDE_FLAG 0x02
/* Low-order octet of the Extended Communities type field for OPAQUE types */
#define ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP 0x0c

View File

@ -730,10 +730,13 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
struct ecommunity ecom_sticky;
struct ecommunity ecom_default_gw;
struct ecommunity ecom_rmac;
struct ecommunity ecom_na;
struct ecommunity_val eval;
struct ecommunity_val eval_sticky;
struct ecommunity_val eval_default_gw;
struct ecommunity_val eval_rmac;
struct ecommunity_val eval_na;
bgp_encap_types tnl_type;
struct listnode *node, *nnode;
struct ecommunity *ecom;
@ -798,6 +801,15 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
ecommunity_merge(attr->ecommunity, &ecom_default_gw);
}
if (attr->router_flag) {
memset(&ecom_na, 0, sizeof(ecom_na));
encode_na_flag_extcomm(&eval_na, attr->router_flag);
ecom_na.size = 1;
ecom_na.val = (uint8_t *)eval_na.val;
attr->ecommunity = ecommunity_merge(attr->ecommunity,
&ecom_na);
}
attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
}
@ -1089,6 +1101,7 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
{
struct bgp_info *old_select, *new_select;
struct bgp_info_pair old_and_new;
struct prefix_evpn *evp;
afi_t afi = AFI_L2VPN;
safi_t safi = SAFI_EVPN;
int ret = 0;
@ -1100,6 +1113,7 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
old_select = old_and_new.old;
new_select = old_and_new.new;
evp = (struct prefix_evpn *)&rn->p;
/* If the best path hasn't changed - see if there is still something to
* update
* to zebra RIB.
@ -1115,6 +1129,10 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
if (old_select->attr->default_gw)
SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
if (is_evpn_prefix_ipaddr_v6(evp) &&
old_select->attr->router_flag)
SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
ret = evpn_zebra_install(
bgp, vpn, (struct prefix_evpn *)&rn->p,
old_select->attr->nexthop, flags);
@ -1148,6 +1166,10 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
if (new_select->attr->default_gw)
SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
if (is_evpn_prefix_ipaddr_v6(evp) &&
new_select->attr->router_flag)
SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
ret = evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p,
new_select->attr->nexthop, flags);
/* If an old best existed and it was a "local" route, the only
@ -1695,6 +1717,8 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
attr.sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) ? 1 : 0;
attr.default_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW) ? 1 : 0;
attr.router_flag = CHECK_FLAG(flags,
ZEBRA_MACIP_TYPE_ROUTER_FLAG) ? 1 : 0;
/* PMSI is only needed for type-3 routes */
if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE)
@ -1993,11 +2017,13 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
&attr_sticky, 0, 1, &ri,
0);
else if (evpn_route_is_def_gw(bgp, rn))
else if (evpn_route_is_def_gw(bgp, rn)) {
if (is_evpn_prefix_ipaddr_v6(evp))
attr_def_gw.router_flag = 1;
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
&attr_def_gw, 0, 1, &ri,
0);
else
} else
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
&attr, 0, 1, &ri, 0);
}

View File

@ -311,6 +311,16 @@ static inline void encode_mac_mobility_extcomm(int static_mac, uint32_t seq,
eval->val[7] = seq & 0xff;
}
static inline void encode_na_flag_extcomm(struct ecommunity_val *eval,
uint8_t na_flag)
{
memset(eval, 0, sizeof(*eval));
eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ND;
if (na_flag)
eval->val[2] |= ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG;
}
static inline void ip_prefix_from_type5_prefix(struct prefix_evpn *evp,
struct prefix *ip)
{

View File

@ -448,6 +448,8 @@ enum zapi_iptable_notify_owner {
/* Zebra MAC types */
#define ZEBRA_MACIP_TYPE_STICKY 0x01 /* Sticky MAC*/
#define ZEBRA_MACIP_TYPE_GW 0x02 /* gateway (SVI) mac*/
#define ZEBRA_MACIP_TYPE_ROUTER_FLAG 0x04 /* Router Flag - proxy NA */
#define ZEBRA_MACIP_TYPE_OVERRIDE_FLAG 0x08 /* Override Flag */
struct zclient_options {
bool receive_notify;

View File

@ -122,7 +122,7 @@ extern int kernel_del_mac(struct interface *ifp, vlanid_t vid,
int local);
extern int kernel_add_neigh(struct interface *ifp, struct ipaddr *ip,
struct ethaddr *mac);
struct ethaddr *mac, uint8_t flags);
extern int kernel_del_neigh(struct interface *ifp, struct ipaddr *ip);
/*

View File

@ -2159,6 +2159,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
char buf2[INET6_ADDRSTRLEN];
int mac_present = 0;
uint8_t ext_learned;
uint8_t router_flag;
ndm = NLMSG_DATA(h);
@ -2249,6 +2250,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
}
ext_learned = (ndm->ndm_flags & NTF_EXT_LEARNED) ? 1 : 0;
router_flag = (ndm->ndm_flags & NTF_ROUTER) ? 1 : 0;
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
@ -2271,7 +2273,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
if (ndm->ndm_state & NUD_VALID)
return zebra_vxlan_handle_kernel_neigh_update(
ifp, link_if, &ip, &mac, ndm->ndm_state,
ext_learned);
ext_learned, router_flag);
return zebra_vxlan_handle_kernel_neigh_del(ifp, link_if, &ip);
}
@ -2405,7 +2407,8 @@ int netlink_neigh_change(struct nlmsghdr *h, ns_id_t ns_id)
}
static int netlink_neigh_update2(struct interface *ifp, struct ipaddr *ip,
struct ethaddr *mac, uint32_t flags, int cmd)
struct ethaddr *mac, uint8_t flags,
uint16_t state, int cmd)
{
struct {
struct nlmsghdr n;
@ -2428,11 +2431,10 @@ static int netlink_neigh_update2(struct interface *ifp, struct ipaddr *ip,
req.n.nlmsg_flags |= (NLM_F_CREATE | NLM_F_REPLACE);
req.n.nlmsg_type = cmd; // RTM_NEWNEIGH or RTM_DELNEIGH
req.ndm.ndm_family = IS_IPADDR_V4(ip) ? AF_INET : AF_INET6;
req.ndm.ndm_state = flags;
req.ndm.ndm_state = state;
req.ndm.ndm_ifindex = ifp->ifindex;
req.ndm.ndm_type = RTN_UNICAST;
req.ndm.ndm_flags = NTF_EXT_LEARNED;
req.ndm.ndm_flags = flags;
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);
@ -2440,12 +2442,12 @@ static int netlink_neigh_update2(struct interface *ifp, struct ipaddr *ip,
addattr_l(&req.n, sizeof(req), NDA_LLADDR, mac, 6);
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("Tx %s family %s IF %s(%u) Neigh %s MAC %s",
zlog_debug("Tx %s family %s IF %s(%u) Neigh %s MAC %s flags 0x%x",
nl_msg_type_to_str(cmd),
nl_family_to_str(req.ndm.ndm_family), ifp->name,
ifp->ifindex, ipaddr2str(ip, buf, sizeof(buf)),
mac ? prefix_mac2str(mac, buf2, sizeof(buf2))
: "null");
: "null", flags);
return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
0);
@ -2466,14 +2468,15 @@ int kernel_del_mac(struct interface *ifp, vlanid_t vid, struct ethaddr *mac,
}
int kernel_add_neigh(struct interface *ifp, struct ipaddr *ip,
struct ethaddr *mac)
struct ethaddr *mac, uint8_t flags)
{
return netlink_neigh_update2(ifp, ip, mac, NUD_NOARP, RTM_NEWNEIGH);
return netlink_neigh_update2(ifp, ip, mac, flags,
NUD_NOARP, RTM_NEWNEIGH);
}
int kernel_del_neigh(struct interface *ifp, struct ipaddr *ip)
{
return netlink_neigh_update2(ifp, ip, NULL, 0, RTM_DELNEIGH);
return netlink_neigh_update2(ifp, ip, NULL, 0, 0, RTM_DELNEIGH);
}
/*

View File

@ -462,7 +462,7 @@ int kernel_del_mac(struct interface *ifp, vlanid_t vid, struct ethaddr *mac,
}
int kernel_add_neigh(struct interface *ifp, struct ipaddr *ip,
struct ethaddr *mac)
struct ethaddr *mac, uint8_t flags)
{
return 0;
}

View File

@ -33,6 +33,9 @@
#include "jhash.h"
#include "vlan.h"
#include "vxlan.h"
#ifdef GNU_LINUX
#include <linux/neighbour.h>
#endif
#include "zebra/rib.h"
#include "zebra/rt.h"
@ -282,6 +285,7 @@ static void zvni_find_neigh_addr_width(struct hash_backet *backet, void *ctxt)
ipaddr2str(&n->ip, buf, sizeof(buf)), width = strlen(buf);
if (width > wctx->addr_width)
wctx->addr_width = width;
}
/*
@ -327,6 +331,10 @@ static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
else
json_object_boolean_true_add(json, "defaultGateway");
}
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)) {
if (!json)
vty_out(vty, " Router");
}
if (json == NULL)
vty_out(vty, "\n");
}
@ -432,11 +440,11 @@ static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
return;
}
num_neigh = hashcount(zvni->neigh_table);
if (json == NULL)
if (json == NULL) {
vty_out(vty,
"\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
zvni->vni, num_neigh);
else {
} else {
json_vni = json_object_new_object();
json_object_int_add(json_vni, "numArpNd", num_neigh);
snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
@ -458,9 +466,10 @@ static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
wctx.json = json_vni;
hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
if (json == NULL)
if (json == NULL) {
vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
"Type", "MAC", "Remote VTEP");
}
hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
if (json)
@ -1556,6 +1565,9 @@ static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_DEF_GW))
SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
/* Set router flag (R-bit) based on local neigh entry add */
if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_ROUTER_FLAG))
SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
ZEBRA_MACIP_ADD);
@ -1579,6 +1591,8 @@ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
struct zebra_if *zif;
struct zebra_l2info_vxlan *vxl;
struct interface *vlan_if;
uint8_t flags;
int ret = 0;
if (!(n->flags & ZEBRA_NEIGH_REMOTE))
return 0;
@ -1591,8 +1605,13 @@ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
if (!vlan_if)
return -1;
return kernel_add_neigh(vlan_if, &n->ip, &n->emac);
#ifdef GNU_LINUX
flags = NTF_EXT_LEARNED;
if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
flags |= NTF_ROUTER;
ret = kernel_add_neigh(vlan_if, &n->ip, &n->emac, flags);
#endif
return ret;
}
/*
@ -1814,6 +1833,9 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
/* Set "local" forwarding info. */
SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
/* Set Router flag (R-bit) */
if (ip->ipa_type == IPADDR_V6)
SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
memcpy(&n->emac, macaddr, ETH_ALEN);
n->ifindex = ifp->ifindex;
@ -1823,10 +1845,10 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
"SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP",
"SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP with flags 0x%x",
ifp->name, ifp->ifindex, zvni->vni,
prefix_mac2str(macaddr, buf, sizeof(buf)),
ipaddr2str(ip, buf2, sizeof(buf2)));
ipaddr2str(ip, buf2, sizeof(buf2)), n->flags);
zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags);
@ -1969,7 +1991,8 @@ static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet,
static int zvni_local_neigh_update(zebra_vni_t *zvni,
struct interface *ifp,
struct ipaddr *ip,
struct ethaddr *macaddr)
struct ethaddr *macaddr,
uint8_t router_flag)
{
char buf[ETHER_ADDR_STRLEN];
char buf2[INET6_ADDRSTRLEN];
@ -2087,15 +2110,19 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
return 0;
}
/*Set router flag (R-bit) */
if (router_flag)
SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
/* Inform BGP. */
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("Neigh %s (MAC %s) is now ACTIVE on L2-VNI %u",
zlog_debug("Neigh %s (MAC %s) is now ACTIVE on L2-VNI %u with flags 0x%x",
ipaddr2str(ip, buf2, sizeof(buf2)),
prefix_mac2str(macaddr, buf, sizeof(buf)),
zvni->vni);
zvni->vni, n->flags);
ZEBRA_NEIGH_SET_ACTIVE(n);
return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, 0);
return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags);
}
static int zvni_remote_neigh_update(zebra_vni_t *zvni,
@ -3366,14 +3393,22 @@ static int zl3vni_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
*/
static int zl3vni_nh_install(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
{
uint8_t flags;
int ret = 0;
if (!is_l3vni_oper_up(zl3vni))
return -1;
if (!(n->flags & ZEBRA_NEIGH_REMOTE)
|| !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
return 0;
return kernel_add_neigh(zl3vni->svi_if, &n->ip, &n->emac);
#ifdef GNU_LINUX
flags = NTF_EXT_LEARNED;
if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
flags |= NTF_ROUTER;
ret = kernel_add_neigh(zl3vni->svi_if, &n->ip, &n->emac, flags);
#endif
return ret;
}
/*
@ -4517,9 +4552,11 @@ void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
wctx.zvni = zvni;
wctx.vty = vty;
wctx.addr_width = 15;
wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
wctx.r_vtep_ip = vtep_ip;
wctx.json = json;
hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
if (use_json) {
@ -4948,7 +4985,8 @@ int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
struct ipaddr *ip,
struct ethaddr *macaddr,
uint16_t state,
uint8_t ext_learned)
uint8_t ext_learned,
uint8_t router_flag)
{
char buf[ETHER_ADDR_STRLEN];
char buf2[INET6_ADDRSTRLEN];
@ -4979,7 +5017,8 @@ int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
/* Is this about a local neighbor or a remote one? */
if (!ext_learned)
return zvni_local_neigh_update(zvni, ifp, ip, macaddr);
return zvni_local_neigh_update(zvni, ifp, ip, macaddr,
router_flag);
return zvni_remote_neigh_update(zvni, ifp, ip, macaddr, state);
}
@ -5366,6 +5405,10 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
n->r_vtep_ip = vtep_ip;
SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
/* Set router flag (R-bit) to this Neighbor entry */
if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
/* Install the entry. */
zvni_neigh_install(zvni, n);
}

View File

@ -124,7 +124,8 @@ extern int zebra_vxlan_svi_down(struct interface *ifp,
struct interface *link_if);
extern int zebra_vxlan_handle_kernel_neigh_update(
struct interface *ifp, struct interface *link_if, struct ipaddr *ip,
struct ethaddr *macaddr, uint16_t state, uint8_t ext_learned);
struct ethaddr *macaddr, uint16_t state, uint8_t ext_learned,
uint8_t router_flag);
extern int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp,
struct interface *link_if,
struct ipaddr *ip);

View File

@ -331,6 +331,7 @@ struct zebra_neigh_t_ {
#define ZEBRA_NEIGH_REMOTE 0x02
#define ZEBRA_NEIGH_REMOTE_NH 0x04 /* neigh entry for remote vtep */
#define ZEBRA_NEIGH_DEF_GW 0x08
#define ZEBRA_NEIGH_ROUTER_FLAG 0x10
enum zebra_neigh_state state;