Skip to content

Commit

Permalink
bgpd: cli for srv6-locator assignment (step4)
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
slankdev authored and Mark Stapp committed Jun 2, 2021
1 parent 92a9e6f commit a0281b2
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 0 deletions.
32 changes: 32 additions & 0 deletions bgpd/bgp_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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"
Expand Down
60 changes: 60 additions & 0 deletions bgpd/bgp_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
1 change: 1 addition & 0 deletions bgpd/bgp_zebra.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit a0281b2

Please sign in to comment.