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
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