Mailing List Archive

[PATCH 1/6] bgpd: static VRF routes
From: David Lamparter <equinox@opensourcerouting.org>

This enhancement provides some APIs to be used to set and unset MPLS
VPN static routes. The intention of this API is to be used by either vty
or zmq/capnp interface.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
---
bgpd/bgp_route.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bgpd/bgpd.h | 11 ++++++++
2 files changed, 92 insertions(+)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 99637b6..7024590 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1526,6 +1526,15 @@ bgp_process_announce_selected (struct peer *peer, struct bgp_info *selected,
return 0;
}

+/* API foo */
+static struct bgp_static * bgp_static_new (void);
+static void bgp_static_free (struct bgp_static *bgp_static);
+static void bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
+ struct bgp_static *bgp_static, afi_t afi, safi_t safi);
+static void bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p,
+ afi_t afi, safi_t safi, struct prefix_rd *prd,
+ uint32_t *labels, size_t nlabels);
+
void bgp_vrf_clean_tables (struct bgp_vrf *vrf)
{
afi_t afi;
@@ -1556,6 +1565,73 @@ void bgp_vrf_clean_tables (struct bgp_vrf *vrf)
}
}

+int
+bgp_vrf_static_set (struct bgp_vrf *vrf, afi_t afi, const struct bgp_api_route *route)
+{
+ struct bgp_static *bgp_static;
+ struct prefix *p = (struct prefix *)&route->prefix;
+ struct bgp_node *rn;
+
+ if (afi != AFI_IP)
+ return -1;
+
+ bgp_static = bgp_static_new ();
+ bgp_static->backdoor = 0;
+ bgp_static->valid = 1;
+ bgp_static->igpmetric = 0;
+ bgp_static->igpnexthop = route->nexthop;
+ bgp_static->labels[0] = (route->label << 4) | 1;
+ bgp_static->nlabels = route->label ? 1 : 0;
+ bgp_static->prd = vrf->outbound_rd;
+ bgp_static->ecomm = vrf->rt_export;
+ if (bgp_static->ecomm)
+ {
+ assert(bgp_static->ecomm->refcnt > 0);
+ bgp_static->ecomm->refcnt++;
+ }
+
+ rn = bgp_node_get (vrf->route[afi], p);
+ if (rn->info)
+ {
+ struct bgp_static *old = rn->info;
+ if (old->ecomm)
+ ecommunity_unintern (&old->ecomm);
+ bgp_static_free (rn->info);
+ /* reference only dropped if we're replacing a route */
+ bgp_unlock_node (rn);
+ }
+ rn->info = bgp_static;
+
+ bgp_static_update_safi (vrf->bgp, p, bgp_static, afi, SAFI_MPLS_VPN);
+ return 0;
+}
+
+int
+bgp_vrf_static_unset (struct bgp_vrf *vrf, afi_t afi, const struct bgp_api_route *route)
+{
+ struct prefix *p = (struct prefix *)&route->prefix;
+ struct bgp_static *old;
+ struct bgp_node *rn;
+
+ if (afi != AFI_IP)
+ return -1;
+
+ rn = bgp_node_lookup (vrf->route[afi], p);
+ if (!rn || !rn->info)
+ return -1;
+
+ bgp_static_withdraw_safi (vrf->bgp, p, afi, SAFI_MPLS_VPN,
+ &vrf->outbound_rd, NULL, 0);
+
+ old = rn->info;
+ if (old->ecomm)
+ ecommunity_unintern (&old->ecomm);
+ bgp_static_free (old);
+ rn->info = NULL;
+ bgp_unlock_node (rn);
+ return 0;
+}
+
void
bgp_vrf_apply_new_imports (struct bgp_vrf *vrf, afi_t afi)
{
@@ -4013,6 +4089,10 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
bgp_attr_extra_get (&attr)->ecommunity = ecommunity_dup (bgp_static->ecomm);
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
}
+
+ if (bgp_static->igpnexthop.s_addr)
+ bgp_attr_extra_get (&attr)->mp_nexthop_global_in = bgp_static->igpnexthop;
+
/* Apply route-map. */
if (bgp_static->rmap.name)
{
@@ -4057,6 +4137,7 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
if (ri)
{
if (attrhash_cmp (ri->attr, attr_new) &&
+ labels_equal (ri, bgp_static->labels, bgp_static->nlabels) &&
!CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
{
bgp_unlock_node (rn);
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 7ff58ef..b3ad648 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -33,6 +33,8 @@ typedef u_int32_t as_t;
typedef u_int16_t as16_t; /* we may still encounter 16 Bit asnums */
typedef u_int16_t bgp_size_t;

+struct bgp_node;
+
/* BGP router distinguisher value. */
#define BGP_RD_SIZE 8

@@ -225,6 +227,13 @@ struct bgp_vrf

};

+struct bgp_api_route
+{
+ struct prefix_ipv4 prefix;
+ struct in_addr nexthop;
+ uint32_t label;
+};
+
/* BGP peer-group support. */
struct peer_group
{
@@ -1041,5 +1050,7 @@ extern void bgp_vrf_delete (struct bgp_vrf *vrf);
extern void bgp_vrf_rt_export_set (struct bgp_vrf *vrf, struct ecommunity *rt_export);
extern void bgp_vrf_rt_import_set (struct bgp_vrf *vrf, struct ecommunity *rt_import);
extern void bgp_vrf_clean_tables (struct bgp_vrf *vrf);
+extern int bgp_vrf_static_set (struct bgp_vrf *vrf, afi_t afi, const struct bgp_api_route *route);
+extern int bgp_vrf_static_unset (struct bgp_vrf *vrf, afi_t afi, const struct bgp_api_route *route);

#endif /* _QUAGGA_BGPD_H */
--
2.1.4


_______________________________________________
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev