return -1;
return 0;
}
+
+extern bool is_zero_gw_ip(const union gw_addr *gw_ip, const afi_t afi)
+{
+ if (afi == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED(&gw_ip->ipv6))
+ return true;
+
+ if (afi == AF_INET && gw_ip->ipv4.s_addr == INADDR_ANY)
+ return true;
+
+ return false;
+}
+
+extern bool is_zero_esi(const struct eth_segment_id *esi)
+{
+ int i;
+
+ for (i = 0; i < ESI_LEN; i++)
+ if (esi->val[i])
+ return false;
+
+ return true;
+}
extern void bgp_attr_evpn_na_flag(struct attr *attr, uint8_t *router_flag);
+extern bool is_zero_gw_ip(const union gw_addr *gw_ip, afi_t afi);
+
+extern bool is_zero_esi(const struct eth_segment_id *esi);
#endif /* _QUAGGA_BGP_ATTR_EVPN_H */
uint32_t eth_tag;
mpls_label_t label; /* holds the VNI as in the packet */
int ret;
+ afi_t gw_afi;
+ bool is_valid_update = false;
/* Type-5 route should be 34 or 58 bytes:
* RD (8), ESI (10), Eth Tag (4), IP len (1), IP (4 or 16),
pfx += 4;
memcpy(&evpn.gw_ip.ipv4, pfx, 4);
pfx += 4;
+ gw_afi = AF_INET;
} else {
SET_IPADDR_V6(&p.prefix.prefix_addr.ip);
memcpy(&p.prefix.prefix_addr.ip.ipaddr_v6, pfx, 16);
pfx += 16;
memcpy(&evpn.gw_ip.ipv6, pfx, 16);
pfx += 16;
+ gw_afi = AF_INET6;
}
/* Get the VNI (in MPLS label field). Stored as bytes here. */
* field
*/
+ if (attr) {
+ is_valid_update = true;
+ if (is_zero_mac(&attr->rmac) && is_zero_esi(&evpn.eth_s_id) &&
+ is_zero_gw_ip(&evpn.gw_ip, gw_afi))
+ is_valid_update = false;
+
+ if (is_mcast_mac(&attr->rmac) || is_bcast_mac(&attr->rmac))
+ is_valid_update = false;
+ }
+
/* Process the route. */
- if (attr)
+ if (is_valid_update)
ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
&prd, &label, 1, 0, &evpn);
return 1;
}
+bool is_bcast_mac(const struct ethaddr *mac)
+{
+ int i = 0;
+
+ for (i = 0; i < ETH_ALEN; i++)
+ if (mac->octet[i] != 0xFF)
+ return false;
+
+ return true;
+}
+
+bool is_mcast_mac(const struct ethaddr *mac)
+{
+ if ((mac->octet[0] & 0x01) == 0x01)
+ return true;
+
+ return false;
+}
+
unsigned int prefix_bit(const uint8_t *prefix, const uint16_t prefixlen)
{
unsigned int offset = prefixlen / 8;
extern const char *inet6_ntoa(struct in6_addr);
extern int is_zero_mac(const struct ethaddr *mac);
+extern bool is_mcast_mac(const struct ethaddr *mac);
+extern bool is_bcast_mac(const struct ethaddr *mac);
extern int prefix_str2mac(const char *str, struct ethaddr *mac);
extern char *prefix_mac2str(const struct ethaddr *mac, char *buf, int size);