mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 08:50:26 +00:00
bgpd: cli for srv6-locator assignment (step4)
This commit add command to speficy SRv6 locator for BGP SRv6-VPN. CLI example is follow. CLI block of "segment-routing" is already implemented by previous commits and it's managed by zebra. Zebra manage just the ownership of locator's prefix. Zlient can request to get srv6-locator's prefix chunk using srv6_manager_get_locator_chunk() which is usuful func to execute ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK api. This request is wokring as async, And zebra calls same api to Zclients when zebra allocate locator prefix chunk. And then, finally zclient(bgpd) catch the information via process_srv6_lcoator_chunk callback function. router bgp 1 segment-routing srv6 locator loc1 ! ! segment-routing srv6 locators locator loc1 prefix 2001:db8:1:1::/64 ! ! ! ! [POINT_OF_REVIEW] In current implementation, user can just configure srv6 locator but user can't de-configure srv6 locator. Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
This commit is contained in:
parent
92a9e6f296
commit
a0281b2eab
@ -9870,6 +9870,29 @@ DEFUN_NOSH (bgp_segment_routing_srv6,
|
|||||||
return CMD_SUCCESS;
|
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,
|
DEFUN_NOSH (exit_address_family,
|
||||||
exit_address_family_cmd,
|
exit_address_family_cmd,
|
||||||
"exit-address-family",
|
"exit-address-family",
|
||||||
@ -17887,6 +17910,14 @@ int bgp_config_write(struct vty *vty)
|
|||||||
if (CHECK_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN))
|
if (CHECK_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN))
|
||||||
vty_out(vty, " bgp shutdown\n");
|
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. */
|
/* IPv4 unicast configuration. */
|
||||||
bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST);
|
bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST);
|
||||||
|
|
||||||
@ -19461,6 +19492,7 @@ void bgp_vty_init(void)
|
|||||||
|
|
||||||
/* srv6 commands */
|
/* srv6 commands */
|
||||||
install_element(BGP_NODE, &bgp_segment_routing_srv6_cmd);
|
install_element(BGP_NODE, &bgp_segment_routing_srv6_cmd);
|
||||||
|
install_element(BGP_SRV6_NODE, &bgp_srv6_locator_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
@ -2976,6 +2976,60 @@ static int bgp_ifp_create(struct interface *ifp)
|
|||||||
return 0;
|
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)
|
void bgp_zebra_init(struct thread_master *master, unsigned short instance)
|
||||||
{
|
{
|
||||||
zclient_num_connects = 0;
|
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->iptable_notify_owner = iptable_notify_owner;
|
||||||
zclient->route_notify_owner = bgp_zebra_route_notify_owner;
|
zclient->route_notify_owner = bgp_zebra_route_notify_owner;
|
||||||
zclient->instance = instance;
|
zclient->instance = instance;
|
||||||
|
zclient->process_srv6_locator_chunk = bgp_zebra_process_srv6_locator_chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_zebra_destroy(void)
|
void bgp_zebra_destroy(void)
|
||||||
@ -3415,3 +3470,8 @@ int bgp_zebra_stale_timer_update(struct bgp *bgp)
|
|||||||
zlog_debug("send capabilty success");
|
zlog_debug("send capabilty success");
|
||||||
return BGP_GR_SUCCESS;
|
return BGP_GR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bgp_zebra_srv6_manager_get_locator_chunk(const char *name)
|
||||||
|
{
|
||||||
|
return srv6_manager_get_locator_chunk(zclient, name);
|
||||||
|
}
|
||||||
|
@ -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_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_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_stale_timer_update(struct bgp *bgp);
|
||||||
|
extern int bgp_zebra_srv6_manager_get_locator_chunk(const char *name);
|
||||||
#endif /* _QUAGGA_BGP_ZEBRA_H */
|
#endif /* _QUAGGA_BGP_ZEBRA_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user