#include "bgpd/bgp_zebra.h"
#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_errors.h"
#include "bgpd/bgp_mpath.h"
#include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_nht.h"
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id(vrf_id);
- if (!bgp)
- return 0;
s = zclient->ibuf;
ifp = zebra_interface_state_read(s, vrf_id);
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Rx Intf del VRF %u IF %s", vrf_id, ifp->name);
- bgp_update_interface_nbrs(bgp, ifp, NULL);
+ if (bgp)
+ bgp_update_interface_nbrs(bgp, ifp, NULL);
if_set_index(ifp, IFINDEX_INTERNAL);
return 0;
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id(vrf_id);
- if (!bgp)
- return 0;
s = zclient->ibuf;
ifp = zebra_interface_state_read(s, vrf_id);
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Rx Intf up VRF %u IF %s", vrf_id, ifp->name);
+ if (!bgp)
+ return 0;
+
for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
bgp_connected_add(bgp, c);
struct nbr_connected *nc;
struct listnode *node, *nnode;
struct bgp *bgp;
+ struct peer *peer;
bgp = bgp_lookup_by_vrf_id(vrf_id);
- if (!bgp)
- return 0;
s = zclient->ibuf;
ifp = zebra_interface_state_read(s, vrf_id);
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Rx Intf down VRF %u IF %s", vrf_id, ifp->name);
+ if (!bgp)
+ return 0;
+
for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
bgp_connected_delete(bgp, c);
bgp_nbr_connected_delete(bgp, nc, 1);
/* Fast external-failover */
- {
- struct peer *peer;
-
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
- return 0;
+ if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) {
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
#if defined(HAVE_CUMULUS)
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id(vrf_id);
- if (!bgp)
- return 0;
ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
ifc->ifp->name, buf);
}
+ if (!bgp)
+ return 0;
+
if (if_is_operative(ifc->ifp)) {
bgp_connected_add(bgp, ifc);
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id(vrf_id);
- if (!bgp)
- return 0;
ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
ifc->ifp->name, buf);
}
- if (if_is_operative(ifc->ifp)) {
+ if (bgp && if_is_operative(ifc->ifp)) {
bgp_connected_delete(bgp, ifc);
}
struct nbr_connected *nc;
struct listnode *node, *nnode;
struct bgp *bgp;
+ struct peer *peer;
ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
&new_vrf_id);
ifp->name, new_vrf_id);
bgp = bgp_lookup_by_vrf_id(vrf_id);
- if (!bgp)
- return 0;
- for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
- bgp_connected_delete(bgp, c);
+ if (bgp) {
+ for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
+ bgp_connected_delete(bgp, c);
- for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc))
- bgp_nbr_connected_delete(bgp, nc, 1);
+ for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc))
+ bgp_nbr_connected_delete(bgp, nc, 1);
- /* Fast external-failover */
- {
- struct peer *peer;
-
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
- return 0;
-
- for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
- if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
- continue;
+ /* Fast external-failover */
+ if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) {
+ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+ if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
+ continue;
- if (ifp == peer->nexthop.ifp)
- BGP_EVENT_ADD(peer, BGP_Stop);
+ if (ifp == peer->nexthop.ifp)
+ BGP_EVENT_ADD(peer, BGP_Stop);
+ }
}
}
return 0;
}
-int bgp_nexthop_set(union sockunion *local, union sockunion *remote,
- struct bgp_nexthop *nexthop, struct peer *peer)
+
+bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
+ struct bgp_nexthop *nexthop, struct peer *peer)
{
int ret = 0;
struct interface *ifp = NULL;
memset(nexthop, 0, sizeof(struct bgp_nexthop));
if (!local)
- return -1;
+ return false;
if (!remote)
- return -1;
+ return false;
if (local->sa.sa_family == AF_INET) {
nexthop->v4 = local->sin.sin_addr;
peer->bgp->vrf_id);
}
- if (!ifp)
- return -1;
+ if (!ifp) {
+ /*
+ * BGP views do not currently get proper data
+ * from zebra( when attached ) to be able to
+ * properly resolve nexthops, so give this
+ * instance type a pass.
+ */
+ if (peer->bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
+ return true;
+ /*
+ * If we have no interface data but we have established
+ * some connection w/ zebra than something has gone
+ * terribly terribly wrong here, so say this failed
+ * If we do not any zebra connection then not
+ * having a ifp pointer is ok.
+ */
+ return zclient_num_connects ? false : true;
+ }
nexthop->ifp = ifp;
/* If we have identified the local interface, there is no error for now.
*/
- return 0;
+ return true;
}
-static struct in6_addr *bgp_info_to_ipv6_nexthop(struct bgp_info *info,
- ifindex_t *ifindex)
+static struct in6_addr *
+bgp_path_info_to_ipv6_nexthop(struct bgp_path_info *info, ifindex_t *ifindex)
{
struct in6_addr *nexthop = NULL;
}
static int bgp_table_map_apply(struct route_map *map, struct prefix *p,
- struct bgp_info *info)
+ struct bgp_path_info *info)
{
route_map_result_t ret;
ifindex_t ifindex;
struct in6_addr *nexthop;
- nexthop = bgp_info_to_ipv6_nexthop(info, &ifindex);
+ nexthop = bgp_path_info_to_ipv6_nexthop(info, &ifindex);
zlog_debug(
"Zebra rmap deny: IPv6 route %s/%d nexthop %s",
inet_ntop(AF_INET6, &p->u.prefix6, buf[0],
ret = tm_table_manager_connect(zclient);
}
if (ret < 0) {
- zlog_warn("Error connecting to table manager!");
+ zlog_info("Error connecting to table manager!");
bgp_tm_status_connected = false;
} else {
if (!bgp_tm_status_connected)
return -1;
ret = tm_get_table_chunk(zclient, chunk_size, start, end);
if (ret < 0) {
- zlog_err("BGP: Error getting table chunk %u", chunk_size);
+ flog_err(EC_BGP_TABLE_CHUNK,
+ "BGP: Error getting table chunk %u", chunk_size);
return -1;
}
zlog_info("BGP: Table Manager returns range from chunk %u is [%u %u]",
return 1;
}
-static int update_ipv6nh_for_route_install(int nh_othervrf,
- struct in6_addr *nexthop,
- ifindex_t ifindex,
- struct bgp_info *ri,
- struct bgp_info *best_ri,
- bool is_evpn,
- struct zapi_nexthop *api_nh)
+static int
+update_ipv6nh_for_route_install(int nh_othervrf, struct in6_addr *nexthop,
+ ifindex_t ifindex, struct bgp_path_info *ri,
+ struct bgp_path_info *best_ri, bool is_evpn,
+ struct zapi_nexthop *api_nh)
{
struct attr *attr;
}
void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
- struct bgp_info *info, struct bgp *bgp, afi_t afi,
+ struct bgp_path_info *info, struct bgp *bgp, afi_t afi,
safi_t safi)
{
struct zapi_route api;
int has_valid_label = 0;
uint8_t distance;
struct peer *peer;
- struct bgp_info *mpinfo;
+ struct bgp_path_info *mpinfo;
uint32_t metric;
struct attr local_attr;
- struct bgp_info local_info;
- struct bgp_info *mpinfo_cp = &local_info;
+ struct bgp_path_info local_info;
+ struct bgp_path_info *mpinfo_cp = &local_info;
route_tag_t tag;
mpls_label_t label;
int nh_othervrf = 0;
/* Obtain peer from parent */
if (info->extra && info->extra->parent)
- peer = ((struct bgp_info *)(info->extra->parent))->peer;
+ peer = ((struct bgp_path_info *)(info->extra->parent))
+ ->peer;
}
tag = info->attr->tag;
/* Metric is currently based on the best-path only */
metric = info->attr->med;
- for (mpinfo = info; mpinfo; mpinfo = bgp_info_mpath_next(mpinfo)) {
+ for (mpinfo = info; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) {
if (valid_nh_count >= multipath_num)
break;
tag = mpinfo_cp->attr->tag;
}
}
- nexthop = bgp_info_to_ipv6_nexthop(mpinfo_cp,
- &ifindex);
+ nexthop = bgp_path_info_to_ipv6_nexthop(mpinfo_cp,
+ &ifindex);
nh_updated = update_ipv6nh_for_route_install(
nh_othervrf, nexthop, ifindex,
mpinfo, info, is_evpn, api_nh);
{
struct bgp_node *rn;
struct bgp_table *table;
- struct bgp_info *ri;
+ struct bgp_path_info *ri;
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
* know of this instance.
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
for (ri = rn->info; ri; ri = ri->next)
- if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED) &&
+ if (CHECK_FLAG(ri->flags, BGP_PATH_SELECTED) &&
(ri->type == ZEBRA_ROUTE_BGP
&& (ri->sub_type == BGP_ROUTE_NORMAL
safi);
}
-void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info,
+void bgp_zebra_withdraw(struct prefix *p, struct bgp_path_info *info,
struct bgp *bgp, safi_t safi)
{
struct zapi_route api;
listnode_delete(bgp->redist[afi][type], red);
XFREE(MTYPE_BGP_REDIST, red);
if (!bgp->redist[afi][type]->count)
- list_delete_and_null(&bgp->redist[afi][type]);
+ list_delete(&bgp->redist[afi][type]);
}
}
/* Other routes redistribution into BGP. */
int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type,
- unsigned short instance)
+ unsigned short instance, bool changed)
{
+ /* If redistribute options are changed call
+ * bgp_redistribute_unreg() to reset the option and withdraw
+ * the routes
+ */
+ if (changed)
+ bgp_redistribute_unreg(bgp, afi, type, instance);
/* Return if already redistribute flag is set. */
if (instance) {
afi_t afi, int type, uint32_t metric)
{
struct bgp_node *rn;
- struct bgp_info *ri;
+ struct bgp_path_info *ri;
if (red->redist_metric_flag && red->redist_metric == metric)
return 0;
ri->attr = bgp_attr_intern(&new_attr);
bgp_attr_unintern(&old_attr);
- bgp_info_set_flag(rn, ri,
- BGP_INFO_ATTR_CHANGED);
+ bgp_path_info_set_flag(rn, ri,
+ BGP_PATH_ATTR_CHANGED);
bgp_process(bgp, rn, afi, SAFI_UNICAST);
}
}
break;
case ZAPI_IPSET_ENTRY_INSTALLED:
{
- struct bgp_info *bgp_info;
- struct bgp_info_extra *extra;
-
- bgp_pbime->installed = true;
- bgp_pbime->install_in_progress = false;
- if (BGP_DEBUG(zebra, ZEBRA))
- zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
- __PRETTY_FUNCTION__);
- /* link bgp_info to bpme */
- bgp_info = (struct bgp_info *)bgp_pbime->bgp_info;
- extra = bgp_info_extra_get(bgp_info);
- if (extra->bgp_fs_pbr == NULL)
- extra->bgp_fs_pbr = list_new();
- listnode_add(extra->bgp_fs_pbr, bgp_pbime);
+ struct bgp_path_info *path;
+ struct bgp_path_info_extra *extra;
+
+ bgp_pbime->installed = true;
+ bgp_pbime->install_in_progress = false;
+ if (BGP_DEBUG(zebra, ZEBRA))
+ zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
+ __PRETTY_FUNCTION__);
+ /* link bgp_path_info to bpme */
+ path = (struct bgp_path_info *)bgp_pbime->path;
+ extra = bgp_path_info_extra_get(path);
+ if (extra->bgp_fs_pbr == NULL)
+ extra->bgp_fs_pbr = list_new();
+ listnode_add(extra->bgp_fs_pbr, bgp_pbime);
}
break;
case ZAPI_IPSET_ENTRY_FAIL_REMOVE:
stream_put(s, pbim->ipset_name,
ZEBRA_IPSET_NAME_SIZE);
-
-
}
static void bgp_encode_pbr_ipset_entry_match(struct stream *s,
int ipa_len;
char buf[ETHER_ADDR_STRLEN];
char buf1[INET6_ADDRSTRLEN];
- uint8_t flags;
+ uint8_t flags = 0;
+ uint32_t seqnum = 0;
memset(&ip, 0, sizeof(ip));
s = zclient->ibuf;
ipa_len = stream_getl(s);
if (ipa_len != 0 && ipa_len != IPV4_MAX_BYTELEN
&& ipa_len != IPV6_MAX_BYTELEN) {
- zlog_err("%u:Recv MACIP %s with invalid IP addr length %d",
+ flog_err(EC_BGP_MACIP_LEN,
+ "%u:Recv MACIP %s with invalid IP addr length %d",
vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del",
ipa_len);
return -1;
(ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4 : IPADDR_V6;
stream_get(&ip.ip.addr, s, ipa_len);
}
- flags = stream_getc(s);
+ if (command == ZEBRA_MACIP_ADD) {
+ flags = stream_getc(s);
+ seqnum = stream_getl(s);
+ }
bgp = bgp_lookup_by_vrf_id(vrf_id);
if (!bgp)
return 0;
if (BGP_DEBUG(zebra, ZEBRA))
- zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u",
+ zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u seq %u",
vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del",
flags, prefix_mac2str(&mac, buf, sizeof(buf)),
- ipaddr2str(&ip, buf1, sizeof(buf1)), vni);
+ ipaddr2str(&ip, buf1, sizeof(buf1)), vni, seqnum);
if (command == ZEBRA_MACIP_ADD)
- return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip, flags);
+ return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip,
+ flags, seqnum);
else
return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip);
}
STREAM_GETL(s, last);
if (zclient->redist_default != proto) {
- zlog_err("Got LM msg with wrong proto %u", proto);
+ flog_err(EC_BGP_LM_ERROR, "Got LM msg with wrong proto %u",
+ proto);
return;
}
if (zclient->instance != instance) {
- zlog_err("Got LM msg with wrong instance %u", proto);
+ flog_err(EC_BGP_LM_ERROR, "Got LM msg with wrong instance %u",
+ proto);
return;
}
first < MPLS_LABEL_UNRESERVED_MIN ||
last > MPLS_LABEL_UNRESERVED_MAX) {
- zlog_err("%s: Invalid Label chunk: %u - %u",
- __func__, first, last);
+ flog_err(EC_BGP_LM_ERROR, "%s: Invalid Label chunk: %u - %u",
+ __func__, first, last);
return;
}
if (BGP_DEBUG(zebra, ZEBRA)) {
extern struct zebra_privs_t bgpd_privs;
-void bgp_zebra_init(struct thread_master *master)
+void bgp_zebra_init(struct thread_master *master, unsigned short instance)
{
zclient_num_connects = 0;
zclient->ipset_notify_owner = ipset_notify_owner;
zclient->ipset_entry_notify_owner = ipset_entry_notify_owner;
zclient->iptable_notify_owner = iptable_notify_owner;
+ zclient->instance = instance;
}
void bgp_zebra_destroy(void)