mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 19:39:28 +00:00
Merge pull request #2665 from chiragshah6/evpn_dev
bgpd: support evpn nd ext community
This commit is contained in:
commit
bbc7adf1b4
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user