Skip to content

Commit

Permalink
pathd:support srv6 te policy
Browse files Browse the repository at this point in the history
Signed-off-by: guozhongfeng.gzf <[email protected]>
  • Loading branch information
guoguojia2021 committed Dec 3, 2024
1 parent ee5a345 commit 7659ef7
Show file tree
Hide file tree
Showing 36 changed files with 894 additions and 228 deletions.
4 changes: 3 additions & 1 deletion bgpd/bgp_nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -1370,8 +1370,10 @@ char *bgp_nexthop_dump_bnc_flags(struct bgp_nexthop_cache *bnc, char *buf,
: "",
CHECK_FLAG(bnc->flags, BGP_NEXTHOP_LABELED_VALID)
? "Label Valid "
: "",
CHECK_FLAG(bnc->flags, BGP_NEXTHOP_SRV6TE_VALID)
? "SRv6 TE Valid "
: "");

return buf;
}

Expand Down
1 change: 1 addition & 0 deletions bgpd/bgp_nexthop.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ struct bgp_nexthop_cache {
#define BGP_STATIC_ROUTE_EXACT_MATCH (1 << 5)
#define BGP_NEXTHOP_LABELED_VALID (1 << 6)
#define BGP_NEXTHOP_ULTIMATE (1 << 7)
#define BGP_NEXTHOP_SRV6TE_VALID (1 << 8)

/*
* This flag is added for EVPN gateway IP nexthops.
Expand Down
33 changes: 21 additions & 12 deletions bgpd/bgp_nht.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,8 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
peer);
} else {
if (BGP_DEBUG(nht, NHT))
zlog_debug("Found existing bnc %pFX(%d)(%s) flags 0x%x ifindex %d #paths %d peer %p, resolved prefix %pFX",
&bnc->prefix, bnc->ifindex_ipv6_ll,
zlog_debug("Found existing bnc %pFX(%d)(%u)(%s) flags 0x%x ifindex %d #paths %d peer %p, resolved prefix %pFX",
&bnc->prefix, bnc->ifindex_ipv6_ll, bnc->srte_color,
bnc->bgp->name_pretty, bnc->flags,
bnc->ifindex_ipv6_ll, bnc->path_count,
bnc->nht_info, &bnc->resolved_prefix);
Expand Down Expand Up @@ -641,9 +641,11 @@ static void bgp_process_nexthop_update(struct bgp_nexthop_cache *bnc,

UNSET_FLAG(bnc->flags,
BGP_NEXTHOP_LABELED_VALID); /* check below */
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_SRV6TE_VALID);

for (i = 0; i < nhr->nexthop_num; i++) {
int num_labels = 0;
int num_segs = 0;

nexthop = nexthop_from_zapi_nexthop(&nhr->nexthops[i]);

Expand Down Expand Up @@ -675,12 +677,17 @@ static void bgp_process_nexthop_update(struct bgp_nexthop_cache *bnc,
num_labels = nexthop->nh_label->num_labels;
}

if (nexthop->nh_srv6 && nexthop->nh_srv6->seg6_segs) {
SET_FLAG(bnc->flags, BGP_NEXTHOP_SRV6TE_VALID);
num_segs = nexthop->nh_srv6->seg6_segs->num_segs;
}

if (BGP_DEBUG(nht, NHT)) {
char buf[NEXTHOP_STRLEN];
zlog_debug(
" nhop via %s (%d labels)",
" nhop via %s (%d labels) (%d segs))",
nexthop2str(nexthop, buf, sizeof(buf)),
num_labels);
num_labels, num_segs);
}

if (nhlist_tail) {
Expand Down Expand Up @@ -743,6 +750,7 @@ static void bgp_process_nexthop_update(struct bgp_nexthop_cache *bnc,
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_EVPN_INCOMPLETE);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_LABELED_VALID);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_SRV6TE_VALID);
bnc->nexthop_num = nhr->nexthop_num;

/* notify bgp fsm if nbr ip goes from valid->invalid */
Expand Down Expand Up @@ -1130,9 +1138,8 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
*/
static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
{
bool exact_match = false;
bool resolve_via_default = false;
int ret;
uint32_t flags = 0;

if (!zclient)
return;
Expand All @@ -1154,19 +1161,21 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
}
if (command == ZEBRA_NEXTHOP_REGISTER) {
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
exact_match = true;
SET_FLAG(flags, NEXTHOP_REGISTER_FLAG_CONNECTED);
if (CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
resolve_via_default = true;
SET_FLAG(flags, NEXTHOP_REGISTER_FLAG_RESOLVE_VIA_DEFAULT);
}

if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: sending cmd %s for %pFX (vrf %s)", __func__,
zlog_debug("%s: sending cmd %s for %pFX (vrf %s) color %d", __func__,
zserv_command_string(command), &bnc->prefix,
bnc->bgp->name_pretty);
bnc->bgp->name_pretty, bnc->srte_color);

if (bnc->srte_color)
SET_FLAG(flags, NEXTHOP_REGISTER_FLAG_COLOR);

ret = zclient_send_rnh(zclient, command, &bnc->prefix, SAFI_UNICAST,
exact_match, resolve_via_default,
bnc->bgp->vrf_id);
flags, bnc->bgp->vrf_id, bnc->srte_color);
if (ret == ZCLIENT_SEND_FAILURE) {
flog_warn(EC_BGP_ZEBRA_SEND,
"sendmsg_nexthop: zclient_send_message() failed");
Expand Down
15 changes: 8 additions & 7 deletions bgpd/bgp_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -1460,8 +1460,8 @@ static void bgp_debug_zebra_nh(struct zapi_route *api)
char eth_buf[ETHER_ADDR_STRLEN + 7] = { '\0' };
char buf1[ETHER_ADDR_STRLEN];
char label_buf[20];
char sid_buf[20];
char segs_buf[256];
char sid_buf[INET6_ADDRSTRLEN];
char segs_buf[512];
struct zapi_nexthop *api_nh;
int count;

Expand Down Expand Up @@ -1511,9 +1511,10 @@ static void bgp_debug_zebra_nh(struct zapi_route *api)
snprintf(eth_buf, sizeof(eth_buf), " RMAC %s",
prefix_mac2str(&api_nh->rmac, buf1,
sizeof(buf1)));
zlog_debug(" nhop [%d]: %s if %u VRF %u wt %" PRIu64

zlog_debug(" nhop [%d][%u]: %s if %u VRF %u wt %" PRIu64
" %s %s %s",
i + 1, nh_buf, api_nh->ifindex, api_nh->vrf_id,
i + 1, api_nh->srte_color, nh_buf, api_nh->ifindex, api_nh->vrf_id,
api_nh->weight, label_buf, segs_buf, eth_buf);
}
}
Expand Down Expand Up @@ -1573,7 +1574,7 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info,
api.tableid = info->attr->rmap_table_id;
}

if (info->attr->srte_color)
if (bgp_attr_get_color(info->attr))
SET_FLAG(api.message, ZAPI_MESSAGE_SRTE);

/* Metric is currently based on the best-path only */
Expand Down Expand Up @@ -1639,9 +1640,9 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info,
}

if (bgp_debug_zebra(p)) {
zlog_debug("Tx route add %s (table id %u) %pFX metric %u tag %" ROUTE_TAG_PRI
zlog_debug("Tx route add %s (table id %u) %pFX color %u metric %u tag %" ROUTE_TAG_PRI
" count %d nhg %d",
bgp->name_pretty, api.tableid, &api.prefix,
bgp->name_pretty, api.tableid, &api.prefix, api.srte_color,
api.metric, api.tag, api.nexthop_num, nhg_id);
bgp_debug_zebra_nh(&api);

Expand Down
4 changes: 3 additions & 1 deletion lib/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,9 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_TC_FILTER_ADD),
DESC_ENTRY(ZEBRA_TC_FILTER_DELETE),
DESC_ENTRY(ZEBRA_OPAQUE_NOTIFY),
DESC_ENTRY(ZEBRA_SRV6_SID_NOTIFY)
DESC_ENTRY(ZEBRA_SRV6_SID_NOTIFY),
DESC_ENTRY(ZEBRA_SRV6_POLICY_SET),
DESC_ENTRY(ZEBRA_SRV6_POLICY_DELETE)
};
#undef DESC_ENTRY

Expand Down
31 changes: 31 additions & 0 deletions lib/nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,37 @@ void nexthop_add_srv6_seg6(struct nexthop *nexthop, const struct in6_addr *segs,
sizeof(struct in6_addr));
}

void nexthop_add_srv6_seg6_ipaddr(struct nexthop *nexthop, const struct ipaddr *segs,
int num_segs)
{
int i;

if (!segs)
return;

if (!nexthop->nh_srv6)
nexthop->nh_srv6 = XCALLOC(MTYPE_NH_SRV6,
sizeof(struct nexthop_srv6));

/* Enforce limit on srv6 seg stack size */
if (num_segs > SRV6_MAX_SIDS)
num_segs = SRV6_MAX_SIDS;

if (!nexthop->nh_srv6->seg6_segs) {
nexthop->nh_srv6->seg6_segs =
XCALLOC(MTYPE_NH_SRV6,
sizeof(struct seg6_seg_stack) +
num_segs * sizeof(struct in6_addr));
}

nexthop->nh_srv6->seg6_segs->num_segs = num_segs;

for (i = 0; i < num_segs; i++)
memcpy(&nexthop->nh_srv6->seg6_segs->seg[i],
&segs[i].ipaddr_v6,
sizeof(struct in6_addr));
}

void nexthop_del_srv6_seg6(struct nexthop *nexthop)
{
if (!nexthop->nh_srv6)
Expand Down
12 changes: 8 additions & 4 deletions lib/nexthop.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,12 @@ struct nexthop {
* active one
*/
#define NEXTHOP_FLAG_RNH_FILTERED (1 << 5) /* rmap filtered, used by rnh */
#define NEXTHOP_FLAG_HAS_BACKUP (1 << 6) /* Backup nexthop index is set */
#define NEXTHOP_FLAG_SRTE (1 << 7) /* SR-TE color used for BGP traffic */
#define NEXTHOP_FLAG_EVPN (1 << 8) /* nexthop is EVPN */
#define NEXTHOP_FLAG_LINKDOWN (1 << 9) /* is not removed on link down */
#define NEXTHOP_FLAG_HAS_BACKUP (1 << 6) /* Backup nexthop index is set */
#define NEXTHOP_FLAG_SRTE (1 << 7) /* SR-TE color used for BGP traffic */
#define NEXTHOP_FLAG_EVPN (1 << 8) /* nexthop is EVPN */
#define NEXTHOP_FLAG_LINKDOWN (1 << 9) /* is not removed on link down */
#define NEXTHOP_FLAG_SRV6TE (1 << 10) /* SRv6-TE color used for BGP traffic */
#define NEXTHOP_FLAG_SRV6_TUNNEL (1 << 11) /* SRv6-TUNNEL used for BGP traffic */

#define NEXTHOP_IS_ACTIVE(flags) \
(CHECK_FLAG(flags, NEXTHOP_FLAG_ACTIVE) \
Expand Down Expand Up @@ -161,6 +163,8 @@ void nexthop_add_srv6_seg6local(struct nexthop *nexthop, uint32_t action,
void nexthop_del_srv6_seg6local(struct nexthop *nexthop);
void nexthop_add_srv6_seg6(struct nexthop *nexthop, const struct in6_addr *seg,
int num_segs);
void nexthop_add_srv6_seg6_ipaddr(struct nexthop *nexthop, const struct ipaddr *segs,
int num_segs);
void nexthop_del_srv6_seg6(struct nexthop *nexthop);

/*
Expand Down
19 changes: 19 additions & 0 deletions lib/prefix.c
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,25 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size)
return str;
}

int prefix2ipaddr(union prefixconstptr pu, struct ipaddr *ip)
{
const struct prefix *p = pu.p;
memset(ip, 0, sizeof(struct ipaddr));

if (p->family == AF_INET) {
ip->ipa_type = IPADDR_V4;
memcpy(&(ip->ipaddr_v4), &(p->u.prefix4),
sizeof(struct in_addr));
} else if (p->family == AF_INET6) {
ip->ipa_type = IPADDR_V6;
memcpy(&(ip->ipaddr_v6), &(p->u.prefix6),
sizeof(struct in6_addr));
} else
return -1;

return 0;
}

void prefix_mcast_ip_dump(const char *onfail, const struct ipaddr *addr,
char *buf, int buf_size)
{
Expand Down
1 change: 1 addition & 0 deletions lib/prefix.h
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ extern void prefix_mcast_inet4_dump(const char *onfail, struct in_addr addr,
extern const char *prefix_sg2str(const struct prefix_sg *sg, char *str);
extern const char *prefix2str(union prefixconstptr upfx, char *buffer,
int size);
extern int prefix2ipaddr(union prefixconstptr pu, struct ipaddr *ip);
extern int evpn_type5_prefix_match(const struct prefix *evpn_pfx,
const struct prefix *match_pfx);
extern int prefix_match(union prefixconstptr unet, union prefixconstptr upfx);
Expand Down
86 changes: 78 additions & 8 deletions lib/zclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,17 +772,15 @@ static void zclient_connect(struct event *t)
}

enum zclient_send_status zclient_send_rnh(struct zclient *zclient, int command,
const struct prefix *p, safi_t safi,
bool connected, bool resolve_via_def,
vrf_id_t vrf_id)
const struct prefix *p, safi_t safi, uint32_t flags,
vrf_id_t vrf_id, uint32_t srte_color)
{
struct stream *s;

s = zclient->obuf;
stream_reset(s);
zclient_create_header(s, command, vrf_id);
stream_putc(s, (connected) ? 1 : 0);
stream_putc(s, (resolve_via_def) ? 1 : 0);
stream_putl(s, flags);
stream_putw(s, safi);
stream_putw(s, PREFIX_FAMILY(p));
stream_putc(s, p->prefixlen);
Expand All @@ -796,6 +794,10 @@ enum zclient_send_status zclient_send_rnh(struct zclient *zclient, int command,
default:
break;
}

if (CHECK_FLAG(flags, NEXTHOP_REGISTER_FLAG_COLOR))
stream_putl(s, srte_color);

stream_putw_at(s, 0, stream_get_endp(s));

return zclient_send_message(zclient);
Expand Down Expand Up @@ -2377,7 +2379,7 @@ static bool zapi_nexthop_update_decode(struct stream *s, struct prefix *match,
STREAM_GETW(s, nhr->nexthop_num);

for (i = 0; i < nhr->nexthop_num; i++) {
if (zapi_nexthop_decode(s, &(nhr->nexthops[i]), 0, 0) != 0)
if (zapi_nexthop_decode(s, &(nhr->nexthops[i]), 0, nhr->message) != 0)
return false;
}

Expand Down Expand Up @@ -3847,8 +3849,17 @@ int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
enum zclient_send_status zebra_send_sr_policy(struct zclient *zclient, int cmd,
struct zapi_sr_policy *zp)
{
if (zapi_sr_policy_encode(zclient->obuf, cmd, zp) < 0)
return ZCLIENT_SEND_FAILURE;
if (cmd == ZEBRA_SR_POLICY_SET || cmd == ZEBRA_SR_POLICY_DELETE)
{
if (zapi_sr_policy_encode(zclient->obuf, cmd, zp) < 0)
return ZCLIENT_SEND_FAILURE;
}
else if (cmd == ZEBRA_SRV6_POLICY_SET || cmd == ZEBRA_SRV6_POLICY_DELETE)
{
if (zapi_srv6_policy_encode(zclient->obuf, cmd, zp) < 0)
return ZCLIENT_SEND_FAILURE;
}

return zclient_send_message(zclient);
}

Expand Down Expand Up @@ -3914,6 +3925,65 @@ int zapi_sr_policy_decode(struct stream *s, struct zapi_sr_policy *zp)
return -1;
}

int zapi_srv6_policy_encode(struct stream *s, int cmd, struct zapi_sr_policy *zp)
{
struct zapi_srv6te_tunnel *zt = &zp->segment_list_v6;

stream_reset(s);

zclient_create_header(s, cmd, VRF_DEFAULT);
stream_putl(s, zp->color);
stream_put_ipaddr(s, &zp->endpoint);
stream_write(s, &zp->name, SRTE_POLICY_NAME_MAX_LENGTH);

if (zt->seg_num > SRV6_MAX_SEGS) {
flog_err(EC_LIB_ZAPI_ENCODE,
"%s: seg: can't encode %u segs (maximum is %u)",
__func__, zt->seg_num, SRV6_MAX_SEGS);
return -1;
}

stream_putw(s, zt->seg_num);

for (int i = 0; i < zt->seg_num; i++)
stream_put_ipaddr(s, &zt->segs[i]);

/* Put length at the first point of the stream. */
stream_putw_at(s, 0, stream_get_endp(s));

return 0;
}

int zapi_srv6_policy_decode(struct stream *s, struct zapi_sr_policy *zp)
{
memset(zp, 0, sizeof(*zp));

struct zapi_srv6te_tunnel *zt = &zp->segment_list_v6;

STREAM_GETL(s, zp->color);
STREAM_GET_IPADDR(s, &zp->endpoint);
STREAM_GET(&zp->name, s, SRTE_POLICY_NAME_MAX_LENGTH);

/* segment list of active candidate path */
STREAM_GETW(s, zt->seg_num);

if (zt->seg_num > SRV6_MAX_SEGS) {
flog_err(EC_LIB_ZAPI_ENCODE,
"%s: seg: can't decode %u segs (maximum is %u)",
__func__, zt->seg_num, SRV6_MAX_SEGS);
return -1;
}

for (int i = 0; i < zt->seg_num; i++)
STREAM_GET_IPADDR(s, &zt->segs[i]);

return 0;

stream_failure:
return -1;
}


int zapi_sr_policy_notify_status_decode(struct stream *s,
struct zapi_sr_policy *zp)
{
Expand Down
Loading

0 comments on commit 7659ef7

Please sign in to comment.