* NOTE: We don't use prefix2str as the output here is a bit different.
*/
void
-bgp_evpn_route2json (struct prefix_evpn *p, json_object *json)
+bgp_evpn_route2json(struct prefix_evpn *p, json_object *json)
{
- char buf1[ETHER_ADDR_STRLEN];
- char buf2[PREFIX2STR_BUFFER];
+ char buf1[ETHER_ADDR_STRLEN];
+ char buf2[PREFIX2STR_BUFFER];
- if (!json)
- return;
+ if (!json)
+ return;
if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) {
- json_object_int_add (json, "routeType", p->prefix.route_type);
- json_object_int_add (json, "ethTag", 0);
- json_object_int_add (json,
- "ipLen",
- IS_EVPN_PREFIX_IPADDR_V4 (p) ?
+ json_object_int_add(json, "routeType", p->prefix.route_type);
+ json_object_int_add(json, "ethTag", 0);
+ json_object_int_add(json,
+ "ipLen",
+ IS_EVPN_PREFIX_IPADDR_V4 (p) ?
IPV4_MAX_BITLEN : IPV6_MAX_BITLEN);
- json_object_string_add (json, "ip",
- inet_ntoa (p->prefix.ip.ipaddr_v4));
+ json_object_string_add(json, "ip",
+ inet_ntoa (p->prefix.ip.ipaddr_v4));
}
else if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
if (IS_EVPN_PREFIX_IPADDR_NONE(p)) {
- json_object_int_add (json, "routeType", p->prefix.route_type);
- json_object_int_add (json, "esi", 0); /* TODO: we don't support esi yet */
- json_object_int_add (json, "ethTag", 0);
- json_object_int_add (json, "macLen", 8 * ETH_ALEN);
- json_object_string_add (json, "mac",
- prefix_mac2str (&p->prefix.mac,
- buf1, sizeof (buf1)));
+ json_object_int_add(json, "routeType", p->prefix.route_type);
+ json_object_int_add(json, "esi", 0); /* TODO: we don't support esi yet */
+ json_object_int_add(json, "ethTag", 0);
+ json_object_int_add(json, "macLen", 8 * ETH_ALEN);
+ json_object_string_add(json, "mac",
+ prefix_mac2str (&p->prefix.mac,
+ buf1, sizeof (buf1)));
} else {
u_char family;
family = IS_EVPN_PREFIX_IPADDR_V4(p) ? \
AF_INET : AF_INET6;
- json_object_int_add (json, "routeType",
+ json_object_int_add(json, "routeType",
p->prefix.route_type);
- json_object_int_add (json, "esi", 0); /* TODO: we don't support esi yet */
- json_object_int_add (json, "ethTag", 0);
- json_object_int_add (json, "macLen",
- 8 * ETH_ALEN);
- json_object_string_add (json, "mac",
- prefix_mac2str (&p->prefix.mac,
- buf1,
- sizeof (buf1)));
- json_object_int_add (json, "ipLen",
- IS_EVPN_PREFIX_IPADDR_V4 (p) ?
+ json_object_int_add(json, "esi", 0); /* TODO: we don't support esi yet */
+ json_object_int_add(json, "ethTag", 0);
+ json_object_int_add(json, "macLen",
+ 8 * ETH_ALEN);
+ json_object_string_add(json, "mac",
+ prefix_mac2str (&p->prefix.mac,
+ buf1,
+ sizeof (buf1)));
+ json_object_int_add(json, "ipLen",
+ IS_EVPN_PREFIX_IPADDR_V4 (p) ?
IPV4_MAX_BITLEN :
IPV6_MAX_BITLEN);
- json_object_string_add (json, "ip",
- inet_ntop (family,
- &p->prefix.ip.ip.addr,
- buf2,
- PREFIX2STR_BUFFER));
+ json_object_string_add(json, "ip",
+ inet_ntop (family,
+ &p->prefix.ip.ip.addr,
+ buf2,
+ PREFIX2STR_BUFFER));
}
} else {
/* Currently, this is to cater to other AF_ETHERNET code. */
if (bgp_debug_update(ri->peer, &rn->p,
NULL, 1))
zlog_debug(
- "%u: prefix %s with "
- "attr %s - DENIED"
- "due to martian or seld"
- "nexthop",
+ "%u: prefix %s with attr %s - DENIED due to martian or self nexthop",
bgp->vrf_id,
prefix2str(
&rn->p,
extern void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw);
extern char *bgp_evpn_label2str(mpls_label_t *label, char *buf, int len);
extern char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len);
-extern void
-bgp_evpn_route2json (struct prefix_evpn *p, json_object *json);
+extern void bgp_evpn_route2json(struct prefix_evpn *p, json_object *json);
extern void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
struct prefix_rd *prd, mpls_label_t *label,
struct attr *attr, int addpath_encode,
char rt_buf[RT_ADDRSTRLEN];
if (json) {
- json_rt = json_object_new_object ();
- json_vnis = json_object_new_array ();
+ json_rt = json_object_new_object();
+ json_vnis = json_object_new_array();
}
/* TODO: This needs to go into a function */
if (json) {
char vni_str[VNI_STR_LEN];
+
json_object_object_add(json_vni, "exportRTs", json_export_rtl);
snprintf(vni_str, VNI_STR_LEN, "%u", vpn->vni);
json_object_object_add(json, vni_str, json_vni);
|| (IN_CLASSB(destination) && p->prefixlen == 16)
|| (IN_CLASSA(destination) && p->prefixlen == 8)
|| p->u.prefix4.s_addr == 0) {
- /* When mask is natural, mask is not displayed. */
+ /* When mask is natural,
+ mask is not displayed. */
} else
len += vty_out(vty, "/%d", p->prefixlen);
} else {
len = vty_out(vty, "%s", buf);
} else if (p->family == AF_EVPN) {
#if defined(HAVE_CUMULUS)
- if (!json)
- len = vty_out (vty, "%s",
- bgp_evpn_route2str((struct prefix_evpn *)p,
- buf, BUFSIZ));
- else
- bgp_evpn_route2json ( (struct prefix_evpn *) p, json);
+ if (!json)
+ len = vty_out(vty, "%s",
+ bgp_evpn_route2str((struct prefix_evpn *)p,
+ buf, BUFSIZ));
+ else
+ bgp_evpn_route2json((struct prefix_evpn *) p, json);
#else
prefix2str(p, buf, PREFIX_STRLEN);
len = vty_out(vty, "%s", buf);
else
vty_out(vty, "%*s", 17, " ");
} else {
- route_vty_out_route (p, vty, json_path);
+ route_vty_out_route(p, vty, json_path);
}
/* Print attribute */
if (has_valid_label)
json_object_int_add(json, "localLabel", label);
- json_object_string_add (json, "prefix",
- prefix2str (p, prefix_str,
- sizeof (prefix_str)));
+ json_object_string_add(json, "prefix",
+ prefix2str(p, prefix_str,
+ sizeof(prefix_str)));
} else {
#if defined(HAVE_CUMULUS)
if (safi == SAFI_EVPN)
" Hostname Capability:");
if (CHECK_FLAG(p->cap, PEER_CAP_HOSTNAME_ADV)) {
- vty_out(vty, " advertised (name: %s, "
- "domain name: %s)",
+ vty_out(vty, " advertised (name: %s,domain name: %s)",
bgp->peer_self->hostname ?
bgp->peer_self->hostname
: "n/a",
}
if (CHECK_FLAG(p->cap, PEER_CAP_HOSTNAME_RCV)) {
- vty_out(vty, " received (name: %s, "
- "domain name: %s)",
+ vty_out(vty, " received (name: %s,domain name: %s)",
p->hostname ?
p->hostname : "n/a",
p->domainname ?
/* Set up or remove link with master */
if (bridge_ifindex != IFINDEX_INTERNAL) {
- zebra_l2_map_slave_to_bridge (&zif->brslave_info);
+ zebra_l2_map_slave_to_bridge(&zif->brslave_info);
/* In the case of VxLAN, invoke the handler for EVPN. */
if (zif->zif_type == ZEBRA_IF_VXLAN)
- zebra_vxlan_if_update (ifp, ZEBRA_VXLIF_MASTER_CHANGE);
+ zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
} else if (old_bridge_ifindex != IFINDEX_INTERNAL) {
- /* In the case of VxLAN, invoke the handler for EVPN. Note that
- * this should be done *prior* to unmapping the interface from the
- * bridge.
+ /* In the case of VxLAN, invoke the handler for EVPN.
+ * Note that this should be done *prior* to unmapping the interface
+ * from the bridge.
*/
if (zif->zif_type == ZEBRA_IF_VXLAN)
- zebra_vxlan_if_update (ifp, ZEBRA_VXLIF_MASTER_CHANGE);
- zebra_l2_unmap_slave_from_bridge (&zif->brslave_info);
+ zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
+ zebra_l2_unmap_slave_from_bridge(&zif->brslave_info);
}
}
zif = ifp->info;
/* If down or not mapped to a bridge, we're done. */
- if (!if_is_operative (ifp) || !zif->brslave_info.br_if)
+ if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
return;
zl2_info = zif->l2info.vxl;
zif = ifp->info;
/* If down or not mapped to a bridge, we're done. */
- if (!if_is_operative (ifp) || !zif->brslave_info.br_if)
+ if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
return;
zl2_info = zif->l2info.vxl;
zebra_vni_t *zvni;
zebra_neigh_t *n;
struct zebra_vrf *zvrf;
- zebra_mac_t *zmac;
+ zebra_mac_t *zmac, *old_zmac;
char buf[ETHER_ADDR_STRLEN];
char buf2[INET6_ADDRSTRLEN];
- int send_upd = 1, send_del = 0;
/* We are only interested in neighbors on an SVI that resides on top
* of a VxLAN bridge.
if (memcmp(n->emac.octet, macaddr->octet,
ETH_ALEN)
== 0) {
- if (n->ifindex == ifp->ifindex)
- /* we're not interested in whatever has
- * changed. */
- return 0;
- /* client doesn't care about a purely local
- * change. */
- send_upd = 0;
- } else
- /* If the MAC has changed, issue a delete first
- * as this means a
- * different MACIP route.
+ /* Update any params and return - client doesn't
+ * care about a purely local change.
+ */
+ n->ifindex = ifp->ifindex;
+ return 0;
+ } else {
+ /* If the MAC has changed,
+ * need to issue a delete first
+ * as this means a different MACIP route.
+ * Also, need to do some unlinking/relinking.
*/
- send_del = 1;
+ zvni_neigh_send_del_to_client(zvrf, zvni->vni,
+ &n->ip, &n->emac,
+ 0);
+ old_zmac = zvni_mac_lookup(zvni, &n->emac);
+ if (old_zmac) {
+ listnode_delete(old_zmac->neigh_list,
+ n);
+ zvni_deref_ip2mac(zvni, old_zmac, 0);
+ }
+
+ /* Set "local" forwarding info. */
+ SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
+ n->ifindex = ifp->ifindex;
+ memcpy(&n->emac, macaddr, ETH_ALEN);
+
+ /* Link to new MAC */
+ listnode_add_sort(zmac->neigh_list, n);
+ }
} else if (ext_learned)
/* The neighbor is remote and that is the notification we got.
*/
{
UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
n->r_vtep_ip.s_addr = 0;
+ SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
+ n->ifindex = ifp->ifindex;
}
} else {
n = zvni_neigh_add(zvni, ip, macaddr);
ifp->name, ifp->ifindex, zvni->vni);
return -1;
}
+ /* Set "local" forwarding info. */
+ SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
+ n->ifindex = ifp->ifindex;
}
- /* Issue delete for older info, if needed. */
- if (send_del)
- zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip, &n->emac,
- 0);
-
- /* Set "local" forwarding info. */
- SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
- n->ifindex = ifp->ifindex;
-
/* Before we program this in BGP, we need to check if MAC is locally
* learnt as well */
if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) {
return 0;
}
- /* Inform BGP if required. */
- if (send_upd) {
- if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug(
- "%u: neigh %s (MAC %s) is now ACTIVE on VNI %u",
- ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
- prefix_mac2str(macaddr, buf, sizeof(buf)),
- zvni->vni);
-
- ZEBRA_NEIGH_SET_ACTIVE(n);
- return zvni_neigh_send_add_to_client(zvrf, zvni->vni, ip,
- macaddr, 0);
- }
+ /* Inform BGP. */
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug(
+ "%u: neigh %s (MAC %s) is now ACTIVE on VNI %u",
+ ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
+ prefix_mac2str(macaddr, buf, sizeof(buf)),
+ zvni->vni);
- return 0;
+ ZEBRA_NEIGH_SET_ACTIVE(n);
+ return zvni_neigh_send_add_to_client(zvrf, zvni->vni, ip,
+ macaddr, 0);
}
+
/*
* Handle message from client to delete a remote MACIP for a VNI.
*/
zif = ifp->info;
/* If down or not mapped to a bridge, we're done. */
- if (!if_is_operative (ifp) || !zif->brslave_info.br_if)
+ if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
continue;
/* The remote VTEP specified is normally expected to exist, but
zif = ifp->info;
/* If down or not mapped to a bridge, we're done. */
- if (!if_is_operative (ifp) || !zif->brslave_info.br_if)
+ if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
continue;
/* The remote VTEP specified should normally exist, but it is
ifp = zvni->vxlan_if;
if (!ifp) {
- zlog_err ("VNI %u hash %p doesn't have intf upon remote VTEP DEL",
- zvni->vni, zvni);
- continue;
+ zlog_err("VNI %u hash %p doesn't have intf upon remote VTEP DEL",
+ zvni->vni, zvni);
+ continue;
}
zif = ifp->info;
/* If down or not mapped to a bridge, we're done. */
- if (!if_is_operative (ifp) || !zif->brslave_info.br_if)
+ if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
continue;
/* If the remote VTEP does not exist, there's nothing more to
zif = ifp->info;
/* If down or not mapped to a bridge, we're done. */
- if (!if_is_operative (ifp) || !zif->brslave_info.br_if)
+ if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
continue;
- /* If the remote VTEP already exists, there's nothing more to do. */
+ /* If the remote VTEP already exists,
+ there's nothing more to do. */
if (zvni_vtep_find(zvni, &vtep_ip))
continue;
zif = ifp->info;
/* If down or not mapped to a bridge, we're done. */
- if (!if_is_operative (ifp) || !zif->brslave_info.br_if)
+ if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
return 0;
zl2_info = zif->l2info.vxl;