mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-25 11:28:06 +00:00
Merge pull request #3893 from mjstapp/dplane_pw_nexthops
zebra: include nexthop info when installing pseudowires
This commit is contained in:
commit
6ac9718a2a
@ -927,7 +927,7 @@ static void _netlink_route_nl_add_gateway_info(uint8_t route_family,
|
|||||||
uint8_t gw_family,
|
uint8_t gw_family,
|
||||||
struct nlmsghdr *nlmsg,
|
struct nlmsghdr *nlmsg,
|
||||||
size_t req_size, int bytelen,
|
size_t req_size, int bytelen,
|
||||||
struct nexthop *nexthop)
|
const struct nexthop *nexthop)
|
||||||
{
|
{
|
||||||
if (route_family == AF_MPLS) {
|
if (route_family == AF_MPLS) {
|
||||||
struct gw_family_t gw_fam;
|
struct gw_family_t gw_fam;
|
||||||
@ -954,7 +954,7 @@ static void _netlink_route_rta_add_gateway_info(uint8_t route_family,
|
|||||||
struct rtattr *rta,
|
struct rtattr *rta,
|
||||||
struct rtnexthop *rtnh,
|
struct rtnexthop *rtnh,
|
||||||
size_t req_size, int bytelen,
|
size_t req_size, int bytelen,
|
||||||
struct nexthop *nexthop)
|
const struct nexthop *nexthop)
|
||||||
{
|
{
|
||||||
if (route_family == AF_MPLS) {
|
if (route_family == AF_MPLS) {
|
||||||
struct gw_family_t gw_fam;
|
struct gw_family_t gw_fam;
|
||||||
@ -990,7 +990,7 @@ static void _netlink_route_rta_add_gateway_info(uint8_t route_family,
|
|||||||
* @param req_size: The size allocated for the message.
|
* @param req_size: The size allocated for the message.
|
||||||
*/
|
*/
|
||||||
static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
|
static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
|
||||||
struct nexthop *nexthop,
|
const struct nexthop *nexthop,
|
||||||
struct nlmsghdr *nlmsg,
|
struct nlmsghdr *nlmsg,
|
||||||
struct rtmsg *rtmsg,
|
struct rtmsg *rtmsg,
|
||||||
size_t req_size, int cmd)
|
size_t req_size, int cmd)
|
||||||
@ -1009,7 +1009,7 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
|
|||||||
label_buf[0] = '\0';
|
label_buf[0] = '\0';
|
||||||
|
|
||||||
assert(nexthop);
|
assert(nexthop);
|
||||||
for (struct nexthop *nh = nexthop; nh; nh = nh->rparent) {
|
for (const struct nexthop *nh = nexthop; nh; nh = nh->rparent) {
|
||||||
char label_buf1[20];
|
char label_buf1[20];
|
||||||
|
|
||||||
nh_label = nh->nh_label;
|
nh_label = nh->nh_label;
|
||||||
@ -1175,11 +1175,11 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
|
|||||||
* the prefsrc should be stored.
|
* the prefsrc should be stored.
|
||||||
*/
|
*/
|
||||||
static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
|
static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
|
||||||
struct nexthop *nexthop,
|
const struct nexthop *nexthop,
|
||||||
struct rtattr *rta,
|
struct rtattr *rta,
|
||||||
struct rtnexthop *rtnh,
|
struct rtnexthop *rtnh,
|
||||||
struct rtmsg *rtmsg,
|
struct rtmsg *rtmsg,
|
||||||
union g_addr **src)
|
const union g_addr **src)
|
||||||
{
|
{
|
||||||
struct mpls_label_stack *nh_label;
|
struct mpls_label_stack *nh_label;
|
||||||
mpls_lse_t out_lse[MPLS_MAX_LABELS];
|
mpls_lse_t out_lse[MPLS_MAX_LABELS];
|
||||||
@ -1200,7 +1200,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
|
|||||||
label_buf[0] = '\0';
|
label_buf[0] = '\0';
|
||||||
|
|
||||||
assert(nexthop);
|
assert(nexthop);
|
||||||
for (struct nexthop *nh = nexthop; nh; nh = nh->rparent) {
|
for (const struct nexthop *nh = nexthop; nh; nh = nh->rparent) {
|
||||||
char label_buf1[20];
|
char label_buf1[20];
|
||||||
|
|
||||||
nh_label = nh->nh_label;
|
nh_label = nh->nh_label;
|
||||||
@ -1342,7 +1342,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void _netlink_mpls_build_singlepath(const char *routedesc,
|
static inline void _netlink_mpls_build_singlepath(const char *routedesc,
|
||||||
zebra_nhlfe_t *nhlfe,
|
const zebra_nhlfe_t *nhlfe,
|
||||||
struct nlmsghdr *nlmsg,
|
struct nlmsghdr *nlmsg,
|
||||||
struct rtmsg *rtmsg,
|
struct rtmsg *rtmsg,
|
||||||
size_t req_size, int cmd)
|
size_t req_size, int cmd)
|
||||||
@ -1358,9 +1358,9 @@ static inline void _netlink_mpls_build_singlepath(const char *routedesc,
|
|||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
_netlink_mpls_build_multipath(const char *routedesc, zebra_nhlfe_t *nhlfe,
|
_netlink_mpls_build_multipath(const char *routedesc, const zebra_nhlfe_t *nhlfe,
|
||||||
struct rtattr *rta, struct rtnexthop *rtnh,
|
struct rtattr *rta, struct rtnexthop *rtnh,
|
||||||
struct rtmsg *rtmsg, union g_addr **src)
|
struct rtmsg *rtmsg, const union g_addr **src)
|
||||||
{
|
{
|
||||||
int bytelen;
|
int bytelen;
|
||||||
uint8_t family;
|
uint8_t family;
|
||||||
@ -1655,7 +1655,7 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx)
|
|||||||
char buf[NL_PKT_BUF_SIZE];
|
char buf[NL_PKT_BUF_SIZE];
|
||||||
struct rtattr *rta = (void *)buf;
|
struct rtattr *rta = (void *)buf;
|
||||||
struct rtnexthop *rtnh;
|
struct rtnexthop *rtnh;
|
||||||
union g_addr *src1 = NULL;
|
const union g_addr *src1 = NULL;
|
||||||
|
|
||||||
rta->rta_type = RTA_MULTIPATH;
|
rta->rta_type = RTA_MULTIPATH;
|
||||||
rta->rta_len = RTA_LENGTH(0);
|
rta->rta_len = RTA_LENGTH(0);
|
||||||
@ -2776,7 +2776,7 @@ int kernel_upd_neigh(struct interface *ifp, struct ipaddr *ip,
|
|||||||
int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx)
|
int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx)
|
||||||
{
|
{
|
||||||
mpls_lse_t lse;
|
mpls_lse_t lse;
|
||||||
zebra_nhlfe_t *nhlfe;
|
const zebra_nhlfe_t *nhlfe;
|
||||||
struct nexthop *nexthop = NULL;
|
struct nexthop *nexthop = NULL;
|
||||||
unsigned int nexthop_num;
|
unsigned int nexthop_num;
|
||||||
const char *routedesc;
|
const char *routedesc;
|
||||||
@ -2879,7 +2879,7 @@ int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx)
|
|||||||
char buf[NL_PKT_BUF_SIZE];
|
char buf[NL_PKT_BUF_SIZE];
|
||||||
struct rtattr *rta = (void *)buf;
|
struct rtattr *rta = (void *)buf;
|
||||||
struct rtnexthop *rtnh;
|
struct rtnexthop *rtnh;
|
||||||
union g_addr *src1 = NULL;
|
const union g_addr *src1 = NULL;
|
||||||
|
|
||||||
rta->rta_type = RTA_MULTIPATH;
|
rta->rta_type = RTA_MULTIPATH;
|
||||||
rta->rta_len = RTA_LENGTH(0);
|
rta->rta_len = RTA_LENGTH(0);
|
||||||
|
@ -111,10 +111,13 @@ struct dplane_pw_info {
|
|||||||
int af;
|
int af;
|
||||||
int status;
|
int status;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
union g_addr nexthop;
|
union g_addr dest;
|
||||||
mpls_label_t local_label;
|
mpls_label_t local_label;
|
||||||
mpls_label_t remote_label;
|
mpls_label_t remote_label;
|
||||||
|
|
||||||
|
/* Nexthops */
|
||||||
|
struct nexthop_group nhg;
|
||||||
|
|
||||||
union pw_protocol_fields fields;
|
union pw_protocol_fields fields;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -386,6 +389,15 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
|
|||||||
|
|
||||||
case DPLANE_OP_PW_INSTALL:
|
case DPLANE_OP_PW_INSTALL:
|
||||||
case DPLANE_OP_PW_UNINSTALL:
|
case DPLANE_OP_PW_UNINSTALL:
|
||||||
|
/* Free allocated nexthops */
|
||||||
|
if ((*pctx)->u.pw.nhg.nexthop) {
|
||||||
|
/* This deals with recursive nexthops too */
|
||||||
|
nexthops_free((*pctx)->u.pw.nhg.nexthop);
|
||||||
|
|
||||||
|
(*pctx)->u.pw.nhg.nexthop = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case DPLANE_OP_NONE:
|
case DPLANE_OP_NONE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -744,14 +756,15 @@ uint32_t dplane_ctx_get_lsp_flags(const struct zebra_dplane_ctx *ctx)
|
|||||||
return ctx->u.lsp.flags;
|
return ctx->u.lsp.flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
zebra_nhlfe_t *dplane_ctx_get_nhlfe(struct zebra_dplane_ctx *ctx)
|
const zebra_nhlfe_t *dplane_ctx_get_nhlfe(const struct zebra_dplane_ctx *ctx)
|
||||||
{
|
{
|
||||||
DPLANE_CTX_VALID(ctx);
|
DPLANE_CTX_VALID(ctx);
|
||||||
|
|
||||||
return ctx->u.lsp.nhlfe_list;
|
return ctx->u.lsp.nhlfe_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
zebra_nhlfe_t *dplane_ctx_get_best_nhlfe(struct zebra_dplane_ctx *ctx)
|
const zebra_nhlfe_t *
|
||||||
|
dplane_ctx_get_best_nhlfe(const struct zebra_dplane_ctx *ctx)
|
||||||
{
|
{
|
||||||
DPLANE_CTX_VALID(ctx);
|
DPLANE_CTX_VALID(ctx);
|
||||||
|
|
||||||
@ -814,12 +827,12 @@ int dplane_ctx_get_pw_status(const struct zebra_dplane_ctx *ctx)
|
|||||||
return ctx->u.pw.status;
|
return ctx->u.pw.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
const union g_addr *dplane_ctx_get_pw_nexthop(
|
const union g_addr *dplane_ctx_get_pw_dest(
|
||||||
const struct zebra_dplane_ctx *ctx)
|
const struct zebra_dplane_ctx *ctx)
|
||||||
{
|
{
|
||||||
DPLANE_CTX_VALID(ctx);
|
DPLANE_CTX_VALID(ctx);
|
||||||
|
|
||||||
return &(ctx->u.pw.nexthop);
|
return &(ctx->u.pw.dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
const union pw_protocol_fields *dplane_ctx_get_pw_proto(
|
const union pw_protocol_fields *dplane_ctx_get_pw_proto(
|
||||||
@ -830,6 +843,14 @@ const union pw_protocol_fields *dplane_ctx_get_pw_proto(
|
|||||||
return &(ctx->u.pw.fields);
|
return &(ctx->u.pw.fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct nexthop_group *
|
||||||
|
dplane_ctx_get_pw_nhg(const struct zebra_dplane_ctx *ctx)
|
||||||
|
{
|
||||||
|
DPLANE_CTX_VALID(ctx);
|
||||||
|
|
||||||
|
return &(ctx->u.pw.nhg);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* End of dplane context accessors
|
* End of dplane context accessors
|
||||||
*/
|
*/
|
||||||
@ -1039,6 +1060,12 @@ static int dplane_ctx_pw_init(struct zebra_dplane_ctx *ctx,
|
|||||||
enum dplane_op_e op,
|
enum dplane_op_e op,
|
||||||
struct zebra_pw *pw)
|
struct zebra_pw *pw)
|
||||||
{
|
{
|
||||||
|
struct prefix p;
|
||||||
|
afi_t afi;
|
||||||
|
struct route_table *table;
|
||||||
|
struct route_node *rn;
|
||||||
|
struct route_entry *re;
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
|
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
|
||||||
zlog_debug("init dplane ctx %s: pw '%s', loc %u, rem %u",
|
zlog_debug("init dplane ctx %s: pw '%s', loc %u, rem %u",
|
||||||
dplane_op2str(op), pw->ifname, pw->local_label,
|
dplane_op2str(op), pw->ifname, pw->local_label,
|
||||||
@ -1056,6 +1083,7 @@ static int dplane_ctx_pw_init(struct zebra_dplane_ctx *ctx,
|
|||||||
|
|
||||||
/* This name appears to be c-string, so we use string copy. */
|
/* This name appears to be c-string, so we use string copy. */
|
||||||
strlcpy(ctx->u.pw.ifname, pw->ifname, sizeof(ctx->u.pw.ifname));
|
strlcpy(ctx->u.pw.ifname, pw->ifname, sizeof(ctx->u.pw.ifname));
|
||||||
|
|
||||||
ctx->zd_vrf_id = pw->vrf_id;
|
ctx->zd_vrf_id = pw->vrf_id;
|
||||||
ctx->u.pw.ifindex = pw->ifindex;
|
ctx->u.pw.ifindex = pw->ifindex;
|
||||||
ctx->u.pw.type = pw->type;
|
ctx->u.pw.type = pw->type;
|
||||||
@ -1064,10 +1092,37 @@ static int dplane_ctx_pw_init(struct zebra_dplane_ctx *ctx,
|
|||||||
ctx->u.pw.remote_label = pw->remote_label;
|
ctx->u.pw.remote_label = pw->remote_label;
|
||||||
ctx->u.pw.flags = pw->flags;
|
ctx->u.pw.flags = pw->flags;
|
||||||
|
|
||||||
ctx->u.pw.nexthop = pw->nexthop;
|
ctx->u.pw.dest = pw->nexthop;
|
||||||
|
|
||||||
ctx->u.pw.fields = pw->data;
|
ctx->u.pw.fields = pw->data;
|
||||||
|
|
||||||
|
/* Capture nexthop info for the pw destination. We need to look
|
||||||
|
* up and use zebra datastructs, but we're running in the zebra
|
||||||
|
* pthread here so that should be ok.
|
||||||
|
*/
|
||||||
|
memcpy(&p.u, &pw->nexthop, sizeof(pw->nexthop));
|
||||||
|
p.family = pw->af;
|
||||||
|
p.prefixlen = ((pw->af == AF_INET) ?
|
||||||
|
IPV4_MAX_PREFIXLEN : IPV6_MAX_PREFIXLEN);
|
||||||
|
|
||||||
|
afi = (pw->af == AF_INET) ? AFI_IP : AFI_IP6;
|
||||||
|
table = zebra_vrf_table(afi, SAFI_UNICAST, pw->vrf_id);
|
||||||
|
if (table) {
|
||||||
|
rn = route_node_match(table, &p);
|
||||||
|
if (rn) {
|
||||||
|
RNODE_FOREACH_RE(rn, re) {
|
||||||
|
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (re)
|
||||||
|
copy_nexthops(&(ctx->u.pw.nhg.nexthop),
|
||||||
|
re->ng.nexthop, NULL);
|
||||||
|
|
||||||
|
route_unlock_node(rn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return AOK;
|
return AOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,8 +203,9 @@ const struct nexthop_group *dplane_ctx_get_old_ng(
|
|||||||
mpls_label_t dplane_ctx_get_in_label(const struct zebra_dplane_ctx *ctx);
|
mpls_label_t dplane_ctx_get_in_label(const struct zebra_dplane_ctx *ctx);
|
||||||
uint8_t dplane_ctx_get_addr_family(const struct zebra_dplane_ctx *ctx);
|
uint8_t dplane_ctx_get_addr_family(const struct zebra_dplane_ctx *ctx);
|
||||||
uint32_t dplane_ctx_get_lsp_flags(const struct zebra_dplane_ctx *ctx);
|
uint32_t dplane_ctx_get_lsp_flags(const struct zebra_dplane_ctx *ctx);
|
||||||
zebra_nhlfe_t *dplane_ctx_get_nhlfe(struct zebra_dplane_ctx *ctx);
|
const zebra_nhlfe_t *dplane_ctx_get_nhlfe(const struct zebra_dplane_ctx *ctx);
|
||||||
zebra_nhlfe_t *dplane_ctx_get_best_nhlfe(struct zebra_dplane_ctx *ctx);
|
const zebra_nhlfe_t *dplane_ctx_get_best_nhlfe(
|
||||||
|
const struct zebra_dplane_ctx *ctx);
|
||||||
uint32_t dplane_ctx_get_lsp_num_ecmp(const struct zebra_dplane_ctx *ctx);
|
uint32_t dplane_ctx_get_lsp_num_ecmp(const struct zebra_dplane_ctx *ctx);
|
||||||
|
|
||||||
/* Accessors for pseudowire information */
|
/* Accessors for pseudowire information */
|
||||||
@ -215,10 +216,12 @@ int dplane_ctx_get_pw_type(const struct zebra_dplane_ctx *ctx);
|
|||||||
int dplane_ctx_get_pw_af(const struct zebra_dplane_ctx *ctx);
|
int dplane_ctx_get_pw_af(const struct zebra_dplane_ctx *ctx);
|
||||||
uint32_t dplane_ctx_get_pw_flags(const struct zebra_dplane_ctx *ctx);
|
uint32_t dplane_ctx_get_pw_flags(const struct zebra_dplane_ctx *ctx);
|
||||||
int dplane_ctx_get_pw_status(const struct zebra_dplane_ctx *ctx);
|
int dplane_ctx_get_pw_status(const struct zebra_dplane_ctx *ctx);
|
||||||
const union g_addr *dplane_ctx_get_pw_nexthop(
|
const union g_addr *dplane_ctx_get_pw_dest(
|
||||||
const struct zebra_dplane_ctx *ctx);
|
const struct zebra_dplane_ctx *ctx);
|
||||||
const union pw_protocol_fields *dplane_ctx_get_pw_proto(
|
const union pw_protocol_fields *dplane_ctx_get_pw_proto(
|
||||||
const struct zebra_dplane_ctx *ctx);
|
const struct zebra_dplane_ctx *ctx);
|
||||||
|
const struct nexthop_group *dplane_ctx_get_pw_nhg(
|
||||||
|
const struct zebra_dplane_ctx *ctx);
|
||||||
|
|
||||||
/* Namespace info - esp. for netlink communication */
|
/* Namespace info - esp. for netlink communication */
|
||||||
const struct zebra_dplane_info *dplane_ctx_get_ns(
|
const struct zebra_dplane_info *dplane_ctx_get_ns(
|
||||||
|
@ -43,7 +43,7 @@ struct {
|
|||||||
} kr_state;
|
} kr_state;
|
||||||
|
|
||||||
static int kernel_send_rtmsg_v4(int action, mpls_label_t in_label,
|
static int kernel_send_rtmsg_v4(int action, mpls_label_t in_label,
|
||||||
zebra_nhlfe_t *nhlfe)
|
const zebra_nhlfe_t *nhlfe)
|
||||||
{
|
{
|
||||||
struct iovec iov[5];
|
struct iovec iov[5];
|
||||||
struct rt_msghdr hdr;
|
struct rt_msghdr hdr;
|
||||||
@ -135,7 +135,7 @@ static int kernel_send_rtmsg_v4(int action, mpls_label_t in_label,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label,
|
static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label,
|
||||||
zebra_nhlfe_t *nhlfe)
|
const zebra_nhlfe_t *nhlfe)
|
||||||
{
|
{
|
||||||
struct iovec iov[5];
|
struct iovec iov[5];
|
||||||
struct rt_msghdr hdr;
|
struct rt_msghdr hdr;
|
||||||
@ -238,7 +238,7 @@ static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label,
|
|||||||
|
|
||||||
static int kernel_lsp_cmd(struct zebra_dplane_ctx *ctx)
|
static int kernel_lsp_cmd(struct zebra_dplane_ctx *ctx)
|
||||||
{
|
{
|
||||||
zebra_nhlfe_t *nhlfe;
|
const zebra_nhlfe_t *nhlfe;
|
||||||
struct nexthop *nexthop = NULL;
|
struct nexthop *nexthop = NULL;
|
||||||
unsigned int nexthop_num = 0;
|
unsigned int nexthop_num = 0;
|
||||||
int action;
|
int action;
|
||||||
@ -342,7 +342,7 @@ static enum zebra_dplane_result kmpw_install(struct zebra_dplane_ctx *ctx)
|
|||||||
|
|
||||||
/* pseudowire nexthop */
|
/* pseudowire nexthop */
|
||||||
memset(&ss, 0, sizeof(ss));
|
memset(&ss, 0, sizeof(ss));
|
||||||
gaddr = dplane_ctx_get_pw_nexthop(ctx);
|
gaddr = dplane_ctx_get_pw_dest(ctx);
|
||||||
switch (dplane_ctx_get_pw_af(ctx)) {
|
switch (dplane_ctx_get_pw_af(ctx)) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
sa_in->sin_family = AF_INET;
|
sa_in->sin_family = AF_INET;
|
||||||
|
Loading…
Reference in New Issue
Block a user