mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 21:39:38 +00:00
Merge branch 'frr/pull/822' ("EVPN fixes")
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
commit
695bb8f0d1
@ -2606,10 +2606,9 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi,
|
||||
stream_putc(s, pkt_safi); /* SAFI */
|
||||
|
||||
/* Nexthop AFI */
|
||||
if (afi == AFI_IP && safi == SAFI_UNICAST) {
|
||||
if (afi == AFI_IP
|
||||
&& (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
|
||||
nh_afi = peer_cap_enhe(peer, afi, safi) ? AFI_IP6 : AFI_IP;
|
||||
} else if (safi == SAFI_LABELED_UNICAST)
|
||||
nh_afi = afi;
|
||||
else
|
||||
nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->mp_nexthop_len);
|
||||
|
||||
@ -2800,9 +2799,8 @@ static void bgp_packet_mpattr_tea(struct bgp *bgp, struct peer *peer,
|
||||
|
||||
if (attrlenfield > 0xff) {
|
||||
/* 2-octet length field */
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, attrtype);
|
||||
stream_putw(s, attrlenfield & 0xffff);
|
||||
} else {
|
||||
@ -3040,15 +3038,14 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
|
||||
if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY)
|
||||
&& (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) {
|
||||
if (attr->community->size * 4 > 255) {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_COMMUNITIES);
|
||||
stream_putw(s, attr->community->size * 4);
|
||||
} else {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_COMMUNITIES);
|
||||
stream_putc(s, attr->community->size * 4);
|
||||
}
|
||||
@ -3062,15 +3059,14 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
|
||||
PEER_FLAG_SEND_LARGE_COMMUNITY)
|
||||
&& (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))) {
|
||||
if (attr->lcommunity->size * 12 > 255) {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
|
||||
stream_putw(s, attr->lcommunity->size * 12);
|
||||
} else {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
|
||||
stream_putc(s, attr->lcommunity->size * 12);
|
||||
}
|
||||
@ -3122,16 +3118,14 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
|
||||
if (peer->sort == BGP_PEER_IBGP
|
||||
|| peer->sort == BGP_PEER_CONFED) {
|
||||
if (attr->ecommunity->size * 8 > 255) {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
|
||||
stream_putw(s, attr->ecommunity->size * 8);
|
||||
} else {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
|
||||
stream_putc(s, attr->ecommunity->size * 8);
|
||||
}
|
||||
@ -3197,9 +3191,8 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
|
||||
label_index = attr->label_index;
|
||||
|
||||
if (label_index != BGP_INVALID_LABEL_INDEX) {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_PREFIX_SID);
|
||||
stream_putc(s, 10);
|
||||
stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX);
|
||||
@ -3227,9 +3220,8 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
|
||||
*/
|
||||
aspath = aspath_delete_confed_seq(aspath);
|
||||
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_AS4_PATH);
|
||||
aspath_sizep = stream_get_endp(s);
|
||||
stream_putw(s, 0);
|
||||
@ -3414,15 +3406,14 @@ void bgp_dump_routes_attr(struct stream *s, struct attr *attr,
|
||||
/* Community attribute. */
|
||||
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
|
||||
if (attr->community->size * 4 > 255) {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_COMMUNITIES);
|
||||
stream_putw(s, attr->community->size * 4);
|
||||
} else {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_COMMUNITIES);
|
||||
stream_putc(s, attr->community->size * 4);
|
||||
}
|
||||
@ -3432,15 +3423,14 @@ void bgp_dump_routes_attr(struct stream *s, struct attr *attr,
|
||||
/* Large Community attribute. */
|
||||
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
|
||||
if (attr->lcommunity->size * 12 > 255) {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
|
||||
stream_putw(s, attr->lcommunity->size * 12);
|
||||
} else {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
|
||||
stream_putc(s, attr->lcommunity->size * 12);
|
||||
}
|
||||
@ -3485,9 +3475,8 @@ void bgp_dump_routes_attr(struct stream *s, struct attr *attr,
|
||||
/* Prefix SID */
|
||||
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
|
||||
if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_PREFIX_SID);
|
||||
stream_putc(s, 10);
|
||||
stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX);
|
||||
|
@ -169,7 +169,7 @@ extern int bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag,
|
||||
prefix_copy(src, dst);
|
||||
memset(dst, 0, sizeof(struct prefix));
|
||||
p_evpn_p = &(dst->u.prefix_evpn);
|
||||
dst->family = AF_ETHERNET;
|
||||
dst->family = AF_EVPN;
|
||||
p_evpn_p->route_type = evpn_type;
|
||||
if (evpn_type == BGP_EVPN_IP_PREFIX_ROUTE) {
|
||||
p_evpn_p->eth_tag = eth_tag;
|
||||
|
@ -347,9 +347,9 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
s = zclient->obuf;
|
||||
stream_reset(s);
|
||||
|
||||
zclient_create_header(
|
||||
s, add ? ZEBRA_REMOTE_MACIP_ADD : ZEBRA_REMOTE_MACIP_DEL,
|
||||
bgp->vrf_id);
|
||||
zclient_create_header(s, add ? ZEBRA_REMOTE_MACIP_ADD
|
||||
: ZEBRA_REMOTE_MACIP_DEL,
|
||||
bgp->vrf_id);
|
||||
stream_putl(s, vpn->vni);
|
||||
stream_put(s, &p->prefix.mac.octet, ETH_ALEN); /* Mac Addr */
|
||||
/* IP address length and IP address, if any. */
|
||||
@ -400,9 +400,9 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
s = zclient->obuf;
|
||||
stream_reset(s);
|
||||
|
||||
zclient_create_header(
|
||||
s, add ? ZEBRA_REMOTE_VTEP_ADD : ZEBRA_REMOTE_VTEP_DEL,
|
||||
bgp->vrf_id);
|
||||
zclient_create_header(s, add ? ZEBRA_REMOTE_VTEP_ADD
|
||||
: ZEBRA_REMOTE_VTEP_DEL,
|
||||
bgp->vrf_id);
|
||||
stream_putl(s, vpn->vni);
|
||||
if (IS_EVPN_PREFIX_IPADDR_V4(p))
|
||||
stream_put_in_addr(s, &p->prefix.ip.ipaddr_v4);
|
||||
@ -472,7 +472,7 @@ static void add_mac_mobility_to_attr(u_int32_t seq_num, struct attr *attr)
|
||||
{
|
||||
struct ecommunity ecom_tmp;
|
||||
struct ecommunity_val eval;
|
||||
struct ecommunity *ecom_mm;
|
||||
u_int8_t *ecom_val_ptr;
|
||||
int i;
|
||||
u_int8_t *pnt;
|
||||
int type = 0;
|
||||
@ -482,7 +482,7 @@ static void add_mac_mobility_to_attr(u_int32_t seq_num, struct attr *attr)
|
||||
encode_mac_mobility_extcomm(0, seq_num, &eval);
|
||||
|
||||
/* Find current MM ecommunity */
|
||||
ecom_mm = NULL;
|
||||
ecom_val_ptr = NULL;
|
||||
|
||||
if (attr->ecommunity) {
|
||||
for (i = 0; i < attr->ecommunity->size; i++) {
|
||||
@ -493,17 +493,17 @@ static void add_mac_mobility_to_attr(u_int32_t seq_num, struct attr *attr)
|
||||
if (type == ECOMMUNITY_ENCODE_EVPN
|
||||
&& sub_type
|
||||
== ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY) {
|
||||
ecom_mm = (struct ecommunity *)
|
||||
attr->ecommunity->val
|
||||
+ (i * 8);
|
||||
ecom_val_ptr =
|
||||
(u_int8_t *)(attr->ecommunity->val
|
||||
+ (i * 8));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the existing MM ecommunity */
|
||||
if (ecom_mm) {
|
||||
memcpy(ecom_mm->val, eval.val, sizeof(char) * ECOMMUNITY_SIZE);
|
||||
if (ecom_val_ptr) {
|
||||
memcpy(ecom_val_ptr, eval.val, sizeof(char) * ECOMMUNITY_SIZE);
|
||||
}
|
||||
/* Add MM to existing */
|
||||
else {
|
||||
@ -704,7 +704,7 @@ static int evpn_route_is_sticky(struct bgp *bgp, struct bgp_node *rn)
|
||||
static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
afi_t afi, safi_t safi, struct bgp_node *rn,
|
||||
struct attr *attr, int add, int vni_table,
|
||||
struct bgp_info **ri)
|
||||
struct bgp_info **ri, u_char flags)
|
||||
{
|
||||
struct bgp_info *tmp_ri;
|
||||
struct bgp_info *local_ri, *remote_ri;
|
||||
@ -751,8 +751,11 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
* remote, we have to initiate appropriate MAC mobility steps.
|
||||
* This
|
||||
* is applicable when updating the VNI routing table.
|
||||
* We need to skip mobility steps for g/w macs (local mac on g/w
|
||||
* SVI) advertised in EVPN.
|
||||
* This will ensure that local routes are preferred for g/w macs
|
||||
*/
|
||||
if (remote_ri) {
|
||||
if (remote_ri && !CHECK_FLAG(flags, ZEBRA_MAC_TYPE_GW)) {
|
||||
u_int32_t cur_seqnum;
|
||||
|
||||
/* Add MM extended community to route. */
|
||||
@ -811,7 +814,7 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
* and schedule for processing.
|
||||
*/
|
||||
static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
struct prefix_evpn *p, u_char sticky)
|
||||
struct prefix_evpn *p, u_char flags)
|
||||
{
|
||||
struct bgp_node *rn;
|
||||
struct attr attr;
|
||||
@ -828,7 +831,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
attr.nexthop = vpn->originator_ip;
|
||||
attr.mp_nexthop_global_in = vpn->originator_ip;
|
||||
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
|
||||
attr.sticky = sticky;
|
||||
attr.sticky = CHECK_FLAG(flags, ZEBRA_MAC_TYPE_STICKY) ? 1 : 0;
|
||||
|
||||
/* Set up RT and ENCAP extended community. */
|
||||
build_evpn_route_extcomm(vpn, &attr);
|
||||
@ -839,7 +842,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
|
||||
/* Create or update route entry. */
|
||||
route_change = update_evpn_route_entry(bgp, vpn, afi, safi, rn, &attr,
|
||||
1, 1, &ri);
|
||||
1, 1, &ri, flags);
|
||||
assert(ri);
|
||||
attr_new = ri->attr;
|
||||
|
||||
@ -860,7 +863,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
|
||||
(struct prefix *)p, &vpn->prd);
|
||||
update_evpn_route_entry(bgp, vpn, afi, safi, rn, attr_new, 1, 0,
|
||||
&global_ri);
|
||||
&global_ri, flags);
|
||||
|
||||
/* Schedule for processing and unlock node. */
|
||||
bgp_process(bgp, rn, afi, safi);
|
||||
@ -998,10 +1001,10 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
|
||||
if (evpn_route_is_sticky(bgp, rn))
|
||||
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
|
||||
&attr_sticky, 0, 1, &ri);
|
||||
&attr_sticky, 0, 1, &ri, 0);
|
||||
else
|
||||
update_evpn_route_entry(bgp, vpn, afi, safi, rn, &attr,
|
||||
0, 1, &ri);
|
||||
0, 1, &ri, 0);
|
||||
|
||||
/* If a local route exists for this prefix, we need to update
|
||||
* the global routing table too.
|
||||
@ -1022,7 +1025,7 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
(struct prefix *)evp, &vpn->prd);
|
||||
assert(rd_rn);
|
||||
update_evpn_route_entry(bgp, vpn, afi, safi, rd_rn, attr_new, 0,
|
||||
0, &global_ri);
|
||||
0, &global_ri, 0);
|
||||
|
||||
/* Schedule for processing and unlock node. */
|
||||
bgp_process(bgp, rd_rn, afi, safi);
|
||||
@ -1190,6 +1193,12 @@ static int handle_tunnel_ip_change(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
{
|
||||
struct prefix_evpn p;
|
||||
|
||||
/* If VNI is not live, we only need to update the originator ip */
|
||||
if (!is_vni_live(vpn)) {
|
||||
vpn->originator_ip = originator_ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Need to withdraw type-3 route as the originator IP is part
|
||||
* of the key.
|
||||
*/
|
||||
@ -1631,8 +1640,8 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
|
||||
global_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
|
||||
(struct prefix *)&p, &vpn->prd);
|
||||
update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, 0,
|
||||
&ri);
|
||||
update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, 0, &ri,
|
||||
0);
|
||||
|
||||
/* Schedule for processing and unlock node. */
|
||||
bgp_process(bgp, global_rn, afi, safi);
|
||||
@ -1665,7 +1674,7 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
(struct prefix *)evp, &vpn->prd);
|
||||
assert(global_rn);
|
||||
update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1,
|
||||
0, &global_ri);
|
||||
0, &global_ri, 0);
|
||||
|
||||
/* Schedule for processing and unlock node. */
|
||||
bgp_process(bgp, global_rn, afi, safi);
|
||||
@ -1798,7 +1807,7 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
|
||||
|
||||
/* Make EVPN prefix. */
|
||||
memset(&p, 0, sizeof(struct prefix_evpn));
|
||||
p.family = AF_ETHERNET;
|
||||
p.family = AF_EVPN;
|
||||
p.prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
|
||||
p.prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
|
||||
|
||||
@ -1887,7 +1896,7 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
|
||||
|
||||
/* Make EVPN prefix. */
|
||||
memset(&p, 0, sizeof(struct prefix_evpn));
|
||||
p.family = AF_ETHERNET;
|
||||
p.family = AF_EVPN;
|
||||
p.prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
|
||||
p.prefix.route_type = BGP_EVPN_IMET_ROUTE;
|
||||
|
||||
@ -1952,7 +1961,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
|
||||
|
||||
/* Make EVPN prefix. */
|
||||
memset(&p, 0, sizeof(struct prefix_evpn));
|
||||
p.family = AF_ETHERNET;
|
||||
p.family = AF_EVPN;
|
||||
p.prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE;
|
||||
|
||||
/* Additional information outside of prefix - ESI and GW IP */
|
||||
@ -2021,7 +2030,7 @@ static void evpn_mpattr_encode_type5(struct stream *s, struct prefix *p,
|
||||
struct evpn_addr *p_evpn_p;
|
||||
|
||||
memset(&temp, 0, 16);
|
||||
if (p->family != AF_ETHERNET)
|
||||
if (p->family != AF_EVPN)
|
||||
return;
|
||||
p_evpn_p = &(p->u.prefix_evpn);
|
||||
|
||||
@ -2204,7 +2213,7 @@ char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len)
|
||||
PREFIX2STR_BUFFER));
|
||||
}
|
||||
} else {
|
||||
/* Currently, this is to cater to other AF_ETHERNET code. */
|
||||
/* For EVPN route types not supported yet. */
|
||||
}
|
||||
|
||||
return (buf);
|
||||
@ -2586,7 +2595,7 @@ int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
|
||||
* Handle add of a local MACIP.
|
||||
*/
|
||||
int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
|
||||
struct ipaddr *ip, u_char sticky)
|
||||
struct ipaddr *ip, u_char flags)
|
||||
{
|
||||
struct bgpevpn *vpn;
|
||||
struct prefix_evpn p;
|
||||
@ -2606,13 +2615,15 @@ int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
|
||||
|
||||
/* Create EVPN type-2 route and schedule for processing. */
|
||||
build_evpn_type2_prefix(&p, mac, ip);
|
||||
if (update_evpn_route(bgp, vpn, &p, sticky)) {
|
||||
if (update_evpn_route(bgp, vpn, &p, flags)) {
|
||||
char buf[ETHER_ADDR_STRLEN];
|
||||
char buf2[INET6_ADDRSTRLEN];
|
||||
|
||||
zlog_err(
|
||||
"%u:Failed to create Type-2 route, VNI %u %sMAC %s IP %s",
|
||||
bgp->vrf_id, vpn->vni, sticky ? "sticky" : "",
|
||||
"%u:Failed to create Type-2 route, VNI %u %s MAC %s IP %s",
|
||||
bgp->vrf_id, vpn->vni,
|
||||
CHECK_FLAG(flags, ZEBRA_MAC_TYPE_STICKY) ? "sticky gateway"
|
||||
: "",
|
||||
prefix_mac2str(mac, buf, sizeof(buf)),
|
||||
ipaddr2str(ip, buf2, sizeof(buf2)));
|
||||
return -1;
|
||||
@ -2671,14 +2682,15 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
|
||||
|
||||
/* Lookup VNI. If present and no change, exit. */
|
||||
vpn = bgp_evpn_lookup_vni(bgp, vni);
|
||||
if (vpn && is_vni_live(vpn)) {
|
||||
if (IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip))
|
||||
if (vpn) {
|
||||
if (is_vni_live(vpn)
|
||||
&& IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip))
|
||||
/* Probably some other param has changed that we don't
|
||||
* care about. */
|
||||
return 0;
|
||||
|
||||
/* Local tunnel endpoint IP address has changed */
|
||||
return handle_tunnel_ip_change(bgp, vpn, originator_ip);
|
||||
handle_tunnel_ip_change(bgp, vpn, originator_ip);
|
||||
}
|
||||
|
||||
/* Create or update as appropriate. */
|
||||
@ -2692,6 +2704,10 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
|
||||
}
|
||||
}
|
||||
|
||||
/* if the VNI is live already, there is nothibng more to do */
|
||||
if (is_vni_live(vpn))
|
||||
return 0;
|
||||
|
||||
/* Mark as "live" */
|
||||
SET_FLAG(vpn->flags, VNI_FLAG_LIVE);
|
||||
|
||||
|
@ -42,7 +42,7 @@ extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
|
||||
struct ethaddr *mac, struct ipaddr *ip);
|
||||
extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni,
|
||||
struct ethaddr *mac, struct ipaddr *ip,
|
||||
u_char sticky);
|
||||
u_char flags);
|
||||
extern int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni);
|
||||
extern int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
|
||||
struct in_addr originator_ip);
|
||||
|
@ -58,6 +58,9 @@ struct bgpevpn {
|
||||
#define VNI_FLAG_IMPRT_CFGD 0x8 /* Import RT is user configured */
|
||||
#define VNI_FLAG_EXPRT_CFGD 0x10 /* Export RT is user configured */
|
||||
|
||||
/* Flag to indicate if we are advertising the g/w mac ip for this VNI*/
|
||||
u_int8_t advertise_gw_macip;
|
||||
|
||||
/* Id for deriving the RD automatically for this VNI */
|
||||
u_int16_t rd_id;
|
||||
|
||||
@ -171,7 +174,7 @@ static inline void build_evpn_type2_prefix(struct prefix_evpn *p,
|
||||
struct ipaddr *ip)
|
||||
{
|
||||
memset(p, 0, sizeof(struct prefix_evpn));
|
||||
p->family = AF_ETHERNET;
|
||||
p->family = AF_EVPN;
|
||||
p->prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
|
||||
p->prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
|
||||
memcpy(&p->prefix.mac.octet, mac->octet, ETH_ALEN);
|
||||
@ -184,7 +187,7 @@ static inline void build_evpn_type3_prefix(struct prefix_evpn *p,
|
||||
struct in_addr originator_ip)
|
||||
{
|
||||
memset(p, 0, sizeof(struct prefix_evpn));
|
||||
p->family = AF_ETHERNET;
|
||||
p->family = AF_EVPN;
|
||||
p->prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
|
||||
p->prefix.route_type = BGP_EVPN_IMET_ROUTE;
|
||||
p->prefix.ip.ipa_type = IPADDR_V4;
|
||||
|
@ -195,6 +195,8 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn)
|
||||
vty_out(vty, " RD: %s\n",
|
||||
prefix_rd2str(&vpn->prd, buf1, RD_ADDRSTRLEN));
|
||||
vty_out(vty, " Originator IP: %s\n", inet_ntoa(vpn->originator_ip));
|
||||
vty_out(vty, " Advertise-gw-macip : %s\n",
|
||||
vpn->advertise_gw_macip ? "Yes" : "No");
|
||||
|
||||
vty_out(vty, " Import Route Target:\n");
|
||||
for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
|
||||
@ -1641,6 +1643,51 @@ static void evpn_show_all_vnis(struct vty *vty, struct bgp *bgp)
|
||||
vty);
|
||||
}
|
||||
|
||||
/*
|
||||
* evpn - enable advertisement of default g/w
|
||||
*/
|
||||
static void evpn_set_advertise_default_gw(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
{
|
||||
if (!vpn) {
|
||||
if (bgp->advertise_gw_macip)
|
||||
return;
|
||||
|
||||
bgp->advertise_gw_macip = 1;
|
||||
bgp_zebra_advertise_gw_macip(bgp, bgp->advertise_gw_macip, 0);
|
||||
} else {
|
||||
if (vpn->advertise_gw_macip)
|
||||
return;
|
||||
|
||||
vpn->advertise_gw_macip = 1;
|
||||
bgp_zebra_advertise_gw_macip(bgp, vpn->advertise_gw_macip,
|
||||
vpn->vni);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* evpn - disable advertisement of default g/w
|
||||
*/
|
||||
static void evpn_unset_advertise_default_gw(struct bgp *bgp,
|
||||
struct bgpevpn *vpn)
|
||||
{
|
||||
if (!vpn) {
|
||||
if (!bgp->advertise_gw_macip)
|
||||
return;
|
||||
|
||||
bgp->advertise_gw_macip = 0;
|
||||
bgp_zebra_advertise_gw_macip(bgp, bgp->advertise_gw_macip, 0);
|
||||
} else {
|
||||
if (!vpn->advertise_gw_macip)
|
||||
return;
|
||||
|
||||
vpn->advertise_gw_macip = 0;
|
||||
bgp_zebra_advertise_gw_macip(bgp, vpn->advertise_gw_macip,
|
||||
vpn->vni);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* EVPN (VNI advertisement) enabled. Register with zebra.
|
||||
*/
|
||||
@ -1700,6 +1747,9 @@ static void write_vni_config(struct vty *vty, struct bgpevpn *vpn, int *write)
|
||||
}
|
||||
}
|
||||
|
||||
if (vpn->advertise_gw_macip)
|
||||
vty_out(vty, " advertise-default-gw\n");
|
||||
|
||||
vty_out(vty, " exit-vni\n");
|
||||
}
|
||||
}
|
||||
@ -1712,6 +1762,77 @@ static void write_vni_config_for_entry(struct hash_backet *backet,
|
||||
}
|
||||
|
||||
#if defined(HAVE_CUMULUS)
|
||||
DEFUN (bgp_evpn_advertise_default_gw_vni,
|
||||
bgp_evpn_advertise_default_gw_vni_cmd,
|
||||
"advertise-default-gw",
|
||||
"Advertise defualt g/w mac-ip routes in EVPN for a VNI\n")
|
||||
{
|
||||
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
|
||||
VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
|
||||
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (!vpn)
|
||||
return CMD_WARNING;
|
||||
|
||||
evpn_set_advertise_default_gw(bgp, vpn);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_bgp_evpn_advertise_default_vni_gw,
|
||||
no_bgp_evpn_advertise_default_gw_vni_cmd,
|
||||
"no advertise-default-gw",
|
||||
NO_STR
|
||||
"Withdraw default g/w mac-ip routes from EVPN for a VNI\n")
|
||||
{
|
||||
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
|
||||
VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
|
||||
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (!vpn)
|
||||
return CMD_WARNING;
|
||||
|
||||
evpn_unset_advertise_default_gw(bgp, vpn);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DEFUN (bgp_evpn_advertise_default_gw,
|
||||
bgp_evpn_advertise_default_gw_cmd,
|
||||
"advertise-default-gw",
|
||||
"Advertise All defualt g/w mac-ip routes in EVPN\n")
|
||||
{
|
||||
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
|
||||
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
evpn_set_advertise_default_gw(bgp, NULL);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_bgp_evpn_advertise_default_gw,
|
||||
no_bgp_evpn_advertise_default_gw_cmd,
|
||||
"no advertise-default-gw",
|
||||
NO_STR
|
||||
"Withdraw All default g/w mac-ip routes from EVPN\n")
|
||||
{
|
||||
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
|
||||
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
evpn_unset_advertise_default_gw(bgp, NULL);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (bgp_evpn_advertise_all_vni,
|
||||
bgp_evpn_advertise_all_vni_cmd,
|
||||
"advertise-all-vni",
|
||||
@ -1739,86 +1860,95 @@ DEFUN (no_bgp_evpn_advertise_all_vni,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_bgp_evpn_vni,
|
||||
show_bgp_evpn_vni_cmd,
|
||||
"show bgp evpn vni",
|
||||
/*
|
||||
* Display VNI information - for all or a specific VNI
|
||||
*/
|
||||
DEFUN (show_bgp_l2vpn_evpn_vni,
|
||||
show_bgp_l2vpn_evpn_vni_cmd,
|
||||
"show bgp l2vpn evpn vni [(1-16777215)]",
|
||||
SHOW_STR
|
||||
BGP_STR
|
||||
L2VPN_HELP_STR
|
||||
EVPN_HELP_STR
|
||||
"Show VNI\n")
|
||||
{
|
||||
struct bgp *bgp;
|
||||
|
||||
bgp = bgp_get_default();
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
vty_out(vty, "Advertise All VNI flag: %s\n",
|
||||
bgp->advertise_all_vni ? "Enabled" : "Disabled");
|
||||
|
||||
evpn_show_all_vnis(vty, bgp);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_bgp_evpn_vni_num,
|
||||
show_bgp_evpn_vni_num_cmd,
|
||||
"show bgp evpn vni (1-16777215)",
|
||||
SHOW_STR
|
||||
BGP_STR
|
||||
"Address family modifier\n"
|
||||
"Show VNI\n"
|
||||
"VNI number\n")
|
||||
{
|
||||
vni_t vni;
|
||||
struct bgp *bgp;
|
||||
vni_t vni;
|
||||
int idx = 0;
|
||||
|
||||
bgp = bgp_get_default();
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
vni = strtoul(argv[4]->arg, NULL, 10);
|
||||
if (!argv_find(argv, argc, "evpn", &idx))
|
||||
return CMD_WARNING;
|
||||
|
||||
if (argc == ((idx + 1) + 1)) {
|
||||
vty_out(vty, "Advertise gateway macip flag: %s\n",
|
||||
bgp->advertise_gw_macip ? "Enabled" : "Disabled");
|
||||
|
||||
/* Display all VNIs */
|
||||
vty_out(vty, "Advertise All VNI flag: %s\n",
|
||||
bgp->advertise_all_vni ? "Enabled" : "Disabled");
|
||||
evpn_show_all_vnis(vty, bgp);
|
||||
} else {
|
||||
/* Display specific VNI */
|
||||
vni = strtoul(argv[argc - 1]->arg, NULL, 10);
|
||||
evpn_show_vni(vty, bgp, vni);
|
||||
}
|
||||
|
||||
evpn_show_vni(vty, bgp, vni);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* `show bgp evpn summary' commands. */
|
||||
DEFUN (show_bgp_evpn_summary,
|
||||
show_bgp_evpn_summary_cmd,
|
||||
"show bgp evpn summary [json]",
|
||||
/*
|
||||
* Display EVPN neighbor summary.
|
||||
*/
|
||||
DEFUN (show_bgp_l2vpn_evpn_summary,
|
||||
show_bgp_l2vpn_evpn_summary_cmd,
|
||||
"show bgp l2vpn evpn summary [json]",
|
||||
SHOW_STR
|
||||
BGP_STR
|
||||
"EVPN\n"
|
||||
L2VPN_HELP_STR
|
||||
EVPN_HELP_STR
|
||||
"Summary of BGP neighbor status\n"
|
||||
"JavaScript Object Notation\n")
|
||||
JSON_STR)
|
||||
{
|
||||
u_char uj = use_json(argc, argv);
|
||||
return bgp_show_summary_vty(vty, NULL, AFI_L2VPN, SAFI_EVPN, uj);
|
||||
}
|
||||
|
||||
/* Show bgp evpn route */
|
||||
DEFUN (show_bgp_evpn_route,
|
||||
show_bgp_evpn_route_cmd,
|
||||
"show bgp evpn route [type <macip|multicast>]",
|
||||
/*
|
||||
* Display global EVPN routing table.
|
||||
*/
|
||||
DEFUN (show_bgp_l2vpn_evpn_route,
|
||||
show_bgp_l2vpn_evpn_route_cmd,
|
||||
"show bgp l2vpn evpn route [type <macip|multicast>]",
|
||||
SHOW_STR
|
||||
BGP_STR
|
||||
"Address Family Modifier\n"
|
||||
"Display EVPN route information\n"
|
||||
L2VPN_HELP_STR
|
||||
EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"Specify Route type\n"
|
||||
"MAC-IP (Type-2) route\n"
|
||||
"Multicast (Type-3) route\n")
|
||||
{
|
||||
struct bgp *bgp;
|
||||
int idx = 0;
|
||||
int type = 0;
|
||||
|
||||
bgp = bgp_get_default();
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (argc == 6) {
|
||||
if (strncmp(argv[5]->arg, "ma", 2) == 0)
|
||||
if (!argv_find(argv, argc, "evpn", &idx))
|
||||
return CMD_WARNING;
|
||||
|
||||
if (argc == ((idx + 1) + 3)) {
|
||||
/* Specific type is requested */
|
||||
if (strncmp(argv[argc - 1]->arg, "ma", 2) == 0)
|
||||
type = BGP_EVPN_MAC_IP_ROUTE;
|
||||
else if (strncmp(argv[5]->arg, "mu", 2) == 0)
|
||||
else if (strncmp(argv[argc - 1]->arg, "mu", 2) == 0)
|
||||
type = BGP_EVPN_IMET_ROUTE;
|
||||
else
|
||||
return CMD_WARNING;
|
||||
@ -1828,13 +1958,17 @@ DEFUN (show_bgp_evpn_route,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_bgp_evpn_route_rd,
|
||||
show_bgp_evpn_route_rd_cmd,
|
||||
"show bgp evpn route rd ASN:nn_or_IP-address:nn [type <macip|multicast>]",
|
||||
/*
|
||||
* Display global EVPN routing table for specific RD.
|
||||
*/
|
||||
DEFUN (show_bgp_l2vpn_evpn_route_rd,
|
||||
show_bgp_l2vpn_evpn_route_rd_cmd,
|
||||
"show bgp l2vpn evpn route rd ASN:nn_or_IP-address:nn [type <macip|multicast>]",
|
||||
SHOW_STR
|
||||
BGP_STR
|
||||
"Address Family Modifier\n"
|
||||
"Display EVPN route information\n"
|
||||
L2VPN_HELP_STR
|
||||
EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"Route Distinguisher\n"
|
||||
"ASN:XX or A.B.C.D:XX\n"
|
||||
"Specify Route type\n"
|
||||
@ -1844,22 +1978,27 @@ DEFUN (show_bgp_evpn_route_rd,
|
||||
struct bgp *bgp;
|
||||
int ret;
|
||||
struct prefix_rd prd;
|
||||
int idx = 0;
|
||||
int type = 0;
|
||||
|
||||
bgp = bgp_get_default();
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
ret = str2prefix_rd(argv[5]->arg, &prd);
|
||||
if (!argv_find(argv, argc, "evpn", &idx))
|
||||
return CMD_WARNING;
|
||||
|
||||
ret = str2prefix_rd(argv[idx + 3]->arg, &prd);
|
||||
if (!ret) {
|
||||
vty_out(vty, "%% Malformed Route Distinguisher\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (argc == 8) {
|
||||
if (strncmp(argv[7]->arg, "ma", 2) == 0)
|
||||
if (argc == ((idx + 1) + 5)) {
|
||||
/* Specific type is requested */
|
||||
if (strncmp(argv[argc - 1]->arg, "ma", 2) == 0)
|
||||
type = BGP_EVPN_MAC_IP_ROUTE;
|
||||
else if (strncmp(argv[7]->arg, "mu", 2) == 0)
|
||||
else if (strncmp(argv[argc - 1]->arg, "mu", 2) == 0)
|
||||
type = BGP_EVPN_IMET_ROUTE;
|
||||
else
|
||||
return CMD_WARNING;
|
||||
@ -1869,13 +2008,17 @@ DEFUN (show_bgp_evpn_route_rd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_bgp_evpn_route_rd_macip,
|
||||
show_bgp_evpn_route_rd_macip_cmd,
|
||||
"show bgp evpn route rd ASN:nn_or_IP-address:nn mac WORD [ip WORD]",
|
||||
/*
|
||||
* Display global EVPN routing table for specific RD and MACIP.
|
||||
*/
|
||||
DEFUN (show_bgp_l2vpn_evpn_route_rd_macip,
|
||||
show_bgp_l2vpn_evpn_route_rd_macip_cmd,
|
||||
"show bgp l2vpn evpn route rd ASN:nn_or_IP-address:nn mac WORD [ip WORD]",
|
||||
SHOW_STR
|
||||
BGP_STR
|
||||
"Address Family Modifier\n"
|
||||
"Display EVPN route information\n"
|
||||
L2VPN_HELP_STR
|
||||
EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"Route Distinguisher\n"
|
||||
"ASN:XX or A.B.C.D:XX\n"
|
||||
"MAC\n"
|
||||
@ -1888,23 +2031,28 @@ DEFUN (show_bgp_evpn_route_rd_macip,
|
||||
struct prefix_rd prd;
|
||||
struct ethaddr mac;
|
||||
struct ipaddr ip;
|
||||
int idx = 0;
|
||||
|
||||
bgp = bgp_get_default();
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
ret = str2prefix_rd(argv[5]->arg, &prd);
|
||||
if (!argv_find(argv, argc, "evpn", &idx))
|
||||
return CMD_WARNING;
|
||||
|
||||
ret = str2prefix_rd(argv[idx + 3]->arg, &prd);
|
||||
if (!ret) {
|
||||
vty_out(vty, "%% Malformed Route Distinguisher\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
if (!prefix_str2mac(argv[7]->arg, &mac)) {
|
||||
if (!prefix_str2mac(argv[idx + 5]->arg, &mac)) {
|
||||
vty_out(vty, "%% Malformed MAC address\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
memset(&ip, 0, sizeof(ip));
|
||||
if (argc == 10 && argv[9]->arg != NULL) {
|
||||
if (str2ipaddr(argv[9]->arg, &ip) != 0) {
|
||||
if (argc == (idx + 1 + 7) && argv[argc - 1]->arg != NULL) {
|
||||
/* Specific MAC+IP requested */
|
||||
if (str2ipaddr(argv[argc - 1]->arg, &ip) != 0) {
|
||||
vty_out(vty, "%% Malformed IP address\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
@ -1914,13 +2062,17 @@ DEFUN (show_bgp_evpn_route_rd_macip,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_bgp_evpn_route_vni,
|
||||
show_bgp_evpn_route_vni_cmd,
|
||||
"show bgp evpn route vni (1-16777215) [<type <macip|multicast> | vtep A.B.C.D>]",
|
||||
/*
|
||||
* Display per-VNI EVPN routing table.
|
||||
*/
|
||||
DEFUN (show_bgp_l2vpn_evpn_route_vni,
|
||||
show_bgp_l2vpn_evpn_route_vni_cmd,
|
||||
"show bgp l2vpn evpn route vni (1-16777215) [<type <macip|multicast> | vtep A.B.C.D>]",
|
||||
SHOW_STR
|
||||
BGP_STR
|
||||
"Address Family Modifier\n"
|
||||
"Display EVPN route information\n"
|
||||
L2VPN_HELP_STR
|
||||
EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"VXLAN Network Identifier\n"
|
||||
"VNI number\n"
|
||||
"Specify Route type\n"
|
||||
@ -1933,25 +2085,29 @@ DEFUN (show_bgp_evpn_route_vni,
|
||||
struct bgp *bgp;
|
||||
struct in_addr vtep_ip;
|
||||
int type = 0;
|
||||
int idx = 0;
|
||||
|
||||
bgp = bgp_get_default();
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (!argv_find(argv, argc, "evpn", &idx))
|
||||
return CMD_WARNING;
|
||||
|
||||
vtep_ip.s_addr = 0;
|
||||
|
||||
vni = strtoul(argv[5]->arg, NULL, 10);
|
||||
vni = strtoul(argv[idx + 3]->arg, NULL, 10);
|
||||
|
||||
if (argc == 8 && argv[6]->arg) {
|
||||
if (strncmp(argv[6]->arg, "type", 4) == 0) {
|
||||
if (strncmp(argv[7]->arg, "ma", 2) == 0)
|
||||
if (argc == (idx + 1 + 5) && argv[idx + 4]->arg) {
|
||||
if (strncmp(argv[idx + 4]->arg, "type", 4) == 0) {
|
||||
if (strncmp(argv[idx + 5]->arg, "ma", 2) == 0)
|
||||
type = BGP_EVPN_MAC_IP_ROUTE;
|
||||
else if (strncmp(argv[7]->arg, "mu", 2) == 0)
|
||||
else if (strncmp(argv[idx + 5]->arg, "mu", 2) == 0)
|
||||
type = BGP_EVPN_IMET_ROUTE;
|
||||
else
|
||||
return CMD_WARNING;
|
||||
} else if (strncmp(argv[6]->arg, "vtep", 4) == 0) {
|
||||
if (!inet_aton(argv[7]->arg, &vtep_ip)) {
|
||||
} else if (strncmp(argv[idx + 4]->arg, "vtep", 4) == 0) {
|
||||
if (!inet_aton(argv[idx + 5]->arg, &vtep_ip)) {
|
||||
vty_out(vty, "%% Malformed VTEP IP address\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
@ -1963,13 +2119,17 @@ DEFUN (show_bgp_evpn_route_vni,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_bgp_evpn_route_vni_macip,
|
||||
show_bgp_evpn_route_vni_macip_cmd,
|
||||
"show bgp evpn route vni (1-16777215) mac WORD [ip WORD]",
|
||||
/*
|
||||
* Display per-VNI EVPN routing table for specific MACIP.
|
||||
*/
|
||||
DEFUN (show_bgp_l2vpn_evpn_route_vni_macip,
|
||||
show_bgp_l2vpn_evpn_route_vni_macip_cmd,
|
||||
"show bgp l2vpn evpn route vni (1-16777215) mac WORD [ip WORD]",
|
||||
SHOW_STR
|
||||
BGP_STR
|
||||
"Address Family Modifier\n"
|
||||
"Display EVPN route information\n"
|
||||
L2VPN_HELP_STR
|
||||
EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"VXLAN Network Identifier\n"
|
||||
"VNI number\n"
|
||||
"MAC\n"
|
||||
@ -1981,19 +2141,23 @@ DEFUN (show_bgp_evpn_route_vni_macip,
|
||||
struct bgp *bgp;
|
||||
struct ethaddr mac;
|
||||
struct ipaddr ip;
|
||||
int idx = 0;
|
||||
|
||||
bgp = bgp_get_default();
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
vni = strtoul(argv[5]->arg, NULL, 10);
|
||||
if (!prefix_str2mac(argv[7]->arg, &mac)) {
|
||||
if (!argv_find(argv, argc, "evpn", &idx))
|
||||
return CMD_WARNING;
|
||||
|
||||
vni = strtoul(argv[idx + 3]->arg, NULL, 10);
|
||||
if (!prefix_str2mac(argv[idx + 5]->arg, &mac)) {
|
||||
vty_out(vty, "%% Malformed MAC address\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
memset(&ip, 0, sizeof(ip));
|
||||
if (argc == 10 && argv[9]->arg != NULL) {
|
||||
if (str2ipaddr(argv[9]->arg, &ip) != 0) {
|
||||
if (argc == (idx + 1 + 7) && argv[idx + 7]->arg != NULL) {
|
||||
if (str2ipaddr(argv[idx + 7]->arg, &ip) != 0) {
|
||||
vty_out(vty, "%% Malformed IP address\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
@ -2003,13 +2167,17 @@ DEFUN (show_bgp_evpn_route_vni_macip,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_bgp_evpn_route_vni_multicast,
|
||||
show_bgp_evpn_route_vni_multicast_cmd,
|
||||
"show bgp evpn route vni (1-16777215) multicast A.B.C.D",
|
||||
/*
|
||||
* Display per-VNI EVPN routing table for specific multicast IP (remote VTEP).
|
||||
*/
|
||||
DEFUN (show_bgp_l2vpn_evpn_route_vni_multicast,
|
||||
show_bgp_l2vpn_evpn_route_vni_multicast_cmd,
|
||||
"show bgp l2vpn evpn route vni (1-16777215) multicast A.B.C.D",
|
||||
SHOW_STR
|
||||
BGP_STR
|
||||
"Address Family Modifier\n"
|
||||
"Display EVPN route information\n"
|
||||
L2VPN_HELP_STR
|
||||
EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"VXLAN Network Identifier\n"
|
||||
"VNI number\n"
|
||||
"Multicast (Type-3) route\n"
|
||||
@ -2019,13 +2187,17 @@ DEFUN (show_bgp_evpn_route_vni_multicast,
|
||||
struct bgp *bgp;
|
||||
int ret;
|
||||
struct in_addr orig_ip;
|
||||
int idx = 0;
|
||||
|
||||
bgp = bgp_get_default();
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
vni = strtoul(argv[5]->arg, NULL, 10);
|
||||
ret = inet_aton(argv[7]->arg, &orig_ip);
|
||||
if (!argv_find(argv, argc, "evpn", &idx))
|
||||
return CMD_WARNING;
|
||||
|
||||
vni = strtoul(argv[idx + 3]->arg, NULL, 10);
|
||||
ret = inet_aton(argv[idx + 5]->arg, &orig_ip);
|
||||
if (!ret) {
|
||||
vty_out(vty, "%% Malformed Originating Router IP address\n");
|
||||
return CMD_WARNING;
|
||||
@ -2035,13 +2207,17 @@ DEFUN (show_bgp_evpn_route_vni_multicast,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_bgp_evpn_route_vni_all,
|
||||
show_bgp_evpn_route_vni_all_cmd,
|
||||
"show bgp evpn route vni all [vtep A.B.C.D]",
|
||||
/*
|
||||
* Display per-VNI EVPN routing table - for all VNIs.
|
||||
*/
|
||||
DEFUN (show_bgp_l2vpn_evpn_route_vni_all,
|
||||
show_bgp_l2vpn_evpn_route_vni_all_cmd,
|
||||
"show bgp l2vpn evpn route vni all [vtep A.B.C.D]",
|
||||
SHOW_STR
|
||||
BGP_STR
|
||||
"Address Family Modifier\n"
|
||||
"Display EVPN route information\n"
|
||||
L2VPN_HELP_STR
|
||||
EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"VXLAN Network Identifier\n"
|
||||
"All VNIs\n"
|
||||
"Remote VTEP\n"
|
||||
@ -2049,14 +2225,18 @@ DEFUN (show_bgp_evpn_route_vni_all,
|
||||
{
|
||||
struct bgp *bgp;
|
||||
struct in_addr vtep_ip;
|
||||
int idx = 0;
|
||||
|
||||
bgp = bgp_get_default();
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (!argv_find(argv, argc, "evpn", &idx))
|
||||
return CMD_WARNING;
|
||||
|
||||
vtep_ip.s_addr = 0;
|
||||
if (argc == 8 && argv[7]->arg) {
|
||||
if (!inet_aton(argv[7]->arg, &vtep_ip)) {
|
||||
if (argc == (idx + 1 + 5) && argv[idx + 5]->arg) {
|
||||
if (!inet_aton(argv[idx + 5]->arg, &vtep_ip)) {
|
||||
vty_out(vty, "%% Malformed VTEP IP address\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
@ -2066,12 +2246,16 @@ DEFUN (show_bgp_evpn_route_vni_all,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_bgp_evpn_import_rt,
|
||||
show_bgp_evpn_import_rt_cmd,
|
||||
"show bgp evpn import-rt",
|
||||
/*
|
||||
* Display EVPN import route-target hash table
|
||||
*/
|
||||
DEFUN (show_bgp_l2vpn_evpn_import_rt,
|
||||
show_bgp_l2vpn_evpn_import_rt_cmd,
|
||||
"show bgp l2vpn evpn import-rt",
|
||||
SHOW_STR
|
||||
BGP_STR
|
||||
"Address family modifier\n"
|
||||
L2VPN_HELP_STR
|
||||
EVPN_HELP_STR
|
||||
"Show import route target\n")
|
||||
{
|
||||
struct bgp *bgp;
|
||||
@ -2084,6 +2268,97 @@ DEFUN (show_bgp_evpn_import_rt,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#if defined(HAVE_CUMULUS)
|
||||
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_vni, show_bgp_evpn_vni_cmd,
|
||||
"show bgp evpn vni [(1-16777215)]", SHOW_STR BGP_STR EVPN_HELP_STR
|
||||
"Show VNI\n"
|
||||
"VNI number\n")
|
||||
|
||||
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_summary, show_bgp_evpn_summary_cmd,
|
||||
"show bgp evpn summary [json]", SHOW_STR BGP_STR EVPN_HELP_STR
|
||||
"Summary of BGP neighbor status\n"
|
||||
JSON_STR)
|
||||
|
||||
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route, show_bgp_evpn_route_cmd,
|
||||
"show bgp evpn route [type <macip|multicast>]",
|
||||
SHOW_STR BGP_STR EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"Specify Route type\n"
|
||||
"MAC-IP (Type-2) route\n"
|
||||
"Multicast (Type-3) route\n")
|
||||
|
||||
ALIAS_HIDDEN(
|
||||
show_bgp_l2vpn_evpn_route_rd, show_bgp_evpn_route_rd_cmd,
|
||||
"show bgp evpn route rd ASN:nn_or_IP-address:nn [type <macip|multicast>]",
|
||||
SHOW_STR BGP_STR EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"Route Distinguisher\n"
|
||||
"ASN:XX or A.B.C.D:XX\n"
|
||||
"Specify Route type\n"
|
||||
"MAC-IP (Type-2) route\n"
|
||||
"Multicast (Type-3) route\n")
|
||||
|
||||
ALIAS_HIDDEN(
|
||||
show_bgp_l2vpn_evpn_route_rd_macip, show_bgp_evpn_route_rd_macip_cmd,
|
||||
"show bgp evpn route rd ASN:nn_or_IP-address:nn mac WORD [ip WORD]",
|
||||
SHOW_STR BGP_STR EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"Route Distinguisher\n"
|
||||
"ASN:XX or A.B.C.D:XX\n"
|
||||
"MAC\n"
|
||||
"MAC address (e.g., 00:e0:ec:20:12:62)\n"
|
||||
"IP\n"
|
||||
"IP address (IPv4 or IPv6)\n")
|
||||
|
||||
ALIAS_HIDDEN(
|
||||
show_bgp_l2vpn_evpn_route_vni, show_bgp_evpn_route_vni_cmd,
|
||||
"show bgp evpn route vni (1-16777215) [<type <macip|multicast> | vtep A.B.C.D>]",
|
||||
SHOW_STR BGP_STR EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"VXLAN Network Identifier\n"
|
||||
"VNI number\n"
|
||||
"Specify Route type\n"
|
||||
"MAC-IP (Type-2) route\n"
|
||||
"Multicast (Type-3) route\n"
|
||||
"Remote VTEP\n"
|
||||
"Remote VTEP IP address\n")
|
||||
|
||||
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_macip,
|
||||
show_bgp_evpn_route_vni_macip_cmd,
|
||||
"show bgp evpn route vni (1-16777215) mac WORD [ip WORD]",
|
||||
SHOW_STR BGP_STR EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"VXLAN Network Identifier\n"
|
||||
"VNI number\n"
|
||||
"MAC\n"
|
||||
"MAC address (e.g., 00:e0:ec:20:12:62)\n"
|
||||
"IP\n"
|
||||
"IP address (IPv4 or IPv6)\n")
|
||||
|
||||
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_multicast,
|
||||
show_bgp_evpn_route_vni_multicast_cmd,
|
||||
"show bgp evpn route vni (1-16777215) multicast A.B.C.D",
|
||||
SHOW_STR BGP_STR EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"VXLAN Network Identifier\n"
|
||||
"VNI number\n"
|
||||
"Multicast (Type-3) route\n"
|
||||
"Originating Router IP address\n")
|
||||
|
||||
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_all, show_bgp_evpn_route_vni_all_cmd,
|
||||
"show bgp evpn route vni all [vtep A.B.C.D]",
|
||||
SHOW_STR BGP_STR EVPN_HELP_STR
|
||||
"EVPN route information\n"
|
||||
"VXLAN Network Identifier\n"
|
||||
"All VNIs\n"
|
||||
"Remote VTEP\n"
|
||||
"Remote VTEP IP address\n")
|
||||
|
||||
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_import_rt, show_bgp_evpn_import_rt_cmd,
|
||||
"show bgp evpn import-rt",
|
||||
SHOW_STR BGP_STR EVPN_HELP_STR "Show import route target\n")
|
||||
#endif
|
||||
|
||||
DEFUN_NOSH (bgp_evpn_vni,
|
||||
bgp_evpn_vni_cmd,
|
||||
"vni (1-16777215)",
|
||||
@ -2290,11 +2565,11 @@ DEFUN (bgp_evpn_vni_rt,
|
||||
if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT) {
|
||||
ecomadd = ecommunity_str2com(argv[2]->arg,
|
||||
ECOMMUNITY_ROUTE_TARGET, 0);
|
||||
ecommunity_str(ecomadd);
|
||||
if (!ecomadd) {
|
||||
vty_out(vty, "%% Malformed Route Target list\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
ecommunity_str(ecomadd);
|
||||
|
||||
/* Do nothing if we already have this import route-target */
|
||||
if (!bgp_evpn_rt_matches_existing(vpn->import_rtl, ecomadd))
|
||||
@ -2305,11 +2580,11 @@ DEFUN (bgp_evpn_vni_rt,
|
||||
if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_EXPORT) {
|
||||
ecomadd = ecommunity_str2com(argv[2]->arg,
|
||||
ECOMMUNITY_ROUTE_TARGET, 0);
|
||||
ecommunity_str(ecomadd);
|
||||
if (!ecomadd) {
|
||||
vty_out(vty, "%% Malformed Route Target list\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
ecommunity_str(ecomadd);
|
||||
|
||||
/* Do nothing if we already have this export route-target */
|
||||
if (!bgp_evpn_rt_matches_existing(vpn->export_rtl, ecomadd))
|
||||
@ -2372,11 +2647,11 @@ DEFUN (no_bgp_evpn_vni_rt,
|
||||
}
|
||||
|
||||
ecomdel = ecommunity_str2com(argv[3]->arg, ECOMMUNITY_ROUTE_TARGET, 0);
|
||||
ecommunity_str(ecomdel);
|
||||
if (!ecomdel) {
|
||||
vty_out(vty, "%% Malformed Route Target list\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
ecommunity_str(ecomdel);
|
||||
|
||||
if (rt_type == RT_TYPE_IMPORT) {
|
||||
if (!bgp_evpn_rt_matches_existing(vpn->import_rtl, ecomdel)) {
|
||||
@ -2484,6 +2759,11 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
|
||||
bgp_config_write_family_header(vty, afi, safi, write);
|
||||
vty_out(vty, " advertise-all-vni\n");
|
||||
}
|
||||
|
||||
if (bgp->advertise_gw_macip) {
|
||||
bgp_config_write_family_header(vty, afi, safi, write);
|
||||
vty_out(vty, " advertise-default-gw\n");
|
||||
}
|
||||
}
|
||||
|
||||
void bgp_ethernetvpn_init(void)
|
||||
@ -2509,10 +2789,24 @@ void bgp_ethernetvpn_init(void)
|
||||
#if defined(HAVE_CUMULUS)
|
||||
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_all_vni_cmd);
|
||||
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_all_vni_cmd);
|
||||
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_default_gw_cmd);
|
||||
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_default_gw_cmd);
|
||||
|
||||
/* "show bgp l2vpn evpn" commands. */
|
||||
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vni_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_summary_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_rd_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_rd_macip_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_vni_cmd);
|
||||
install_element(VIEW_NODE,
|
||||
&show_bgp_l2vpn_evpn_route_vni_multicast_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_vni_macip_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_vni_all_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_import_rt_cmd);
|
||||
|
||||
/* "show bgp evpn" commands. */
|
||||
install_element(VIEW_NODE, &show_bgp_evpn_vni_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_evpn_vni_num_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_evpn_summary_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_evpn_route_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_evpn_route_rd_cmd);
|
||||
@ -2532,5 +2826,9 @@ void bgp_ethernetvpn_init(void)
|
||||
install_element(BGP_EVPN_VNI_NODE, &bgp_evpn_vni_rt_cmd);
|
||||
install_element(BGP_EVPN_VNI_NODE, &no_bgp_evpn_vni_rt_cmd);
|
||||
install_element(BGP_EVPN_VNI_NODE, &no_bgp_evpn_vni_rt_without_val_cmd);
|
||||
install_element(BGP_EVPN_VNI_NODE,
|
||||
&bgp_evpn_advertise_default_gw_vni_cmd);
|
||||
install_element(BGP_EVPN_VNI_NODE,
|
||||
&no_bgp_evpn_advertise_default_gw_vni_cmd);
|
||||
#endif
|
||||
}
|
||||
|
@ -1580,10 +1580,18 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri,
|
||||
/* Route map & unsuppress-map apply. */
|
||||
if (ROUTE_MAP_OUT_NAME(filter) || (ri->extra && ri->extra->suppress)) {
|
||||
struct bgp_info info;
|
||||
struct bgp_info_extra dummy_info_extra;
|
||||
struct attr dummy_attr;
|
||||
|
||||
info.peer = peer;
|
||||
info.attr = attr;
|
||||
|
||||
if (ri->extra) {
|
||||
memcpy(&dummy_info_extra, ri->extra,
|
||||
sizeof(struct bgp_info_extra));
|
||||
info.extra = &dummy_info_extra;
|
||||
}
|
||||
|
||||
/* don't confuse inbound and outbound setting */
|
||||
RESET_FLAG(attr->rmap_change_flags);
|
||||
|
||||
@ -6238,6 +6246,9 @@ static void route_vty_out_route(struct prefix *p, struct vty *vty)
|
||||
} else
|
||||
len += vty_out(vty, "/%d", p->prefixlen);
|
||||
} else if (p->family == AF_ETHERNET) {
|
||||
prefix2str(p, buf, PREFIX_STRLEN);
|
||||
len = vty_out(vty, "%s", buf);
|
||||
} else if (p->family == AF_EVPN) {
|
||||
#if defined(HAVE_CUMULUS)
|
||||
len = vty_out(vty, "%s",
|
||||
bgp_evpn_route2str((struct prefix_evpn *)p, buf,
|
||||
@ -6505,15 +6516,14 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
|
||||
len = vty_out(
|
||||
vty, "%s",
|
||||
binfo->peer->conf_if);
|
||||
len =
|
||||
7 - len; /* len of IPv6
|
||||
addr + max
|
||||
len of def
|
||||
ifname */
|
||||
len = 16 - len; /* len of IPv6
|
||||
addr + max
|
||||
len of def
|
||||
ifname */
|
||||
|
||||
if (len < 1)
|
||||
vty_out(vty, "\n%*s",
|
||||
45, " ");
|
||||
36, " ");
|
||||
else
|
||||
vty_out(vty, "%*s", len,
|
||||
" ");
|
||||
@ -6801,7 +6811,7 @@ void route_vty_out_tag(struct vty *vty, struct prefix *p,
|
||||
if (attr) {
|
||||
if (((p->family == AF_INET)
|
||||
&& ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
|
||||
|| (safi == SAFI_EVPN && p->family == AF_ETHERNET
|
||||
|| (safi == SAFI_EVPN
|
||||
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
|
||||
|| (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
|
||||
if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|
||||
@ -6826,7 +6836,7 @@ void route_vty_out_tag(struct vty *vty, struct prefix *p,
|
||||
}
|
||||
} else if (((p->family == AF_INET6)
|
||||
&& ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
|
||||
|| (safi == SAFI_EVPN && p->family == AF_ETHERNET
|
||||
|| (safi == SAFI_EVPN
|
||||
&& BGP_ATTR_NEXTHOP_AFI_IP6(attr))
|
||||
|| (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
|
||||
char buf_a[BUFSIZ];
|
||||
@ -7326,7 +7336,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
|
||||
|
||||
/* Line2 display Next-hop, Neighbor, Router-id */
|
||||
/* Display the nexthop */
|
||||
if ((p->family == AF_INET || p->family == AF_ETHERNET)
|
||||
if ((p->family == AF_INET || p->family == AF_ETHERNET ||
|
||||
p->family == AF_EVPN)
|
||||
&& (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|
||||
|| safi == SAFI_EVPN
|
||||
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
|
||||
@ -10232,6 +10243,10 @@ static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
|
||||
afi_t afi, safi_t safi,
|
||||
enum bgp_show_type type, u_char use_json)
|
||||
{
|
||||
/* labeled-unicast routes live in the unicast table */
|
||||
if (safi == SAFI_LABELED_UNICAST)
|
||||
safi = SAFI_UNICAST;
|
||||
|
||||
if (!peer || !peer->afc[afi][safi]) {
|
||||
if (use_json) {
|
||||
json_object *json_no = NULL;
|
||||
|
@ -54,6 +54,9 @@
|
||||
#include "bgpd/bgp_lcommunity.h"
|
||||
#include "bgpd/bgp_vty.h"
|
||||
#include "bgpd/bgp_debug.h"
|
||||
#include "bgpd/bgp_evpn.h"
|
||||
#include "bgpd/bgp_evpn_private.h"
|
||||
#include "bgpd/bgp_evpn_vty.h"
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
|
||||
@ -572,6 +575,106 @@ struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd = {
|
||||
route_match_ip_route_source_prefix_list_compile,
|
||||
route_match_ip_route_source_prefix_list_free};
|
||||
|
||||
/* `match mac address MAC_ACCESS_LIST' */
|
||||
|
||||
/* Match function should return 1 if match is success else return
|
||||
zero. */
|
||||
static route_map_result_t route_match_mac_address(void *rule,
|
||||
struct prefix *prefix,
|
||||
route_map_object_t type,
|
||||
void *object)
|
||||
{
|
||||
struct access_list *alist;
|
||||
struct prefix p;
|
||||
|
||||
if (type == RMAP_BGP) {
|
||||
alist = access_list_lookup(AFI_L2VPN, (char *)rule);
|
||||
if (alist == NULL)
|
||||
return RMAP_NOMATCH;
|
||||
|
||||
if (prefix->u.prefix_evpn.route_type != BGP_EVPN_MAC_IP_ROUTE)
|
||||
return RMAP_NOMATCH;
|
||||
|
||||
p.family = AF_ETHERNET;
|
||||
p.prefixlen = ETH_ALEN * 8;
|
||||
p.u.prefix_eth = prefix->u.prefix_evpn.mac;
|
||||
|
||||
return (access_list_apply(alist, &p)
|
||||
== FILTER_DENY
|
||||
? RMAP_NOMATCH
|
||||
: RMAP_MATCH);
|
||||
}
|
||||
|
||||
return RMAP_NOMATCH;
|
||||
}
|
||||
|
||||
/* Route map `mac address' match statement. `arg' should be
|
||||
access-list name. */
|
||||
static void *route_match_mac_address_compile(const char *arg)
|
||||
{
|
||||
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
||||
}
|
||||
|
||||
/* Free route map's compiled `ip address' value. */
|
||||
static void route_match_mac_address_free(void *rule)
|
||||
{
|
||||
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
||||
}
|
||||
|
||||
/* Route map commands for mac address matching. */
|
||||
struct route_map_rule_cmd route_match_mac_address_cmd = {
|
||||
"mac address", route_match_mac_address, route_match_mac_address_compile,
|
||||
route_match_mac_address_free};
|
||||
|
||||
/* `match vni' */
|
||||
|
||||
/* Match function should return 1 if match is success else return
|
||||
zero. */
|
||||
static route_map_result_t route_match_vni(void *rule, struct prefix *prefix,
|
||||
route_map_object_t type, void *object)
|
||||
{
|
||||
vni_t vni = 0;
|
||||
struct bgp_info *bgp_info = NULL;
|
||||
|
||||
if (type == RMAP_BGP) {
|
||||
vni = *((vni_t *)rule);
|
||||
bgp_info = (struct bgp_info *)object;
|
||||
|
||||
if (vni == label2vni(&bgp_info->extra->label))
|
||||
return RMAP_MATCH;
|
||||
}
|
||||
|
||||
return RMAP_NOMATCH;
|
||||
}
|
||||
|
||||
/* Route map `vni' match statement. */
|
||||
static void *route_match_vni_compile(const char *arg)
|
||||
{
|
||||
vni_t *vni = NULL;
|
||||
char *end = NULL;
|
||||
|
||||
vni = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(vni_t));
|
||||
if (!vni)
|
||||
return NULL;
|
||||
|
||||
*vni = strtoul(arg, &end, 10);
|
||||
if (*end != '\0')
|
||||
return NULL;
|
||||
|
||||
return vni;
|
||||
}
|
||||
|
||||
/* Free route map's compiled `vni' value. */
|
||||
static void route_match_vni_free(void *rule)
|
||||
{
|
||||
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
||||
}
|
||||
|
||||
/* Route map commands for vni matching. */
|
||||
struct route_map_rule_cmd route_match_evpn_vni_cmd = {
|
||||
"evpn vni", route_match_vni, route_match_vni_compile,
|
||||
route_match_vni_free};
|
||||
|
||||
/* `match local-preference LOCAL-PREF' */
|
||||
|
||||
/* Match function return 1 if match is success else return zero. */
|
||||
@ -2994,6 +3097,55 @@ static void bgp_route_map_event(route_map_event_t event, const char *rmap_name)
|
||||
route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
|
||||
}
|
||||
|
||||
DEFUN (match_mac_address,
|
||||
match_mac_address_cmd,
|
||||
"match mac address WORD",
|
||||
MATCH_STR
|
||||
"mac address\n"
|
||||
"Match address of route\n"
|
||||
"MAC Access-list name\n")
|
||||
{
|
||||
return bgp_route_match_add(vty, "mac address", argv[3]->arg,
|
||||
RMAP_EVENT_FILTER_ADDED);
|
||||
}
|
||||
|
||||
DEFUN (no_match_mac_address,
|
||||
no_match_mac_address_cmd,
|
||||
"no match mac address WORD",
|
||||
NO_STR
|
||||
MATCH_STR
|
||||
"mac\n"
|
||||
"Match address of route\n"
|
||||
"MAC acess-list name\n")
|
||||
{
|
||||
return bgp_route_match_delete(vty, "mac address", argv[4]->arg,
|
||||
RMAP_EVENT_FILTER_DELETED);
|
||||
}
|
||||
|
||||
DEFUN (match_evpn_vni,
|
||||
match_evpn_vni_cmd,
|
||||
"match evpn vni (1-16777215)",
|
||||
MATCH_STR
|
||||
EVPN_HELP_STR
|
||||
"Match VNI\n"
|
||||
"VNI ID\n")
|
||||
{
|
||||
return bgp_route_match_add(vty, "evpn vni", argv[3]->arg,
|
||||
RMAP_EVENT_MATCH_ADDED);
|
||||
}
|
||||
|
||||
DEFUN (no_match_evpn_vni,
|
||||
no_match_evpn_vni_cmd,
|
||||
"no match evpn vni (1-16777215)",
|
||||
NO_STR
|
||||
MATCH_STR
|
||||
EVPN_HELP_STR
|
||||
"Match VNI\n"
|
||||
"VNI ID\n")
|
||||
{
|
||||
return bgp_route_match_delete(vty, "evpn vni", argv[4]->arg,
|
||||
RMAP_EVENT_MATCH_DELETED);
|
||||
}
|
||||
|
||||
DEFUN (match_peer,
|
||||
match_peer_cmd,
|
||||
@ -4351,6 +4503,8 @@ void bgp_route_map_init(void)
|
||||
route_map_install_match(&route_match_probability_cmd);
|
||||
route_map_install_match(&route_match_interface_cmd);
|
||||
route_map_install_match(&route_match_tag_cmd);
|
||||
route_map_install_match(&route_match_mac_address_cmd);
|
||||
route_map_install_match(&route_match_evpn_vni_cmd);
|
||||
|
||||
route_map_install_set(&route_set_ip_nexthop_cmd);
|
||||
route_map_install_set(&route_set_local_pref_cmd);
|
||||
@ -4381,6 +4535,10 @@ void bgp_route_map_init(void)
|
||||
install_element(RMAP_NODE, &no_match_ip_route_source_cmd);
|
||||
install_element(RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
|
||||
install_element(RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
|
||||
install_element(RMAP_NODE, &match_mac_address_cmd);
|
||||
install_element(RMAP_NODE, &no_match_mac_address_cmd);
|
||||
install_element(RMAP_NODE, &match_evpn_vni_cmd);
|
||||
install_element(RMAP_NODE, &no_match_evpn_vni_cmd);
|
||||
|
||||
install_element(RMAP_NODE, &match_aspath_cmd);
|
||||
install_element(RMAP_NODE, &no_match_aspath_cmd);
|
||||
|
@ -12047,6 +12047,8 @@ void bgp_vty_init(void)
|
||||
install_element(BGP_VPNV4_NODE, &no_neighbor_route_map_cmd);
|
||||
install_element(BGP_VPNV6_NODE, &neighbor_route_map_cmd);
|
||||
install_element(BGP_VPNV6_NODE, &no_neighbor_route_map_cmd);
|
||||
install_element(BGP_EVPN_NODE, &neighbor_route_map_cmd);
|
||||
install_element(BGP_EVPN_NODE, &no_neighbor_route_map_cmd);
|
||||
|
||||
/* "neighbor unsuppress-map" commands. */
|
||||
install_element(BGP_NODE, &neighbor_unsuppress_map_hidden_cmd);
|
||||
|
@ -2034,6 +2034,29 @@ void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer)
|
||||
zclient_send_interface_radv_req(zclient, bgp->vrf_id, peer->ifp, 0, 0);
|
||||
}
|
||||
|
||||
int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni)
|
||||
{
|
||||
struct stream *s = NULL;
|
||||
|
||||
/* Check socket. */
|
||||
if (!zclient || zclient->sock < 0)
|
||||
return 0;
|
||||
|
||||
/* Don't try to register if Zebra doesn't know of this instance. */
|
||||
if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
|
||||
return 0;
|
||||
|
||||
s = zclient->obuf;
|
||||
stream_reset(s);
|
||||
|
||||
zclient_create_header(s, ZEBRA_ADVERTISE_DEFAULT_GW, bgp->vrf_id);
|
||||
stream_putc(s, advertise);
|
||||
stream_put3(s, vni);
|
||||
stream_putw_at(s, 0, stream_get_endp(s));
|
||||
|
||||
return zclient_send_message(zclient);
|
||||
}
|
||||
|
||||
int bgp_zebra_advertise_all_vni(struct bgp *bgp, int advertise)
|
||||
{
|
||||
struct stream *s;
|
||||
@ -2120,7 +2143,7 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
|
||||
int ipa_len;
|
||||
char buf[ETHER_ADDR_STRLEN];
|
||||
char buf1[INET6_ADDRSTRLEN];
|
||||
u_char sticky;
|
||||
u_char flags;
|
||||
|
||||
memset(&ip, 0, sizeof(ip));
|
||||
s = zclient->ibuf;
|
||||
@ -2140,21 +2163,20 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
|
||||
(ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4 : IPADDR_V6;
|
||||
stream_get(&ip.ip.addr, s, ipa_len);
|
||||
}
|
||||
sticky = stream_getc(s);
|
||||
flags = stream_getc(s);
|
||||
|
||||
bgp = bgp_lookup_by_vrf_id(vrf_id);
|
||||
if (!bgp)
|
||||
return 0;
|
||||
|
||||
if (BGP_DEBUG(zebra, ZEBRA))
|
||||
zlog_debug("%u:Recv MACIP %s %sMAC %s IP %s VNI %u", vrf_id,
|
||||
(command == ZEBRA_MACIP_ADD) ? "Add" : "Del",
|
||||
sticky ? "sticky " : "",
|
||||
prefix_mac2str(&mac, buf, sizeof(buf)),
|
||||
zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u",
|
||||
vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del",
|
||||
flags, prefix_mac2str(&mac, buf, sizeof(buf)),
|
||||
ipaddr2str(&ip, buf1, sizeof(buf1)), vni);
|
||||
|
||||
if (command == ZEBRA_MACIP_ADD)
|
||||
return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip, sticky);
|
||||
return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip, flags);
|
||||
else
|
||||
return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip);
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
#ifndef _QUAGGA_BGP_ZEBRA_H
|
||||
#define _QUAGGA_BGP_ZEBRA_H
|
||||
|
||||
#include "vxlan.h"
|
||||
|
||||
extern void bgp_zebra_init(struct thread_master *master);
|
||||
extern void bgp_zebra_destroy(void);
|
||||
extern int bgp_if_update_all(void);
|
||||
@ -57,6 +59,7 @@ extern struct interface *if_lookup_by_ipv6(struct in6_addr *, ifindex_t,
|
||||
extern struct interface *if_lookup_by_ipv6_exact(struct in6_addr *, ifindex_t,
|
||||
vrf_id_t);
|
||||
|
||||
extern int bgp_zebra_advertise_gw_macip(struct bgp *, int, vni_t);
|
||||
extern int bgp_zebra_advertise_all_vni(struct bgp *, int);
|
||||
|
||||
extern int bgp_zebra_num_connects(void);
|
||||
|
@ -380,6 +380,9 @@ struct bgp {
|
||||
/* EVI hash table */
|
||||
struct hash *vnihash;
|
||||
|
||||
/* EVPN enable - advertise gateway macip routes */
|
||||
int advertise_gw_macip;
|
||||
|
||||
/* EVPN enable - advertise local VNIs and their MACs etc. */
|
||||
int advertise_all_vni;
|
||||
|
||||
@ -1488,7 +1491,8 @@ static inline int peer_group_af_configured(struct peer_group *group)
|
||||
|| peer->afc[AFI_IP6][SAFI_MULTICAST]
|
||||
|| peer->afc[AFI_IP6][SAFI_LABELED_UNICAST]
|
||||
|| peer->afc[AFI_IP6][SAFI_MPLS_VPN]
|
||||
|| peer->afc[AFI_IP6][SAFI_ENCAP] || peer->afc[AFI_IP6][SAFI_EVPN])
|
||||
|| peer->afc[AFI_IP6][SAFI_ENCAP]
|
||||
|| peer->afc[AFI_L2VPN][SAFI_EVPN])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include "command.h"
|
||||
#include "vty.h"
|
||||
#include "json.h"
|
||||
|
||||
#include "ldpd/ldpd.h"
|
||||
#include "ldpd/ldp_vty.h"
|
||||
#include "ldpd/ldp_vty_cmds_clippy.c"
|
||||
@ -586,7 +588,7 @@ DEFPY (ldp_show_mpls_ldp_binding,
|
||||
"IPv6 Address Family\n"
|
||||
"Label Information Base (LIB) information\n"
|
||||
"Show detailed information\n"
|
||||
"JavaScript Object Notation\n")
|
||||
JSON_STR)
|
||||
{
|
||||
return (ldp_vty_show_binding(vty, af, detail, json));
|
||||
}
|
||||
@ -601,7 +603,7 @@ DEFPY (ldp_show_mpls_ldp_discovery,
|
||||
"IPv6 Address Family\n"
|
||||
"Discovery Hello Information\n"
|
||||
"Show detailed information\n"
|
||||
"JavaScript Object Notation\n")
|
||||
JSON_STR)
|
||||
{
|
||||
return (ldp_vty_show_discovery(vty, af, detail, json));
|
||||
}
|
||||
@ -615,7 +617,7 @@ DEFPY (ldp_show_mpls_ldp_interface,
|
||||
"IPv4 Address Family\n"
|
||||
"IPv6 Address Family\n"
|
||||
"interface information\n"
|
||||
"JavaScript Object Notation\n")
|
||||
JSON_STR)
|
||||
{
|
||||
return (ldp_vty_show_interface(vty, af, json));
|
||||
}
|
||||
@ -627,7 +629,7 @@ DEFPY (ldp_show_mpls_ldp_capabilities,
|
||||
"MPLS information\n"
|
||||
"Label Distribution Protocol\n"
|
||||
"Display LDP Capabilities information\n"
|
||||
"JavaScript Object Notation\n")
|
||||
JSON_STR)
|
||||
{
|
||||
return (ldp_vty_show_capabilities(vty, json));
|
||||
}
|
||||
@ -640,7 +642,7 @@ DEFPY (ldp_show_mpls_ldp_neighbor,
|
||||
"Label Distribution Protocol\n"
|
||||
"Neighbor information\n"
|
||||
"Show detailed information\n"
|
||||
"JavaScript Object Notation\n")
|
||||
JSON_STR)
|
||||
{
|
||||
return (ldp_vty_show_neighbor(vty, 0, detail, json));
|
||||
}
|
||||
@ -653,7 +655,7 @@ DEFPY (ldp_show_mpls_ldp_neighbor_capabilities,
|
||||
"Label Distribution Protocol\n"
|
||||
"Neighbor information\n"
|
||||
"Display neighbor capability information\n"
|
||||
"JavaScript Object Notation\n")
|
||||
JSON_STR)
|
||||
{
|
||||
return (ldp_vty_show_neighbor(vty, 1, NULL, json));
|
||||
}
|
||||
@ -665,7 +667,7 @@ DEFPY (ldp_show_l2vpn_atom_binding,
|
||||
"Show information about Layer2 VPN\n"
|
||||
"Show Any Transport over MPLS information\n"
|
||||
"Show AToM label binding information\n"
|
||||
"JavaScript Object Notation\n")
|
||||
JSON_STR)
|
||||
{
|
||||
return (ldp_vty_show_atom_binding(vty, json));
|
||||
}
|
||||
@ -677,7 +679,7 @@ DEFPY (ldp_show_l2vpn_atom_vc,
|
||||
"Show information about Layer2 VPN\n"
|
||||
"Show Any Transport over MPLS information\n"
|
||||
"Show AToM virtual circuit information\n"
|
||||
"JavaScript Object Notation\n")
|
||||
JSON_STR)
|
||||
{
|
||||
return (ldp_vty_show_atom_vc(vty, json));
|
||||
}
|
||||
|
@ -101,6 +101,7 @@ const char *node_names[] = {
|
||||
"ipv4 access list", // ACCESS_NODE,
|
||||
"ipv4 prefix list", // PREFIX_NODE,
|
||||
"ipv6 access list", // ACCESS_IPV6_NODE,
|
||||
"MAC access list", // ACCESS_MAC_NODE,
|
||||
"ipv6 prefix list", // PREFIX_IPV6_NODE,
|
||||
"as list", // AS_LIST_NODE,
|
||||
"community list", // COMMUNITY_LIST_NODE,
|
||||
|
@ -123,6 +123,7 @@ enum node_type {
|
||||
ACCESS_NODE, /* Access list node. */
|
||||
PREFIX_NODE, /* Prefix list node. */
|
||||
ACCESS_IPV6_NODE, /* Access list node. */
|
||||
ACCESS_MAC_NODE, /* MAC access list node*/
|
||||
PREFIX_IPV6_NODE, /* Prefix list node. */
|
||||
AS_LIST_NODE, /* AS list node. */
|
||||
COMMUNITY_LIST_NODE, /* Community list node. */
|
||||
|
212
lib/filter.c
212
lib/filter.c
@ -90,6 +90,14 @@ struct access_master {
|
||||
void (*delete_hook)(struct access_list *);
|
||||
};
|
||||
|
||||
/* Static structure for mac access_list's master. */
|
||||
static struct access_master access_master_mac = {
|
||||
{NULL, NULL},
|
||||
{NULL, NULL},
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* Static structure for IPv4 access_list's master. */
|
||||
static struct access_master access_master_ipv4 = {
|
||||
{NULL, NULL},
|
||||
@ -112,6 +120,8 @@ static struct access_master *access_master_get(afi_t afi)
|
||||
return &access_master_ipv4;
|
||||
else if (afi == AFI_IP6)
|
||||
return &access_master_ipv6;
|
||||
else if (afi == AFI_L2VPN)
|
||||
return &access_master_mac;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -173,7 +183,7 @@ static int filter_match_cisco(struct filter *mfilter, struct prefix *p)
|
||||
/* If filter match to the prefix then return 1. */
|
||||
static int filter_match_zebra(struct filter *mfilter, struct prefix *p)
|
||||
{
|
||||
struct filter_zebra *filter;
|
||||
struct filter_zebra *filter = NULL;
|
||||
|
||||
filter = &mfilter->u.zfilter;
|
||||
|
||||
@ -365,9 +375,7 @@ static struct access_list *access_list_get(afi_t afi, const char *name)
|
||||
enum filter_type access_list_apply(struct access_list *access, void *object)
|
||||
{
|
||||
struct filter *filter;
|
||||
struct prefix *p;
|
||||
|
||||
p = (struct prefix *)object;
|
||||
struct prefix *p = (struct prefix *)object;
|
||||
|
||||
if (access == NULL)
|
||||
return FILTER_DENY;
|
||||
@ -390,6 +398,7 @@ void access_list_add_hook(void (*func)(struct access_list *access))
|
||||
{
|
||||
access_master_ipv4.add_hook = func;
|
||||
access_master_ipv6.add_hook = func;
|
||||
access_master_mac.add_hook = func;
|
||||
}
|
||||
|
||||
/* Delete hook function. */
|
||||
@ -397,6 +406,7 @@ void access_list_delete_hook(void (*func)(struct access_list *access))
|
||||
{
|
||||
access_master_ipv4.delete_hook = func;
|
||||
access_master_ipv6.delete_hook = func;
|
||||
access_master_mac.delete_hook = func;
|
||||
}
|
||||
|
||||
/* Add new filter to the end of specified access_list. */
|
||||
@ -515,10 +525,10 @@ static struct filter *filter_lookup_zebra(struct access_list *access,
|
||||
filter = &mfilter->u.zfilter;
|
||||
|
||||
if (filter->exact == new->exact
|
||||
&& mfilter->type
|
||||
== mnew->type &&prefix_same(&filter->prefix,
|
||||
&new->prefix))
|
||||
return mfilter;
|
||||
&& mfilter->type == mnew->type) {
|
||||
if (prefix_same(&filter->prefix, &new->prefix))
|
||||
return mfilter;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -1252,6 +1262,12 @@ static int filter_set_zebra(struct vty *vty, const char *name_str,
|
||||
"IPv6 address prefix/prefixlen is malformed\n");
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
} else if (afi == AFI_L2VPN) {
|
||||
ret = str2prefix_eth(prefix_str, (struct prefix_eth *)&p);
|
||||
if (ret <= 0) {
|
||||
vty_out(vty, "MAC address is malformed\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
} else
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
|
||||
@ -1274,7 +1290,6 @@ static int filter_set_zebra(struct vty *vty, const char *name_str,
|
||||
access_list_filter_add(access, mfilter);
|
||||
} else {
|
||||
struct filter *delete_filter;
|
||||
|
||||
delete_filter = filter_lookup_zebra(access, mfilter);
|
||||
if (delete_filter)
|
||||
access_list_filter_delete(access, delete_filter);
|
||||
@ -1285,6 +1300,64 @@ static int filter_set_zebra(struct vty *vty, const char *name_str,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (mac_access_list,
|
||||
mac_access_list_cmd,
|
||||
"mac access-list WORD <deny|permit> MAC",
|
||||
"Add a mac access-list\n"
|
||||
"Add an access list entry\n"
|
||||
"MAC zebra access-list name\n"
|
||||
"Specify packets to reject\n"
|
||||
"Specify packets to forward\n"
|
||||
"MAC address to match. e.g. 00:01:00:01:00:01\n")
|
||||
{
|
||||
return filter_set_zebra(vty, argv[2]->arg, argv[3]->arg, AFI_L2VPN,
|
||||
argv[4]->arg, 0, 1);
|
||||
}
|
||||
|
||||
DEFUN (no_mac_access_list,
|
||||
no_mac_access_list_cmd,
|
||||
"no mac access-list WORD <deny|permit> MAC",
|
||||
NO_STR
|
||||
"Remove a mac access-list\n"
|
||||
"Remove an access list entry\n"
|
||||
"MAC zebra access-list name\n"
|
||||
"Specify packets to reject\n"
|
||||
"Specify packets to forward\n"
|
||||
"MAC address to match. e.g. 00:01:00:01:00:01\n")
|
||||
{
|
||||
return filter_set_zebra(vty, argv[3]->arg, argv[4]->arg, AFI_L2VPN,
|
||||
argv[5]->arg, 0, 0);
|
||||
}
|
||||
|
||||
DEFUN (mac_access_list_any,
|
||||
mac_access_list_any_cmd,
|
||||
"mac access-list WORD <deny|permit> any",
|
||||
"Add a mac access-list\n"
|
||||
"Add an access list entry\n"
|
||||
"MAC zebra access-list name\n"
|
||||
"Specify packets to reject\n"
|
||||
"Specify packets to forward\n"
|
||||
"MAC address to match. e.g. 00:01:00:01:00:01\n")
|
||||
{
|
||||
return filter_set_zebra(vty, argv[2]->arg, argv[3]->arg, AFI_L2VPN,
|
||||
"00:00:00:00:00:00", 0, 1);
|
||||
}
|
||||
|
||||
DEFUN (no_mac_access_list_any,
|
||||
no_mac_access_list_any_cmd,
|
||||
"no mac access-list WORD <deny|permit> any",
|
||||
NO_STR
|
||||
"Remove a mac access-list\n"
|
||||
"Remove an access list entry\n"
|
||||
"MAC zebra access-list name\n"
|
||||
"Specify packets to reject\n"
|
||||
"Specify packets to forward\n"
|
||||
"MAC address to match. e.g. 00:01:00:01:00:01\n")
|
||||
{
|
||||
return filter_set_zebra(vty, argv[3]->arg, argv[4]->arg, AFI_L2VPN,
|
||||
"00:00:00:00:00:00", 0, 0);
|
||||
}
|
||||
|
||||
DEFUN (access_list_exact,
|
||||
access_list_exact_cmd,
|
||||
"access-list WORD <deny|permit> A.B.C.D/M [exact-match]",
|
||||
@ -1666,12 +1739,15 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi)
|
||||
filter = &mfilter->u.cfilter;
|
||||
|
||||
if (write) {
|
||||
vty_out(vty, "%s IP%s access list %s\n",
|
||||
vty_out(vty, "%s %s access list %s\n",
|
||||
mfilter->cisco ? (filter->extended
|
||||
? "Extended"
|
||||
: "Standard")
|
||||
: "Zebra",
|
||||
afi == AFI_IP6 ? "v6" : "",
|
||||
(afi == AFI_IP)
|
||||
? ("IP")
|
||||
: ((afi == AFI_IP6) ? ("IPv6 ")
|
||||
: ("MAC ")),
|
||||
access->name);
|
||||
write = 0;
|
||||
}
|
||||
@ -1710,12 +1786,15 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi)
|
||||
filter = &mfilter->u.cfilter;
|
||||
|
||||
if (write) {
|
||||
vty_out(vty, "%s IP%s access list %s\n",
|
||||
vty_out(vty, "%s %s access list %s\n",
|
||||
mfilter->cisco ? (filter->extended
|
||||
? "Extended"
|
||||
: "Standard")
|
||||
: "Zebra",
|
||||
afi == AFI_IP6 ? "v6" : "",
|
||||
(afi == AFI_IP)
|
||||
? ("IP")
|
||||
: ((afi == AFI_IP6) ? ("IPv6 ")
|
||||
: ("MAC ")),
|
||||
access->name);
|
||||
write = 0;
|
||||
}
|
||||
@ -1746,6 +1825,28 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi)
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* show MAC access list - this only has MAC filters for now*/
|
||||
DEFUN (show_mac_access_list,
|
||||
show_mac_access_list_cmd,
|
||||
"show mac access-list",
|
||||
SHOW_STR
|
||||
"mac access lists\n"
|
||||
"List mac access lists\n")
|
||||
{
|
||||
return filter_show(vty, NULL, AFI_L2VPN);
|
||||
}
|
||||
|
||||
DEFUN (show_mac_access_list_name,
|
||||
show_mac_access_list_name_cmd,
|
||||
"show mac access-list WORD",
|
||||
SHOW_STR
|
||||
"mac access lists\n"
|
||||
"List mac access lists\n"
|
||||
"mac address\n")
|
||||
{
|
||||
return filter_show(vty, argv[3]->arg, AFI_L2VPN);
|
||||
}
|
||||
|
||||
DEFUN (show_ip_access_list,
|
||||
show_ip_access_list_cmd,
|
||||
"show ip access-list",
|
||||
@ -1844,10 +1945,17 @@ void config_write_access_zebra(struct vty *vty, struct filter *mfilter)
|
||||
|
||||
if (p->prefixlen == 0 && !filter->exact)
|
||||
vty_out(vty, " any");
|
||||
else
|
||||
else if (p->family == AF_INET6 || p->family == AF_INET)
|
||||
vty_out(vty, " %s/%d%s",
|
||||
inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
|
||||
p->prefixlen, filter->exact ? " exact-match" : "");
|
||||
else if (p->family == AF_ETHERNET) {
|
||||
if (p->prefixlen == 0)
|
||||
vty_out(vty, " any");
|
||||
else
|
||||
vty_out(vty, " %s", prefix_mac2str(&(p->u.prefix_eth),
|
||||
buf, sizeof(buf)));
|
||||
}
|
||||
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
@ -1866,15 +1974,19 @@ static int config_write_access(struct vty *vty, afi_t afi)
|
||||
for (access = master->num.head; access; access = access->next) {
|
||||
if (access->remark) {
|
||||
vty_out(vty, "%saccess-list %s remark %s\n",
|
||||
afi == AFI_IP ? "" : "ipv6 ", access->name,
|
||||
access->remark);
|
||||
(afi == AFI_IP) ? ("")
|
||||
: ((afi == AFI_IP6) ? ("ipv6 ")
|
||||
: ("mac ")),
|
||||
access->name, access->remark);
|
||||
write++;
|
||||
}
|
||||
|
||||
for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
|
||||
vty_out(vty, "%saccess-list %s %s",
|
||||
afi == AFI_IP ? "" : "ipv6 ", access->name,
|
||||
filter_type_str(mfilter));
|
||||
(afi == AFI_IP) ? ("")
|
||||
: ((afi == AFI_IP6) ? ("ipv6 ")
|
||||
: ("mac ")),
|
||||
access->name, filter_type_str(mfilter));
|
||||
|
||||
if (mfilter->cisco)
|
||||
config_write_access_cisco(vty, mfilter);
|
||||
@ -1888,15 +2000,19 @@ static int config_write_access(struct vty *vty, afi_t afi)
|
||||
for (access = master->str.head; access; access = access->next) {
|
||||
if (access->remark) {
|
||||
vty_out(vty, "%saccess-list %s remark %s\n",
|
||||
afi == AFI_IP ? "" : "ipv6 ", access->name,
|
||||
access->remark);
|
||||
(afi == AFI_IP) ? ("")
|
||||
: ((afi == AFI_IP6) ? ("ipv6 ")
|
||||
: ("mac ")),
|
||||
access->name, access->remark);
|
||||
write++;
|
||||
}
|
||||
|
||||
for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
|
||||
vty_out(vty, "%saccess-list %s %s",
|
||||
afi == AFI_IP ? "" : "ipv6 ", access->name,
|
||||
filter_type_str(mfilter));
|
||||
(afi == AFI_IP) ? ("")
|
||||
: ((afi == AFI_IP6) ? ("ipv6 ")
|
||||
: ("mac ")),
|
||||
access->name, filter_type_str(mfilter));
|
||||
|
||||
if (mfilter->cisco)
|
||||
config_write_access_cisco(vty, mfilter);
|
||||
@ -1909,6 +2025,56 @@ static int config_write_access(struct vty *vty, afi_t afi)
|
||||
return write;
|
||||
}
|
||||
|
||||
static struct cmd_node access_mac_node = {
|
||||
ACCESS_MAC_NODE, "", /* Access list has no interface. */
|
||||
1};
|
||||
|
||||
static int config_write_access_mac(struct vty *vty)
|
||||
{
|
||||
return config_write_access(vty, AFI_L2VPN);
|
||||
}
|
||||
|
||||
static void access_list_reset_mac(void)
|
||||
{
|
||||
struct access_list *access;
|
||||
struct access_list *next;
|
||||
struct access_master *master;
|
||||
|
||||
master = access_master_get(AFI_L2VPN);
|
||||
if (master == NULL)
|
||||
return;
|
||||
|
||||
for (access = master->num.head; access; access = next) {
|
||||
next = access->next;
|
||||
access_list_delete(access);
|
||||
}
|
||||
for (access = master->str.head; access; access = next) {
|
||||
next = access->next;
|
||||
access_list_delete(access);
|
||||
}
|
||||
|
||||
assert(master->num.head == NULL);
|
||||
assert(master->num.tail == NULL);
|
||||
|
||||
assert(master->str.head == NULL);
|
||||
assert(master->str.tail == NULL);
|
||||
}
|
||||
|
||||
/* Install vty related command. */
|
||||
static void access_list_init_mac(void)
|
||||
{
|
||||
install_node(&access_mac_node, config_write_access_mac);
|
||||
|
||||
install_element(ENABLE_NODE, &show_mac_access_list_cmd);
|
||||
install_element(ENABLE_NODE, &show_mac_access_list_name_cmd);
|
||||
|
||||
/* Zebra access-list */
|
||||
install_element(CONFIG_NODE, &mac_access_list_cmd);
|
||||
install_element(CONFIG_NODE, &no_mac_access_list_cmd);
|
||||
install_element(CONFIG_NODE, &mac_access_list_any_cmd);
|
||||
install_element(CONFIG_NODE, &no_mac_access_list_any_cmd);
|
||||
}
|
||||
|
||||
/* Access-list node. */
|
||||
static struct cmd_node access_node = {ACCESS_NODE,
|
||||
"", /* Access list has no interface. */
|
||||
@ -2050,10 +2216,12 @@ void access_list_init()
|
||||
{
|
||||
access_list_init_ipv4();
|
||||
access_list_init_ipv6();
|
||||
access_list_init_mac();
|
||||
}
|
||||
|
||||
void access_list_reset()
|
||||
{
|
||||
access_list_reset_ipv4();
|
||||
access_list_reset_ipv6();
|
||||
access_list_reset_mac();
|
||||
}
|
||||
|
@ -917,6 +917,7 @@ static const struct zebra_desc_table command_types[] = {
|
||||
DESC_ENTRY(ZEBRA_GET_LABEL_CHUNK),
|
||||
DESC_ENTRY(ZEBRA_RELEASE_LABEL_CHUNK),
|
||||
DESC_ENTRY(ZEBRA_ADVERTISE_ALL_VNI),
|
||||
DESC_ENTRY(ZEBRA_ADVERTISE_DEFAULT_GW),
|
||||
DESC_ENTRY(ZEBRA_VNI_ADD),
|
||||
DESC_ENTRY(ZEBRA_VNI_DEL),
|
||||
DESC_ENTRY(ZEBRA_REMOTE_VTEP_ADD),
|
||||
|
704
lib/prefix.c
704
lib/prefix.c
@ -37,390 +37,262 @@ static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
|
||||
static const struct in6_addr maskbytes6[] = {
|
||||
/* /0 */ {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /1 */
|
||||
{{{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /2 */
|
||||
{{{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /3 */
|
||||
{{{0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /4 */
|
||||
{{{0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /5 */
|
||||
{{{0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /6 */
|
||||
{{{0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /7 */
|
||||
{{{0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /8 */
|
||||
{{{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /9 */
|
||||
{{{0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /10 */
|
||||
{{{0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /11 */
|
||||
{{{0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /12 */
|
||||
{{{0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /13 */
|
||||
{{{0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /14 */
|
||||
{{{0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /15 */
|
||||
{{{0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /16 */
|
||||
{{{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /17 */
|
||||
{{{0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /18 */
|
||||
{{{0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /19 */
|
||||
{{{0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /20 */
|
||||
{{{0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /21 */
|
||||
{{{0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /22 */
|
||||
{{{0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /23 */
|
||||
{{{0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /24 */
|
||||
{{{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /25 */
|
||||
{{{0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /26 */
|
||||
{{{0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /27 */
|
||||
{{{0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /28 */
|
||||
{{{0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /29 */
|
||||
{{{0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /30 */
|
||||
{{{0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /31 */
|
||||
{{{0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /32 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /33 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /34 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /35 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /36 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /37 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /38 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /39 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /40 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /41 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /42 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /43 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /44 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /45 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /46 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /47 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /48 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /49 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /50 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /51 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /52 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /53 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /54 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /55 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /56 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /57 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /58 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /59 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /60 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /61 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /62 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /63 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /64 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /65 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /66 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /67 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /68 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /69 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /70 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /71 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /72 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /73 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /74 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /75 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /76 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /77 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /78 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /79 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /80 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /81 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /82 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /83 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /84 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /85 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /86 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /87 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /88 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /89 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /90 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xc0, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /91 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xe0, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /92 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf0, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /93 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf8, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /94 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xfc, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /95 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xfe, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /96 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /97 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x80, 0x00, 0x00, 0x00}}},
|
||||
/* /98 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xc0, 0x00, 0x00, 0x00}}},
|
||||
/* /99 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xe0, 0x00, 0x00, 0x00}}},
|
||||
/* /100 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xf0, 0x00, 0x00, 0x00}}},
|
||||
/* /101 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xf8, 0x00, 0x00, 0x00}}},
|
||||
/* /102 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xfc, 0x00, 0x00, 0x00}}},
|
||||
/* /103 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xfe, 0x00, 0x00, 0x00}}},
|
||||
/* /104 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00}}},
|
||||
/* /105 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0x80, 0x00, 0x00}}},
|
||||
/* /106 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xc0, 0x00, 0x00}}},
|
||||
/* /107 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xe0, 0x00, 0x00}}},
|
||||
/* /108 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xf0, 0x00, 0x00}}},
|
||||
/* /109 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xf8, 0x00, 0x00}}},
|
||||
/* /110 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xfc, 0x00, 0x00}}},
|
||||
/* /111 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xfe, 0x00, 0x00}}},
|
||||
/* /112 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0x00, 0x00}}},
|
||||
/* /113 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0x80, 0x00}}},
|
||||
/* /114 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xc0, 0x00}}},
|
||||
/* /115 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xe0, 0x00}}},
|
||||
/* /116 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xf0, 0x00}}},
|
||||
/* /117 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xf8, 0x00}}},
|
||||
/* /118 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfc, 0x00}}},
|
||||
/* /119 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfe, 0x00}}},
|
||||
/* /120 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00}}},
|
||||
/* /121 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x80}}},
|
||||
/* /122 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xc0}}},
|
||||
/* /123 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xe0}}},
|
||||
/* /124 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xf0}}},
|
||||
/* /125 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xf8}}},
|
||||
/* /126 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfc}}},
|
||||
/* /127 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfe}}},
|
||||
/* /128 */
|
||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff}}}};
|
||||
/* /1 */ {{{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /2 */ {{{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /3 */ {{{0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /4 */ {{{0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /5 */ {{{0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /6 */ {{{0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /7 */ {{{0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /8 */ {{{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /9 */ {{{0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /10 */ {{{0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /11 */ {{{0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /12 */ {{{0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /13 */ {{{0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /14 */ {{{0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /15 */ {{{0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /16 */ {{{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /17 */ {{{0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /18 */ {{{0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /19 */ {{{0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /20 */ {{{0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /21 */ {{{0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /22 */ {{{0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /23 */ {{{0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /24 */ {{{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /25 */ {{{0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /26 */ {{{0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /27 */ {{{0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /28 */ {{{0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /29 */ {{{0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /30 */ {{{0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /31 */ {{{0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /32 */ {{{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /33 */ {{{0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /34 */ {{{0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /35 */ {{{0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /36 */ {{{0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /37 */ {{{0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /38 */ {{{0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /39 */ {{{0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /40 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /41 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /42 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /43 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /44 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /45 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /46 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /47 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /48 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /49 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /50 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /51 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /52 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /53 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /54 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /55 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /56 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /57 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /58 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /59 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /60 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /61 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /62 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /63 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /64 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /65 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /66 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /67 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /68 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /69 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /70 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /71 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /72 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /73 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /74 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /75 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /76 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /77 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /78 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /79 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /80 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /81 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /82 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /83 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /84 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /85 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /86 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /87 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /88 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /89 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /90 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /91 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /92 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /93 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /94 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /95 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /96 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}}},
|
||||
/* /97 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00}}},
|
||||
/* /98 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00}}},
|
||||
/* /99 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00}}},
|
||||
/* /100 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00}}},
|
||||
/* /101 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00}}},
|
||||
/* /102 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00}}},
|
||||
/* /103 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00}}},
|
||||
/* /104 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00}}},
|
||||
/* /105 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00}}},
|
||||
/* /106 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00}}},
|
||||
/* /107 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00}}},
|
||||
/* /108 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00}}},
|
||||
/* /109 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00}}},
|
||||
/* /110 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00}}},
|
||||
/* /111 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00}}},
|
||||
/* /112 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00}}},
|
||||
/* /113 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00}}},
|
||||
/* /114 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00}}},
|
||||
/* /115 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00}}},
|
||||
/* /116 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00}}},
|
||||
/* /117 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00}}},
|
||||
/* /118 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00}}},
|
||||
/* /119 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00}}},
|
||||
/* /120 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}}},
|
||||
/* /121 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80}}},
|
||||
/* /122 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0}}},
|
||||
/* /123 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0}}},
|
||||
/* /124 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0}}},
|
||||
/* /125 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8}}},
|
||||
/* /126 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc}}},
|
||||
/* /127 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}}},
|
||||
/* /128 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}}};
|
||||
|
||||
/* Number of bits in prefix type. */
|
||||
#ifndef PNBBY
|
||||
@ -429,6 +301,18 @@ static const struct in6_addr maskbytes6[] = {
|
||||
|
||||
#define MASKBIT(offset) ((0xff << (PNBBY - (offset))) & 0xff)
|
||||
|
||||
static int is_zero_mac(const struct ethaddr *mac)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
if (mac->octet[i])
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int prefix_bit(const u_char *prefix, const u_char prefixlen)
|
||||
{
|
||||
unsigned int offset = prefixlen / 8;
|
||||
@ -450,6 +334,8 @@ int str2family(const char *string)
|
||||
return AF_INET6;
|
||||
else if (!strcmp("ethernet", string))
|
||||
return AF_ETHERNET;
|
||||
else if (!strcmp("evpn", string))
|
||||
return AF_EVPN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -462,6 +348,7 @@ int afi2family(afi_t afi)
|
||||
return AF_INET6;
|
||||
else if (afi == AFI_L2VPN)
|
||||
return AF_ETHERNET;
|
||||
/* NOTE: EVPN code should NOT use this interface. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -471,7 +358,7 @@ afi_t family2afi(int family)
|
||||
return AFI_IP;
|
||||
else if (family == AF_INET6)
|
||||
return AFI_IP6;
|
||||
else if (family == AF_ETHERNET)
|
||||
else if (family == AF_ETHERNET || family == AF_EVPN)
|
||||
return AFI_L2VPN;
|
||||
return 0;
|
||||
}
|
||||
@ -577,6 +464,9 @@ void prefix_copy(struct prefix *dest, const struct prefix *src)
|
||||
else if (src->family == AF_INET6)
|
||||
dest->u.prefix6 = src->u.prefix6;
|
||||
else if (src->family == AF_ETHERNET) {
|
||||
memcpy(&dest->u.prefix_eth, &src->u.prefix_eth,
|
||||
sizeof(struct ethaddr));
|
||||
} else if (src->family == AF_EVPN) {
|
||||
memcpy(&dest->u.prefix_evpn, &src->u.prefix_evpn,
|
||||
sizeof(struct evpn_addr));
|
||||
} else if (src->family == AF_UNSPEC) {
|
||||
@ -615,6 +505,10 @@ int prefix_same(const struct prefix *p1, const struct prefix *p2)
|
||||
&p2->u.prefix6.s6_addr))
|
||||
return 1;
|
||||
if (p1->family == AF_ETHERNET)
|
||||
if (!memcmp(&p1->u.prefix_eth, &p2->u.prefix_eth,
|
||||
sizeof(struct ethaddr)))
|
||||
return 1;
|
||||
if (p1->family == AF_EVPN)
|
||||
if (!memcmp(&p1->u.prefix_evpn, &p2->u.prefix_evpn,
|
||||
sizeof(struct evpn_addr)))
|
||||
return 1;
|
||||
@ -679,6 +573,8 @@ int prefix_common_bits(const struct prefix *p1, const struct prefix *p2)
|
||||
if (p1->family == AF_INET6)
|
||||
length = IPV6_MAX_BYTELEN;
|
||||
if (p1->family == AF_ETHERNET)
|
||||
length = ETH_ALEN;
|
||||
if (p1->family == AF_EVPN)
|
||||
length = 8 * sizeof(struct evpn_addr);
|
||||
|
||||
if (p1->family != p2->family || !length)
|
||||
@ -707,6 +603,8 @@ const char *prefix_family_str(const struct prefix *p)
|
||||
return "inet6";
|
||||
if (p->family == AF_ETHERNET)
|
||||
return "ether";
|
||||
if (p->family == AF_EVPN)
|
||||
return "evpn";
|
||||
return "unspec";
|
||||
}
|
||||
|
||||
@ -783,6 +681,13 @@ int str2prefix_eth(const char *str, struct prefix_eth *p)
|
||||
const char *str_addr = str;
|
||||
unsigned int a[6];
|
||||
int i;
|
||||
bool slash = false;
|
||||
|
||||
if (!strcmp(str, "any")) {
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->family = AF_ETHERNET;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Find slash inside string. */
|
||||
pnt = strchr(str, '/');
|
||||
@ -800,6 +705,7 @@ int str2prefix_eth(const char *str, struct prefix_eth *p)
|
||||
*(cp + (pnt - str)) = '\0';
|
||||
|
||||
str_addr = cp;
|
||||
slash = true;
|
||||
}
|
||||
|
||||
/* Convert string to prefix. */
|
||||
@ -814,6 +720,15 @@ int str2prefix_eth(const char *str, struct prefix_eth *p)
|
||||
}
|
||||
p->prefixlen = plen;
|
||||
p->family = AF_ETHERNET;
|
||||
|
||||
/*
|
||||
* special case to allow old configurations to work
|
||||
* Since all zero's is implicitly meant to allow
|
||||
* a comparison to zero, let's assume
|
||||
*/
|
||||
if (!slash && is_zero_mac(&(p->eth_addr)))
|
||||
p->prefixlen = 0;
|
||||
|
||||
ret = 1;
|
||||
|
||||
done:
|
||||
@ -1063,6 +978,7 @@ int prefix_blen(const struct prefix *p)
|
||||
break;
|
||||
case AF_ETHERNET:
|
||||
return ETH_ALEN;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1090,7 +1006,7 @@ int str2prefix(const char *str, struct prefix *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *prefixeth2str(const struct prefix *p, char *str, int size)
|
||||
static const char *prefixevpn2str(const struct prefix *p, char *str, int size)
|
||||
{
|
||||
u_char family;
|
||||
char buf[PREFIX2STR_BUFFER];
|
||||
@ -1134,12 +1050,8 @@ static const char *prefixeth2str(const struct prefix *p, char *str, int size)
|
||||
PREFIX2STR_BUFFER),
|
||||
p->prefixlen);
|
||||
} else {
|
||||
sprintf(str, "UNK AF_ETHER prefix");
|
||||
snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x/%d",
|
||||
p->u.prefix_eth.octet[0], p->u.prefix_eth.octet[1],
|
||||
p->u.prefix_eth.octet[2], p->u.prefix_eth.octet[3],
|
||||
p->u.prefix_eth.octet[4], p->u.prefix_eth.octet[5],
|
||||
p->prefixlen);
|
||||
sprintf(str, "Unsupported EVPN route type %d",
|
||||
p->u.prefix_evpn.route_type);
|
||||
}
|
||||
|
||||
return str;
|
||||
@ -1159,7 +1071,13 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size)
|
||||
break;
|
||||
|
||||
case AF_ETHERNET:
|
||||
prefixeth2str(p, str, size);
|
||||
snprintf(str, size, "%s/%d",
|
||||
prefix_mac2str(&p->u.prefix_eth, buf, sizeof(buf)),
|
||||
p->prefixlen);
|
||||
break;
|
||||
|
||||
case AF_EVPN:
|
||||
prefixevpn2str(p, str, size);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
16
lib/prefix.h
16
lib/prefix.h
@ -116,7 +116,18 @@ struct evpn_addr {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* IPv4 and IPv6 unified prefix structure. */
|
||||
/* The 'family' in the prefix structure is internal to FRR and need not
|
||||
* map to standard OS AF_ definitions except where needed for interacting
|
||||
* with the kernel. However, AF_ definitions are currently in use and
|
||||
* prevalent across the code. Define a new FRR-specific AF for EVPN to
|
||||
* distinguish between 'ethernet' (MAC-only) and 'evpn' prefixes and
|
||||
* ensure it does not conflict with any OS AF_ definition.
|
||||
*/
|
||||
#if !defined(AF_EVPN)
|
||||
#define AF_EVPN (AF_MAX + 1)
|
||||
#endif
|
||||
|
||||
/* FRR generic prefix structure. */
|
||||
struct prefix {
|
||||
u_char family;
|
||||
u_char prefixlen;
|
||||
@ -131,7 +142,7 @@ struct prefix {
|
||||
struct ethaddr prefix_eth; /* AF_ETHERNET */
|
||||
u_char val[8];
|
||||
uintptr_t ptr;
|
||||
struct evpn_addr prefix_evpn;
|
||||
struct evpn_addr prefix_evpn; /* AF_EVPN */
|
||||
} u __attribute__((aligned(8)));
|
||||
};
|
||||
|
||||
@ -356,6 +367,7 @@ static inline int ipv6_martian(struct in6_addr *addr)
|
||||
}
|
||||
|
||||
extern int all_digit(const char *);
|
||||
extern int macstr2prefix_evpn(const char *str, struct prefix_evpn *p);
|
||||
|
||||
/* NOTE: This routine expects the address argument in network byte order. */
|
||||
static inline int ipv4_martian(struct in_addr *addr)
|
||||
|
@ -111,6 +111,7 @@ typedef enum {
|
||||
ZEBRA_FEC_REGISTER,
|
||||
ZEBRA_FEC_UNREGISTER,
|
||||
ZEBRA_FEC_UPDATE,
|
||||
ZEBRA_ADVERTISE_DEFAULT_GW,
|
||||
ZEBRA_ADVERTISE_ALL_VNI,
|
||||
ZEBRA_VNI_ADD,
|
||||
ZEBRA_VNI_DEL,
|
||||
@ -305,6 +306,10 @@ struct zapi_pw_status {
|
||||
uint32_t status;
|
||||
};
|
||||
|
||||
/* Zebra MAC types */
|
||||
#define ZEBRA_MAC_TYPE_STICKY 0x01 /* Sticky MAC*/
|
||||
#define ZEBRA_MAC_TYPE_GW 0x02 /* gateway (SVI) mac*/
|
||||
|
||||
/* Prototypes of zebra client service functions. */
|
||||
extern struct zclient *zclient_new(struct thread_master *);
|
||||
extern void zclient_init(struct zclient *, int, u_short);
|
||||
|
@ -432,6 +432,8 @@ end
|
||||
ctx_keys.append("address-family ipv6 unicast")
|
||||
elif line == "address-family ipv4":
|
||||
ctx_keys.append("address-family ipv4 unicast")
|
||||
elif line == "address-family evpn":
|
||||
ctx_keys.append("address-family l2vpn evpn")
|
||||
else:
|
||||
ctx_keys.append(line)
|
||||
|
||||
@ -745,6 +747,37 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
|
||||
lines_to_del_to_del.append((ctx_keys, None))
|
||||
lines_to_add_to_del.append(((tmpline,), None))
|
||||
|
||||
if (len(ctx_keys) == 3 and
|
||||
ctx_keys[0].startswith('router bgp') and
|
||||
ctx_keys[1] == 'address-family l2vpn evpn' and
|
||||
ctx_keys[2].startswith('vni')):
|
||||
|
||||
re_route_target = re.search('^route-target import (.*)$', line) if line is not None else False
|
||||
|
||||
if re_route_target:
|
||||
rt = re_route_target.group(1).strip()
|
||||
route_target_import_line = line
|
||||
route_target_export_line = "route-target export %s" % rt
|
||||
route_target_both_line = "route-target both %s" % rt
|
||||
|
||||
found_route_target_export_line = line_exist(lines_to_del, ctx_keys, route_target_export_line)
|
||||
found_route_target_both_line = line_exist(lines_to_add, ctx_keys, route_target_both_line)
|
||||
|
||||
'''
|
||||
If the running configs has
|
||||
route-target import 1:1
|
||||
route-target export 1:1
|
||||
|
||||
and the config we are reloading against has
|
||||
route-target both 1:1
|
||||
|
||||
then we can ignore deleting the import/export and ignore adding the 'both'
|
||||
'''
|
||||
if found_route_target_export_line and found_route_target_both_line:
|
||||
lines_to_del_to_del.append((ctx_keys, route_target_import_line))
|
||||
lines_to_del_to_del.append((ctx_keys, route_target_export_line))
|
||||
lines_to_add_to_del.append((ctx_keys, route_target_both_line))
|
||||
|
||||
if not deleted:
|
||||
found_add_line = line_exist(lines_to_add, ctx_keys, line)
|
||||
|
||||
@ -822,6 +855,13 @@ def compare_context_objects(newconf, running):
|
||||
elif "router bgp" in running_ctx_keys[0] and len(running_ctx_keys) > 1 and delete_bgpd:
|
||||
continue
|
||||
|
||||
# Delete an entire vni sub-context under "address-family l2vpn evpn"
|
||||
elif ("router bgp" in running_ctx_keys[0] and
|
||||
len(running_ctx_keys) > 2 and
|
||||
running_ctx_keys[1].startswith('address-family l2vpn evpn') and
|
||||
running_ctx_keys[2].startswith('vni ')):
|
||||
lines_to_del.append((running_ctx_keys, None))
|
||||
|
||||
elif ("router bgp" in running_ctx_keys[0] and
|
||||
len(running_ctx_keys) > 1 and
|
||||
running_ctx_keys[1].startswith('address-family')):
|
||||
|
@ -1164,10 +1164,10 @@ DEFUNSH(VTYSH_BGPD, address_family_evpn, address_family_evpn_cmd,
|
||||
}
|
||||
|
||||
#if defined(HAVE_CUMULUS)
|
||||
DEFUNSH(VTYSH_BGPD, address_family_evpn2, address_family_evpn2_cmd,
|
||||
"address-family evpn",
|
||||
"Enter Address Family command mode\n"
|
||||
"EVPN Address family\n")
|
||||
DEFUNSH_HIDDEN(VTYSH_BGPD, address_family_evpn2, address_family_evpn2_cmd,
|
||||
"address-family evpn",
|
||||
"Enter Address Family command mode\n"
|
||||
"EVPN Address family\n")
|
||||
{
|
||||
vty->node = BGP_EVPN_NODE;
|
||||
return CMD_SUCCESS;
|
||||
|
@ -224,6 +224,10 @@ void vtysh_config_parse_line(void *arg, const char *line)
|
||||
strlen("ipv6 access-list"))
|
||||
== 0)
|
||||
config = config_get(ACCESS_IPV6_NODE, line);
|
||||
else if (strncmp(line, "mac access-list",
|
||||
strlen("mac access-list"))
|
||||
== 0)
|
||||
config = config_get(ACCESS_MAC_NODE, line);
|
||||
else if (strncmp(line, "ip prefix-list",
|
||||
strlen("ip prefix-list"))
|
||||
== 0)
|
||||
@ -302,9 +306,10 @@ void vtysh_config_parse_line(void *arg, const char *line)
|
||||
#define NO_DELIMITER(I) \
|
||||
((I) == ACCESS_NODE || (I) == PREFIX_NODE || (I) == IP_NODE \
|
||||
|| (I) == AS_LIST_NODE || (I) == COMMUNITY_LIST_NODE \
|
||||
|| (I) == ACCESS_IPV6_NODE || (I) == PREFIX_IPV6_NODE \
|
||||
|| (I) == SERVICE_NODE || (I) == FORWARDING_NODE || (I) == DEBUG_NODE \
|
||||
|| (I) == AAA_NODE || (I) == VRF_DEBUG_NODE || (I) == MPLS_NODE)
|
||||
|| (I) == ACCESS_IPV6_NODE || (I) == ACCESS_MAC_NODE \
|
||||
|| (I) == PREFIX_IPV6_NODE || (I) == SERVICE_NODE \
|
||||
|| (I) == FORWARDING_NODE || (I) == DEBUG_NODE || (I) == AAA_NODE \
|
||||
|| (I) == VRF_DEBUG_NODE || (I) == MPLS_NODE)
|
||||
|
||||
/* Display configuration to file pointer. */
|
||||
void vtysh_config_dump(FILE *fp)
|
||||
|
@ -251,6 +251,8 @@ static void netlink_determine_zebra_iftype(char *kind, zebra_iftype_t *zif_type)
|
||||
*zif_type = ZEBRA_IF_VLAN;
|
||||
else if (strcmp(kind, "vxlan") == 0)
|
||||
*zif_type = ZEBRA_IF_VXLAN;
|
||||
else if (strcmp(kind, "macvlan") == 0)
|
||||
*zif_type = ZEBRA_IF_MACVLAN;
|
||||
}
|
||||
|
||||
// Temporary Assignments to compile on older platforms.
|
||||
@ -401,16 +403,19 @@ static int get_iflink_speed(const char *ifname)
|
||||
/* use ioctl to get IP address of an interface */
|
||||
sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
if (sd < 0) {
|
||||
zlog_debug("Failure to read interface %s speed: %d %s", ifname,
|
||||
errno, safe_strerror(errno));
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug("Failure to read interface %s speed: %d %s",
|
||||
ifname, errno, safe_strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the current link state for the interface */
|
||||
rc = ioctl(sd, SIOCETHTOOL, (char *)&ifdata);
|
||||
if (rc < 0) {
|
||||
zlog_debug("IOCTL failure to read interface %s speed: %d %s",
|
||||
ifname, errno, safe_strerror(errno));
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"IOCTL failure to read interface %s speed: %d %s",
|
||||
ifname, errno, safe_strerror(errno));
|
||||
ecmd.speed_hi = 0;
|
||||
ecmd.speed = 0;
|
||||
}
|
||||
|
@ -186,11 +186,12 @@ struct rtadvconf {
|
||||
|
||||
/* Zebra interface type - ones of interest. */
|
||||
typedef enum {
|
||||
ZEBRA_IF_VXLAN, /* VxLAN interface */
|
||||
ZEBRA_IF_VRF, /* VRF device */
|
||||
ZEBRA_IF_BRIDGE, /* bridge device */
|
||||
ZEBRA_IF_VLAN, /* VLAN sub-interface */
|
||||
ZEBRA_IF_OTHER, /* Anything else */
|
||||
ZEBRA_IF_VXLAN, /* VxLAN interface */
|
||||
ZEBRA_IF_VRF, /* VRF device */
|
||||
ZEBRA_IF_BRIDGE, /* bridge device */
|
||||
ZEBRA_IF_VLAN, /* VLAN sub-interface */
|
||||
ZEBRA_IF_MACVLAN, /* MAC VLAN interface*/
|
||||
ZEBRA_IF_OTHER, /* Anything else */
|
||||
} zebra_iftype_t;
|
||||
|
||||
/* Zebra "slave" interface type */
|
||||
@ -295,6 +296,9 @@ static inline void zebra_if_set_ziftype(struct interface *ifp,
|
||||
#define IS_ZEBRA_IF_VXLAN(ifp) \
|
||||
(((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_VXLAN)
|
||||
|
||||
#define IS_ZEBRA_IF_MACVLAN(ifp) \
|
||||
(((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_MACVLAN)
|
||||
|
||||
#define IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) \
|
||||
(((struct zebra_if *)(ifp->info))->zif_slave_type \
|
||||
== ZEBRA_IF_SLAVE_BRIDGE)
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "zebra/debug.h"
|
||||
#include "zebra/router-id.h"
|
||||
#include "zebra/zebra_memory.h"
|
||||
#include "zebra/zebra_vxlan.h"
|
||||
|
||||
#define ZEBRA_PTM_SUPPORT
|
||||
|
||||
@ -402,6 +403,8 @@ void zebra_interface_address_add_update(struct interface *ifp,
|
||||
zlog_warn(
|
||||
"WARNING: advertising address to clients that is not yet usable.");
|
||||
|
||||
zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 1);
|
||||
|
||||
router_id_add_address(ifc);
|
||||
|
||||
for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
|
||||
@ -428,6 +431,8 @@ void zebra_interface_address_delete_update(struct interface *ifp,
|
||||
prefix2str(p, buf, sizeof(buf)), ifc->ifp->name);
|
||||
}
|
||||
|
||||
zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
|
||||
|
||||
router_id_del_address(ifc);
|
||||
|
||||
for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
|
||||
|
@ -1321,9 +1321,9 @@ static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
vty_out(vty, "%s",
|
||||
CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED) ? " (installed)"
|
||||
: "");
|
||||
vty_out(vty, "%s", CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)
|
||||
? " (installed)"
|
||||
: "");
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
|
||||
@ -2807,6 +2807,8 @@ void zebra_mpls_close_tables(struct zebra_vrf *zvrf)
|
||||
hash_free(zvrf->lsp_table);
|
||||
hash_clean(zvrf->slsp_table, NULL);
|
||||
hash_free(zvrf->slsp_table);
|
||||
route_table_finish(zvrf->fec_table[AFI_IP]);
|
||||
route_table_finish(zvrf->fec_table[AFI_IP6]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -107,6 +107,11 @@ struct zebra_vrf {
|
||||
*/
|
||||
int advertise_all_vni;
|
||||
|
||||
/*
|
||||
* Whether we are advertising g/w macip in EVPN or not.
|
||||
*/
|
||||
int advertise_gw_macip;
|
||||
|
||||
/* Route Installs */
|
||||
uint64_t installs;
|
||||
uint64_t removals;
|
||||
|
@ -2285,89 +2285,100 @@ DEFUN (show_vrf,
|
||||
|
||||
DEFUN (show_evpn_vni,
|
||||
show_evpn_vni_cmd,
|
||||
"show evpn vni",
|
||||
"show evpn vni [json]",
|
||||
SHOW_STR
|
||||
"EVPN\n"
|
||||
"VxLAN information\n")
|
||||
"VxLAN information\n"
|
||||
JSON_STR)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
u_char uj = use_json(argc, argv);
|
||||
|
||||
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
||||
zebra_vxlan_print_vnis(vty, zvrf);
|
||||
zebra_vxlan_print_vnis(vty, zvrf, uj);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_evpn_vni_vni,
|
||||
show_evpn_vni_vni_cmd,
|
||||
"show evpn vni " CMD_VNI_RANGE,
|
||||
"show evpn vni " CMD_VNI_RANGE "[json]",
|
||||
SHOW_STR
|
||||
"EVPN\n"
|
||||
"VxLAN Network Identifier\n"
|
||||
"VNI number\n")
|
||||
"VNI number\n"
|
||||
JSON_STR)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
vni_t vni;
|
||||
u_char uj = use_json(argc, argv);
|
||||
|
||||
vni = strtoul(argv[3]->arg, NULL, 10);
|
||||
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
||||
zebra_vxlan_print_vni(vty, zvrf, vni);
|
||||
zebra_vxlan_print_vni(vty, zvrf, vni, uj);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_evpn_mac_vni,
|
||||
show_evpn_mac_vni_cmd,
|
||||
"show evpn mac vni " CMD_VNI_RANGE,
|
||||
"show evpn mac vni " CMD_VNI_RANGE "[json]",
|
||||
SHOW_STR
|
||||
"EVPN\n"
|
||||
"MAC addresses\n"
|
||||
"VxLAN Network Identifier\n"
|
||||
"VNI number\n")
|
||||
"VNI number\n"
|
||||
JSON_STR)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
vni_t vni;
|
||||
u_char uj = use_json(argc, argv);
|
||||
|
||||
vni = strtoul(argv[4]->arg, NULL, 10);
|
||||
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
||||
zebra_vxlan_print_macs_vni(vty, zvrf, vni);
|
||||
zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_evpn_mac_vni_all,
|
||||
show_evpn_mac_vni_all_cmd,
|
||||
"show evpn mac vni all",
|
||||
"show evpn mac vni all [json]",
|
||||
SHOW_STR
|
||||
"EVPN\n"
|
||||
"MAC addresses\n"
|
||||
"VxLAN Network Identifier\n"
|
||||
"All VNIs\n")
|
||||
"All VNIs\n"
|
||||
JSON_STR)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
u_char uj = use_json(argc, argv);
|
||||
|
||||
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
||||
zebra_vxlan_print_macs_all_vni(vty, zvrf);
|
||||
zebra_vxlan_print_macs_all_vni(vty, zvrf, uj);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_evpn_mac_vni_all_vtep,
|
||||
show_evpn_mac_vni_all_vtep_cmd,
|
||||
"show evpn mac vni all vtep A.B.C.D",
|
||||
"show evpn mac vni all vtep A.B.C.D [json]",
|
||||
SHOW_STR
|
||||
"EVPN\n"
|
||||
"MAC addresses\n"
|
||||
"VxLAN Network Identifier\n"
|
||||
"All VNIs\n"
|
||||
"Remote VTEP\n"
|
||||
"Remote VTEP IP address\n")
|
||||
"Remote VTEP IP address\n"
|
||||
JSON_STR)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
struct in_addr vtep_ip;
|
||||
u_char uj = use_json(argc, argv);
|
||||
|
||||
if (!inet_aton(argv[6]->arg, &vtep_ip)) {
|
||||
vty_out(vty, "%% Malformed VTEP IP address\n");
|
||||
if (!uj)
|
||||
vty_out(vty, "%% Malformed VTEP IP address\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
||||
zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip);
|
||||
zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@ -2400,112 +2411,125 @@ DEFUN (show_evpn_mac_vni_mac,
|
||||
|
||||
DEFUN (show_evpn_mac_vni_vtep,
|
||||
show_evpn_mac_vni_vtep_cmd,
|
||||
"show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D",
|
||||
"show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
|
||||
SHOW_STR
|
||||
"EVPN\n"
|
||||
"MAC addresses\n"
|
||||
"VxLAN Network Identifier\n"
|
||||
"VNI number\n"
|
||||
"Remote VTEP\n"
|
||||
"Remote VTEP IP address\n")
|
||||
"Remote VTEP IP address\n"
|
||||
JSON_STR)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
vni_t vni;
|
||||
struct in_addr vtep_ip;
|
||||
u_char uj = use_json(argc, argv);
|
||||
|
||||
vni = strtoul(argv[4]->arg, NULL, 10);
|
||||
if (!inet_aton(argv[6]->arg, &vtep_ip)) {
|
||||
vty_out(vty, "%% Malformed VTEP IP address\n");
|
||||
if (!uj)
|
||||
vty_out(vty, "%% Malformed VTEP IP address\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
||||
zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip);
|
||||
zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_evpn_neigh_vni,
|
||||
show_evpn_neigh_vni_cmd,
|
||||
"show evpn arp-cache vni " CMD_VNI_RANGE,
|
||||
"show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
|
||||
SHOW_STR
|
||||
"EVPN\n"
|
||||
"ARP and ND cache\n"
|
||||
"VxLAN Network Identifier\n"
|
||||
"VNI number\n")
|
||||
"VNI number\n"
|
||||
JSON_STR)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
vni_t vni;
|
||||
u_char uj = use_json(argc, argv);
|
||||
|
||||
vni = strtoul(argv[4]->arg, NULL, 10);
|
||||
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
||||
zebra_vxlan_print_neigh_vni(vty, zvrf, vni);
|
||||
zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_evpn_neigh_vni_all,
|
||||
show_evpn_neigh_vni_all_cmd,
|
||||
"show evpn arp-cache vni all",
|
||||
"show evpn arp-cache vni all [json]",
|
||||
SHOW_STR
|
||||
"EVPN\n"
|
||||
"ARP and ND cache\n"
|
||||
"VxLAN Network Identifier\n"
|
||||
"All VNIs\n")
|
||||
"All VNIs\n"
|
||||
JSON_STR)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
u_char uj = use_json(argc, argv);
|
||||
|
||||
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
||||
zebra_vxlan_print_neigh_all_vni(vty, zvrf);
|
||||
zebra_vxlan_print_neigh_all_vni(vty, zvrf, uj);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_evpn_neigh_vni_neigh,
|
||||
show_evpn_neigh_vni_neigh_cmd,
|
||||
"show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD",
|
||||
"show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
|
||||
SHOW_STR
|
||||
"EVPN\n"
|
||||
"ARP and ND cache\n"
|
||||
"VxLAN Network Identifier\n"
|
||||
"VNI number\n"
|
||||
"Neighbor\n"
|
||||
"Neighbor address (IPv4 or IPv6 address)\n")
|
||||
"Neighbor address (IPv4 or IPv6 address)\n"
|
||||
JSON_STR)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
vni_t vni;
|
||||
struct ipaddr ip;
|
||||
u_char uj = use_json(argc, argv);
|
||||
|
||||
vni = strtoul(argv[4]->arg, NULL, 10);
|
||||
if (str2ipaddr(argv[6]->arg, &ip) != 0) {
|
||||
vty_out(vty, "%% Malformed Neighbor address\n");
|
||||
if (!uj)
|
||||
vty_out(vty, "%% Malformed Neighbor address\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
||||
zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip);
|
||||
zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_evpn_neigh_vni_vtep,
|
||||
show_evpn_neigh_vni_vtep_cmd,
|
||||
"show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D",
|
||||
"show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
|
||||
SHOW_STR
|
||||
"EVPN\n"
|
||||
"ARP and ND cache\n"
|
||||
"VxLAN Network Identifier\n"
|
||||
"VNI number\n"
|
||||
"Remote VTEP\n"
|
||||
"Remote VTEP IP address\n")
|
||||
"Remote VTEP IP address\n"
|
||||
JSON_STR)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
vni_t vni;
|
||||
struct in_addr vtep_ip;
|
||||
u_char uj = use_json(argc, argv);
|
||||
|
||||
vni = strtoul(argv[4]->arg, NULL, 10);
|
||||
if (!inet_aton(argv[6]->arg, &vtep_ip)) {
|
||||
vty_out(vty, "%% Malformed VTEP IP address\n");
|
||||
if (!uj)
|
||||
vty_out(vty, "%% Malformed VTEP IP address\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
||||
zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip);
|
||||
zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
1565
zebra/zebra_vxlan.c
1565
zebra/zebra_vxlan.c
File diff suppressed because it is too large
Load Diff
@ -41,33 +41,44 @@
|
||||
#define ZEBRA_VXLIF_MASTER_CHANGE 0x2
|
||||
#define ZEBRA_VXLIF_VLAN_CHANGE 0x4
|
||||
|
||||
#define VNI_STR_LEN 32
|
||||
|
||||
extern void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
|
||||
vni_t vni);
|
||||
vni_t vni, u_char use_json);
|
||||
extern void zebra_vxlan_print_macs_all_vni(struct vty *vty,
|
||||
struct zebra_vrf *zvrf);
|
||||
struct zebra_vrf *zvrf,
|
||||
u_char use_json);
|
||||
extern void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
|
||||
struct zebra_vrf *zvrf,
|
||||
struct in_addr vtep_ip);
|
||||
struct in_addr vtep_ip,
|
||||
u_char use_json);
|
||||
extern void zebra_vxlan_print_specific_mac_vni(struct vty *vty,
|
||||
struct zebra_vrf *zvrf,
|
||||
vni_t vni, struct ethaddr *mac);
|
||||
extern void zebra_vxlan_print_macs_vni_vtep(struct vty *vty,
|
||||
struct zebra_vrf *zvrf, vni_t vni,
|
||||
struct in_addr vtep_ip);
|
||||
struct in_addr vtep_ip,
|
||||
u_char use_json);
|
||||
extern void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
|
||||
vni_t vni);
|
||||
vni_t vni, u_char use_json);
|
||||
extern void zebra_vxlan_print_neigh_all_vni(struct vty *vty,
|
||||
struct zebra_vrf *zvrf);
|
||||
struct zebra_vrf *zvrf,
|
||||
u_char use_json);
|
||||
extern void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
|
||||
struct zebra_vrf *zvrf,
|
||||
vni_t vni, struct ipaddr *ip);
|
||||
vni_t vni, struct ipaddr *ip,
|
||||
u_char use_json);
|
||||
extern void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty,
|
||||
struct zebra_vrf *zvrf, vni_t vni,
|
||||
struct in_addr vtep_ip);
|
||||
struct in_addr vtep_ip,
|
||||
u_char use_json);
|
||||
extern void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf,
|
||||
vni_t vni);
|
||||
extern void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf);
|
||||
vni_t vni, u_char use_json);
|
||||
extern void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
|
||||
u_char use_json);
|
||||
|
||||
extern int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
|
||||
int add);
|
||||
extern int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if);
|
||||
extern int zebra_vxlan_svi_down(struct interface *ifp,
|
||||
struct interface *link_if);
|
||||
@ -104,6 +115,9 @@ extern int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock,
|
||||
u_short length, struct zebra_vrf *zvrf);
|
||||
extern int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock,
|
||||
u_short length, struct zebra_vrf *zvrf);
|
||||
extern int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock,
|
||||
u_short length,
|
||||
struct zebra_vrf *zvrf);
|
||||
extern int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock,
|
||||
u_short length,
|
||||
struct zebra_vrf *zvrf);
|
||||
|
@ -63,6 +63,9 @@ struct zebra_vni_t_ {
|
||||
/* VNI - key */
|
||||
vni_t vni;
|
||||
|
||||
/* Flag for advertising gw macip */
|
||||
u_int8_t advertise_gw_macip;
|
||||
|
||||
/* Corresponding VxLAN interface. */
|
||||
struct interface *vxlan_if;
|
||||
|
||||
@ -112,6 +115,9 @@ struct zebra_mac_t_ {
|
||||
} fwd_info;
|
||||
|
||||
u_int32_t neigh_refcnt;
|
||||
|
||||
/* List of neigh associated with this mac */
|
||||
struct list *neigh_list;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -132,10 +138,21 @@ struct mac_walk_ctx {
|
||||
|
||||
struct in_addr r_vtep_ip; /* To walk MACs from specific VTEP */
|
||||
|
||||
struct vty *vty; /* Used by VTY handlers */
|
||||
u_int32_t count; /* Used by VTY handlers */
|
||||
struct vty *vty; /* Used by VTY handlers */
|
||||
u_int32_t count; /* Used by VTY handlers */
|
||||
struct json_object *json; /* Used for JSON Output */
|
||||
};
|
||||
|
||||
enum zebra_neigh_state { ZEBRA_NEIGH_INACTIVE = 0, ZEBRA_NEIGH_ACTIVE = 1 };
|
||||
|
||||
#define IS_ZEBRA_NEIGH_ACTIVE(n) n->state == ZEBRA_NEIGH_ACTIVE
|
||||
|
||||
#define IS_ZEBRA_NEIGH_INACTIVE(n) n->state == ZEBRA_NEIGH_INACTIVE
|
||||
|
||||
#define ZEBRA_NEIGH_SET_ACTIVE(n) n->state = ZEBRA_NEIGH_ACTIVE
|
||||
|
||||
#define ZEBRA_NEIGH_SET_INACTIVE(n) n->state = ZEBRA_NEIGH_INACTIVE
|
||||
|
||||
/*
|
||||
* Neighbor hash table.
|
||||
*
|
||||
@ -158,8 +175,10 @@ struct zebra_neigh_t_ {
|
||||
ifindex_t ifindex;
|
||||
|
||||
u_int32_t flags;
|
||||
#define ZEBRA_NEIGH_LOCAL 0x01
|
||||
#define ZEBRA_NEIGH_REMOTE 0x02
|
||||
#define ZEBRA_NEIGH_LOCAL 0x01
|
||||
#define ZEBRA_NEIGH_REMOTE 0x02
|
||||
|
||||
enum zebra_neigh_state state;
|
||||
|
||||
/* Remote VTEP IP - applicable only for remote neighbors. */
|
||||
struct in_addr r_vtep_ip;
|
||||
@ -183,9 +202,10 @@ struct neigh_walk_ctx {
|
||||
|
||||
struct in_addr r_vtep_ip; /* To walk neighbors from specific VTEP */
|
||||
|
||||
struct vty *vty; /* Used by VTY handlers */
|
||||
u_int32_t count; /* Used by VTY handlers */
|
||||
u_char addr_width; /* Used by VTY handlers */
|
||||
struct vty *vty; /* Used by VTY handlers */
|
||||
u_int32_t count; /* Used by VTY handlers */
|
||||
u_char addr_width; /* Used by VTY handlers */
|
||||
struct json_object *json; /* Used for JSON Output */
|
||||
};
|
||||
|
||||
#endif /* _ZEBRA_VXLAN_PRIVATE_H */
|
||||
|
@ -2533,6 +2533,9 @@ static int zebra_client_read(struct thread *thread)
|
||||
case ZEBRA_FEC_UNREGISTER:
|
||||
zserv_fec_unregister(client, sock, length);
|
||||
break;
|
||||
case ZEBRA_ADVERTISE_DEFAULT_GW:
|
||||
zebra_vxlan_advertise_gw_macip(client, sock, length, zvrf);
|
||||
break;
|
||||
case ZEBRA_ADVERTISE_ALL_VNI:
|
||||
zebra_vxlan_advertise_all_vni(client, sock, length, zvrf);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user