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 Nov 25, 2024
1 parent 1dcb4bb commit 5f719a0
Show file tree
Hide file tree
Showing 30 changed files with 899 additions and 208 deletions.
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
20 changes: 14 additions & 6 deletions bgpd/bgp_nht.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,8 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
}

srte_color = bgp_attr_get_color(pi->attr);
if (srte_color)
p.u.prefix6 = pi->attr->mp_nexthop_global;

} else if (peer) {
/*
Expand Down Expand Up @@ -636,6 +638,10 @@ static void bgp_process_nexthop_update(struct bgp_nexthop_cache *bnc,

if (!bnc->is_evpn_gwip_nexthop)
SET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
if (nhr->type == ZEBRA_ROUTE_SRTE)
SET_FLAG(bnc->flags, BGP_NEXTHOP_SRV6TE_VALID);
else
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_SRV6TE_VALID);
bnc->metric = nhr->metric;
bnc->nexthop_num = nhr->nexthop_num;

Expand Down Expand Up @@ -743,6 +749,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 @@ -1123,9 +1130,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 @@ -1147,19 +1153,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__,
zserv_command_string(command), &bnc->prefix,
bnc->bgp->name_pretty);

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
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
18 changes: 18 additions & 0 deletions lib/prefix.c
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,24 @@ 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
82 changes: 75 additions & 7 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 @@ -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,63 @@ 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_write(s, (uint8_t *)&zt->segs[i], IPV6_MAX_BYTELEN);

/* 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(&zt->segs[i], s, IPV6_MAX_BYTELEN);

return 0;

stream_failure:
return -1;
}


int zapi_sr_policy_notify_status_decode(struct stream *s,
struct zapi_sr_policy *zp)
{
Expand Down
17 changes: 15 additions & 2 deletions lib/zclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ typedef uint16_t zebra_size_t;
#define ZEBRA_FEC_REGISTER_LABEL 0x1
#define ZEBRA_FEC_REGISTER_LABEL_INDEX 0x2

#define NEXTHOP_REGISTER_FLAG_CONNECTED (1 << 0)
#define NEXTHOP_REGISTER_FLAG_RESOLVE_VIA_DEFAULT (1 << 1)
#define NEXTHOP_REGISTER_FLAG_COLOR (1 << 2)


/* Client capabilities */
enum zserv_client_capabilities {
ZEBRA_CLIENT_GR_CAPABILITIES = 1,
Expand Down Expand Up @@ -238,6 +243,8 @@ typedef enum {
ZEBRA_TC_FILTER_DELETE,
ZEBRA_OPAQUE_NOTIFY,
ZEBRA_SRV6_SID_NOTIFY,
ZEBRA_SRV6_POLICY_SET,
ZEBRA_SRV6_POLICY_DELETE,
} zebra_message_types_t;
/* Zebra message types. Please update the corresponding
* command_types array with any changes!
Expand Down Expand Up @@ -636,11 +643,16 @@ struct zapi_srte_tunnel {
mpls_label_t labels[MPLS_MAX_LABELS];
};

struct zapi_srv6te_tunnel {
uint8_t seg_num;
struct in6_addr segs[SRV6_MAX_SEGS];
};
struct zapi_sr_policy {
uint32_t color;
struct ipaddr endpoint;
char name[SRTE_POLICY_NAME_MAX_LENGTH];
struct zapi_srte_tunnel segment_list;
struct zapi_srv6te_tunnel segment_list_v6;
int status;
};

Expand Down Expand Up @@ -1106,6 +1118,8 @@ extern int zapi_sr_policy_decode(struct stream *s, struct zapi_sr_policy *zp);
extern int zapi_sr_policy_notify_status_decode(struct stream *s,
struct zapi_sr_policy *zp);

extern int zapi_srv6_policy_encode(struct stream *s, int cmd, struct zapi_sr_policy *zp);
extern int zapi_srv6_policy_decode(struct stream *s, struct zapi_sr_policy *zp);
extern enum zclient_send_status zebra_send_mpls_labels(struct zclient *zclient,
int cmd,
struct zapi_labels *zl);
Expand All @@ -1130,8 +1144,7 @@ extern enum zclient_send_status zclient_route_send(uint8_t, struct zclient *,
struct zapi_route *);
extern enum zclient_send_status
zclient_send_rnh(struct zclient *zclient, int command, const struct prefix *p,
safi_t safi, bool connected, bool resolve_via_default,
vrf_id_t vrf_id);
safi_t safi, uint32_t flags, vrf_id_t vrf_id, uint32_t srte_color);
int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
uint32_t api_flags, uint32_t api_message);
extern int zapi_route_encode(uint8_t, struct stream *, struct zapi_route *);
Expand Down
6 changes: 3 additions & 3 deletions ospf6d/ospf6_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg)
{
struct prefix prefix = {};
int command;
uint32_t flags = 0;

if (zclient->sock < 0) {
if (IS_OSPF6_DEBUG_ZEBRA(SEND))
Expand All @@ -140,9 +141,8 @@ void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg)
zlog_debug("%s: sending cmd %s for %pFX (vrf %u)", __func__,
zserv_command_string(command), &prefix,
ospf6->vrf_id);

if (zclient_send_rnh(zclient, command, &prefix, SAFI_UNICAST, false,
true, ospf6->vrf_id)
SET_FLAG(flags, NEXTHOP_REGISTER_FLAG_RESOLVE_VIA_DEFAULT);
if (zclient_send_rnh(zclient, command, &prefix, SAFI_UNICAST, flags, ospf6->vrf_id, 0)
== ZCLIENT_SEND_FAILURE)
flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_send_rnh() failed",
__func__);
Expand Down
6 changes: 4 additions & 2 deletions ospfd/ospf_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,7 @@ void ospf_zebra_import_default_route(struct ospf *ospf, bool unreg)
{
struct prefix prefix = {};
int command;
uint32_t flags = 0;

if (zclient->sock < 0) {
if (IS_DEBUG_OSPF(zebra, ZEBRA))
Expand All @@ -1494,8 +1495,9 @@ void ospf_zebra_import_default_route(struct ospf *ospf, bool unreg)
zserv_command_string(command), &prefix,
ospf_vrf_id_to_name(ospf->vrf_id));

if (zclient_send_rnh(zclient, command, &prefix, SAFI_UNICAST, false,
true, ospf->vrf_id) == ZCLIENT_SEND_FAILURE)
SET_FLAG(flags, NEXTHOP_REGISTER_FLAG_RESOLVE_VIA_DEFAULT);
if (zclient_send_rnh(zclient, command, &prefix, SAFI_UNICAST, flags,
ospf->vrf_id, 0) == ZCLIENT_SEND_FAILURE)
flog_err(EC_LIB_ZAPI_SOCKET, "%s(%s): zclient_send_rnh() failed",
__func__, ospf_vrf_id_to_name(ospf->vrf_id));
}
Expand Down
Loading

0 comments on commit 5f719a0

Please sign in to comment.