summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_zebra.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_zebra.c')
-rw-r--r--bgpd/bgp_zebra.c157
1 files changed, 143 insertions, 14 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 72bd081a7..d76eb951d 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA. */
#include "lib/json.h"
#include "lib/bfd.h"
#include "filter.h"
+#include "mpls.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_route.h"
@@ -46,6 +47,7 @@ Boston, MA 02111-1307, USA. */
#include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_nht.h"
#include "bgpd/bgp_bfd.h"
+#include "bgpd/bgp_label.h"
#if ENABLE_BGP_VNC
# include "bgpd/rfapi/rfapi_backend.h"
# include "bgpd/rfapi/vnc_export_bgp.h"
@@ -57,6 +59,7 @@ struct zclient *zclient = NULL;
/* Growable buffer for nexthops sent to zebra */
struct stream *bgp_nexthop_buf = NULL;
struct stream *bgp_ifindices_buf = NULL;
+struct stream *bgp_label_buf = NULL;
/* These array buffers are used in making a copy of the attributes for
route-map apply. Arrays are being used here to minimize mallocs and
@@ -178,6 +181,14 @@ bgp_update_interface_nbrs (struct bgp *bgp, struct interface *ifp,
}
}
+static int
+bgp_read_fec_update (int command, struct zclient *zclient,
+ zebra_size_t length)
+{
+ bgp_parse_fec_update();
+ return 0;
+}
+
static void
bgp_start_interface_nbrs (struct bgp *bgp, struct interface *ifp)
{
@@ -1204,8 +1215,8 @@ bgp_table_map_apply (struct route_map *map, struct prefix *p,
}
void
-bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
- afi_t afi, safi_t safi)
+bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info,
+ struct bgp *bgp, afi_t afi, safi_t safi)
{
u_int32_t flags;
u_char distance;
@@ -1216,6 +1227,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
struct bgp_info local_info;
struct bgp_info *info_cp = &local_info;
route_tag_t tag;
+ u_int32_t label;
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
* know of this instance.
@@ -1271,7 +1283,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
(sizeof (struct in_addr *) * nhcount))
{
- newsize = (sizeof (struct in_addr *) * nhcount);
+ newsize = sizeof (struct in_addr *) * nhcount;
newsize = stream_resize (bgp_nexthop_buf, newsize);
if (newsize == oldsize)
{
@@ -1282,6 +1294,25 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
stream_reset (bgp_nexthop_buf);
nexthop = NULL;
+ /* For labeled unicast, each nexthop has a label too. Resize label
+ * buffer, if required.
+ */
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ if ((oldsize = stream_get_size (bgp_label_buf)) <
+ (sizeof (unsigned int) * nhcount))
+ {
+ newsize = (sizeof (unsigned int) * nhcount);
+ newsize = stream_resize (bgp_label_buf, newsize);
+ if (newsize == oldsize)
+ {
+ zlog_err ("can't resize label buffer");
+ return;
+ }
+ }
+ stream_reset (bgp_label_buf);
+ }
+
/* Metric is currently based on the best-path only. */
metric = info->attr->med;
@@ -1311,6 +1342,11 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
{
stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
valid_nh_count++;
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ label = label_pton(info->extra->tag);
+ stream_put (bgp_label_buf, &label, sizeof (u_int32_t));
+ }
}
for (mpinfo = bgp_info_mpath_first (info); mpinfo;
@@ -1336,6 +1372,11 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
continue;
stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ label = label_pton(mpinfo->extra->tag);
+ stream_put (bgp_label_buf, &label, sizeof (u_int32_t));
+ }
valid_nh_count++;
}
@@ -1344,8 +1385,10 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
api.type = ZEBRA_ROUTE_BGP;
api.instance = 0;
api.message = 0;
- api.safi = safi;
+ api.safi = (safi == SAFI_LABELED_UNICAST) ? SAFI_UNICAST : safi;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
+ if (safi == SAFI_LABELED_UNICAST)
+ SET_FLAG (api.message, ZAPI_MESSAGE_LABEL);
/* Note that this currently only applies to Null0 routes for aggregates.
* ZEBRA_FLAG_BLACKHOLE signals zapi_ipv4_route to encode a special
@@ -1358,6 +1401,16 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
api.nexthop_num = valid_nh_count;
api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ api.label_num = valid_nh_count;
+ api.label = (unsigned int *)STREAM_DATA (bgp_label_buf);
+ }
+ else
+ {
+ api.label_num = 0;
+ api.label = NULL;
+ }
api.ifindex_num = 0;
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
api.metric = metric;
@@ -1379,14 +1432,22 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (bgp_debug_zebra(p))
{
int i;
+ char label_buf[20];
zlog_debug("Tx IPv4 route %s VRF %u %s/%d metric %u tag %"ROUTE_TAG_PRI
" count %d", (valid_nh_count ? "add":"delete"),
bgp->vrf_id,
inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag, api.nexthop_num);
for (i = 0; i < api.nexthop_num; i++)
- zlog_debug(" IPv4 [nexthop %d] %s", i+1,
- inet_ntop(AF_INET, api.nexthop[i], buf[1], sizeof(buf[1])));
+ {
+ label_buf[0] = '\0';
+ if (safi == SAFI_LABELED_UNICAST)
+ sprintf(label_buf, "label %u", api.label[i]);
+ zlog_debug(" nhop [%d]: %s %s",
+ i+1,
+ inet_ntop(AF_INET, api.nexthop[i], buf[1], sizeof(buf[1])),
+ label_buf);
+ }
}
zapi_ipv4_route (valid_nh_count ? ZEBRA_IPV4_ROUTE_ADD: ZEBRA_IPV4_ROUTE_DELETE,
@@ -1431,6 +1492,25 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
}
stream_reset (bgp_ifindices_buf);
+ /* For labeled unicast, each nexthop has a label too. Resize label
+ * buffer, if required.
+ */
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ if ((oldsize = stream_get_size (bgp_label_buf)) <
+ (sizeof (unsigned int) * nhcount))
+ {
+ newsize = (sizeof (unsigned int) * nhcount);
+ newsize = stream_resize (bgp_label_buf, newsize);
+ if (newsize == oldsize)
+ {
+ zlog_err ("can't resize label buffer");
+ return;
+ }
+ }
+ stream_reset (bgp_label_buf);
+ }
+
ifindex = 0;
nexthop = NULL;
@@ -1476,6 +1556,11 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
}
stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ label = label_pton(info->extra->tag);
+ stream_put (bgp_label_buf, &label, sizeof (u_int32_t));
+ }
valid_nh_count++;
}
@@ -1518,6 +1603,11 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ label = label_pton(mpinfo->extra->tag);
+ stream_put (bgp_label_buf, &label, sizeof (u_int32_t));
+ }
valid_nh_count++;
}
@@ -1527,8 +1617,10 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
api.type = ZEBRA_ROUTE_BGP;
api.instance = 0;
api.message = 0;
- api.safi = safi;
+ api.safi = (safi == SAFI_LABELED_UNICAST) ? SAFI_UNICAST : safi;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
+ if (safi == SAFI_LABELED_UNICAST)
+ SET_FLAG (api.message, ZAPI_MESSAGE_LABEL);
/* Note that this currently only applies to Null0 routes for aggregates.
* ZEBRA_FLAG_BLACKHOLE signals zapi_ipv6_route to encode a special
@@ -1544,6 +1636,16 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
api.ifindex_num = valid_nh_count;
api.ifindex = (ifindex_t *)STREAM_DATA (bgp_ifindices_buf);
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ api.label_num = valid_nh_count;
+ api.label = (unsigned int *)STREAM_DATA (bgp_label_buf);
+ }
+ else
+ {
+ api.label_num = 0;
+ api.label = NULL;
+ }
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
api.metric = metric;
api.tag = 0;
@@ -1566,13 +1668,22 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (bgp_debug_zebra(p))
{
int i;
+ char label_buf[20];
zlog_debug("Tx IPv4 route %s VRF %u %s/%d metric %u tag %"ROUTE_TAG_PRI,
valid_nh_count ? "add" : "delete", bgp->vrf_id,
inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag);
for (i = 0; i < api.nexthop_num; i++)
- zlog_debug(" IPv6 [nexthop %d] %s", i+1,
- inet_ntop(AF_INET6, api.nexthop[i], buf[1], sizeof(buf[1])));
+ {
+ label_buf[0] = '\0';
+ if (safi == SAFI_LABELED_UNICAST)
+ sprintf(label_buf, "label %u", api.label[i]);
+ zlog_debug(" nhop [%d]: %s if %s %s",
+ i+1,
+ inet_ntop(AF_INET6, api.nexthop[i], buf[1], sizeof(buf[1])),
+ ifindex2ifname (api.ifindex[i], bgp->vrf_id),
+ label_buf);
+ }
}
if (valid_nh_count)
@@ -1588,13 +1699,22 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (bgp_debug_zebra(p))
{
int i;
+ char label_buf[20];
zlog_debug("Tx IPv6 route %s VRF %u %s/%d metric %u tag %"ROUTE_TAG_PRI,
valid_nh_count ? "add" : "delete", bgp->vrf_id,
inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag);
for (i = 0; i < api.nexthop_num; i++)
- zlog_debug(" IPv6 [nexthop %d] %s", i+1,
- inet_ntop(AF_INET6, api.nexthop[i], buf[1], sizeof(buf[1])));
+ {
+ label_buf[0] = '\0';
+ if (safi == SAFI_LABELED_UNICAST)
+ sprintf(label_buf, "label %u", api.label[i]);
+ zlog_debug(" nhop [%d]: %s if %s %s",
+ i+1,
+ inet_ntop(AF_INET6, api.nexthop[i], buf[1], sizeof(buf[1])),
+ ifindex2ifname (api.ifindex[i], bgp->vrf_id),
+ label_buf);
+ }
}
zapi_ipv6_route (valid_nh_count ?
@@ -1626,7 +1746,7 @@ bgp_zebra_announce_table (struct bgp *bgp, afi_t afi, safi_t safi)
if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
&& ri->type == ZEBRA_ROUTE_BGP
&& ri->sub_type == BGP_ROUTE_NORMAL)
- bgp_zebra_announce (&rn->p, ri, bgp, afi, safi);
+ bgp_zebra_announce (rn, &rn->p, ri, bgp, afi, safi);
}
void
@@ -1673,10 +1793,14 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
api.type = ZEBRA_ROUTE_BGP;
api.instance = 0;
api.message = 0;
- api.safi = safi;
+ api.safi = (safi == SAFI_LABELED_UNICAST) ? SAFI_UNICAST : safi;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
+ if (safi == SAFI_LABELED_UNICAST)
+ SET_FLAG (api.message, ZAPI_MESSAGE_LABEL);
api.nexthop_num = 0;
api.nexthop = NULL;
+ api.label_num = 0;
+ api.label = NULL;
api.ifindex_num = 0;
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
api.metric = info->attr->med;
@@ -1712,11 +1836,14 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
api.type = ZEBRA_ROUTE_BGP;
api.instance = 0;
api.message = 0;
- api.safi = safi;
+ api.safi = (safi == SAFI_LABELED_UNICAST) ? SAFI_UNICAST : safi;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
+ if (safi == SAFI_LABELED_UNICAST)
+ SET_FLAG (api.message, ZAPI_MESSAGE_LABEL);
api.nexthop_num = 0;
api.nexthop = NULL;
api.ifindex_num = 0;
+ api.label_num = 0;
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
api.metric = info->attr->med;
api.tag = 0;
@@ -2141,9 +2268,11 @@ bgp_zebra_init (struct thread_master *master)
zclient->redistribute_route_ipv6_del = zebra_read_ipv6;
zclient->nexthop_update = bgp_read_nexthop_update;
zclient->import_check_update = bgp_read_import_check_update;
+ zclient->fec_update = bgp_read_fec_update;
bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
bgp_ifindices_buf = stream_new(BGP_IFINDICES_BUF_SIZE);
+ bgp_label_buf = stream_new(BGP_LABEL_BUF_SIZE);
}
void