summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_vty.c32
-rw-r--r--bgpd/bgp_zebra.c60
-rw-r--r--bgpd/bgp_zebra.h1
3 files changed, 93 insertions, 0 deletions
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 8067c33884..a236d4e30c 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -9870,6 +9870,29 @@ DEFUN_NOSH (bgp_segment_routing_srv6,
return CMD_SUCCESS;
}
+DEFPY (bgp_srv6_locator,
+ bgp_srv6_locator_cmd,
+ "locator NAME$name",
+ "Specify SRv6 locator\n"
+ "Specify SRv6 locator\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+ if (strlen(bgp->srv6_locator_name) > 0
+ && strcmp(name, bgp->srv6_locator_name) != 0) {
+ vty_out(vty, "srv6 locator is already configured\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ } else
+ snprintf(bgp->srv6_locator_name,
+ sizeof(bgp->srv6_locator_name), "%s", name);
+
+ int ret = bgp_zebra_srv6_manager_get_locator_chunk(name);
+ if (ret < 0)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ return CMD_SUCCESS;
+}
+
DEFUN_NOSH (exit_address_family,
exit_address_family_cmd,
"exit-address-family",
@@ -17887,6 +17910,14 @@ int bgp_config_write(struct vty *vty)
if (CHECK_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN))
vty_out(vty, " bgp shutdown\n");
+ if (bgp->srv6_enabled) {
+ vty_frame(vty, " !\n segment-routing srv6\n");
+ if (bgp->srv6_locator_name)
+ vty_out(vty, " locator %s\n",
+ bgp->srv6_locator_name);
+ }
+
+
/* IPv4 unicast configuration. */
bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST);
@@ -19461,6 +19492,7 @@ void bgp_vty_init(void)
/* srv6 commands */
install_element(BGP_NODE, &bgp_segment_routing_srv6_cmd);
+ install_element(BGP_SRV6_NODE, &bgp_srv6_locator_cmd);
}
#include "memory.h"
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 97f781b2bf..c66348691b 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -2976,6 +2976,60 @@ static int bgp_ifp_create(struct interface *ifp)
return 0;
}
+static void bgp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
+{
+ struct stream *s = NULL;
+ uint8_t proto;
+ uint16_t instance;
+ uint16_t len;
+ char name[256] = {0};
+ struct prefix_ipv6 *chunk = NULL;
+ chunk = prefix_ipv6_new();
+
+ s = zclient->ibuf;
+ STREAM_GETC(s, proto);
+ STREAM_GETW(s, instance);
+
+ STREAM_GETW(s, len);
+ STREAM_GET(name, s, len);
+
+ STREAM_GETW(s, chunk->prefixlen);
+ STREAM_GET(&chunk->prefix, s, 16);
+
+ if (zclient->redist_default != proto) {
+ zlog_err("Got SRv6 Manager msg with wrong proto %u", proto);
+ return;
+ }
+ if (zclient->instance != instance) {
+ zlog_err("Got SRv6 Manager msg with wrong instance %u", proto);
+ return;
+ }
+
+ struct bgp *bgp = bgp_get_default();
+ if (strcmp(bgp->srv6_locator_name, name) != 0) {
+ zlog_info("name unmatch %s:%s",
+ bgp->srv6_locator_name, name);
+ return;
+ }
+
+ struct listnode *node;
+ struct prefix_ipv6 *c;
+ for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, c)) {
+ if (!prefix_cmp(c, chunk))
+ return;
+ }
+
+ listnode_add(bgp->srv6_locator_chunks, chunk);
+ vpn_leak_postchange_all();
+ return;
+
+stream_failure:
+ free(chunk);
+
+ zlog_err("%s: can't get locator_chunk!!", __func__);
+ return;
+}
+
void bgp_zebra_init(struct thread_master *master, unsigned short instance)
{
zclient_num_connects = 0;
@@ -3018,6 +3072,7 @@ void bgp_zebra_init(struct thread_master *master, unsigned short instance)
zclient->iptable_notify_owner = iptable_notify_owner;
zclient->route_notify_owner = bgp_zebra_route_notify_owner;
zclient->instance = instance;
+ zclient->process_srv6_locator_chunk = bgp_zebra_process_srv6_locator_chunk;
}
void bgp_zebra_destroy(void)
@@ -3415,3 +3470,8 @@ int bgp_zebra_stale_timer_update(struct bgp *bgp)
zlog_debug("send capabilty success");
return BGP_GR_SUCCESS;
}
+
+int bgp_zebra_srv6_manager_get_locator_chunk(const char *name)
+{
+ return srv6_manager_get_locator_chunk(zclient, name);
+}
diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h
index 4b357c380a..02b6484943 100644
--- a/bgpd/bgp_zebra.h
+++ b/bgpd/bgp_zebra.h
@@ -113,4 +113,5 @@ extern void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh,
extern int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable);
extern int bgp_zebra_update(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type);
extern int bgp_zebra_stale_timer_update(struct bgp *bgp);
+extern int bgp_zebra_srv6_manager_get_locator_chunk(const char *name);
#endif /* _QUAGGA_BGP_ZEBRA_H */