Merge pull request #3893 from mjstapp/dplane_pw_nexthops

zebra: include nexthop info when installing pseudowires
This commit is contained in:
Donald Sharp 2019-03-12 12:44:42 -04:00 committed by GitHub
commit 6ac9718a2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 84 additions and 26 deletions

View File

@ -927,7 +927,7 @@ static void _netlink_route_nl_add_gateway_info(uint8_t route_family,
uint8_t gw_family,
struct nlmsghdr *nlmsg,
size_t req_size, int bytelen,
struct nexthop *nexthop)
const struct nexthop *nexthop)
{
if (route_family == AF_MPLS) {
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 rtnexthop *rtnh,
size_t req_size, int bytelen,
struct nexthop *nexthop)
const struct nexthop *nexthop)
{
if (route_family == AF_MPLS) {
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.
*/
static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
struct nexthop *nexthop,
const struct nexthop *nexthop,
struct nlmsghdr *nlmsg,
struct rtmsg *rtmsg,
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';
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];
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.
*/
static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
struct nexthop *nexthop,
const struct nexthop *nexthop,
struct rtattr *rta,
struct rtnexthop *rtnh,
struct rtmsg *rtmsg,
union g_addr **src)
const union g_addr **src)
{
struct mpls_label_stack *nh_label;
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';
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];
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,
zebra_nhlfe_t *nhlfe,
const zebra_nhlfe_t *nhlfe,
struct nlmsghdr *nlmsg,
struct rtmsg *rtmsg,
size_t req_size, int cmd)
@ -1358,9 +1358,9 @@ static inline void _netlink_mpls_build_singlepath(const char *routedesc,
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 rtmsg *rtmsg, union g_addr **src)
struct rtmsg *rtmsg, const union g_addr **src)
{
int bytelen;
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];
struct rtattr *rta = (void *)buf;
struct rtnexthop *rtnh;
union g_addr *src1 = NULL;
const union g_addr *src1 = NULL;
rta->rta_type = RTA_MULTIPATH;
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)
{
mpls_lse_t lse;
zebra_nhlfe_t *nhlfe;
const zebra_nhlfe_t *nhlfe;
struct nexthop *nexthop = NULL;
unsigned int nexthop_num;
const char *routedesc;
@ -2879,7 +2879,7 @@ int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx)
char buf[NL_PKT_BUF_SIZE];
struct rtattr *rta = (void *)buf;
struct rtnexthop *rtnh;
union g_addr *src1 = NULL;
const union g_addr *src1 = NULL;
rta->rta_type = RTA_MULTIPATH;
rta->rta_len = RTA_LENGTH(0);

View File

@ -111,10 +111,13 @@ struct dplane_pw_info {
int af;
int status;
uint32_t flags;
union g_addr nexthop;
union g_addr dest;
mpls_label_t local_label;
mpls_label_t remote_label;
/* Nexthops */
struct nexthop_group nhg;
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_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:
break;
}
@ -744,14 +756,15 @@ uint32_t dplane_ctx_get_lsp_flags(const struct zebra_dplane_ctx *ctx)
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);
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);
@ -814,12 +827,12 @@ int dplane_ctx_get_pw_status(const struct zebra_dplane_ctx *ctx)
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)
{
DPLANE_CTX_VALID(ctx);
return &(ctx->u.pw.nexthop);
return &(ctx->u.pw.dest);
}
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);
}
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
*/
@ -1039,6 +1060,12 @@ static int dplane_ctx_pw_init(struct zebra_dplane_ctx *ctx,
enum dplane_op_e op,
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)
zlog_debug("init dplane ctx %s: pw '%s', loc %u, rem %u",
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. */
strlcpy(ctx->u.pw.ifname, pw->ifname, sizeof(ctx->u.pw.ifname));
ctx->zd_vrf_id = pw->vrf_id;
ctx->u.pw.ifindex = pw->ifindex;
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.flags = pw->flags;
ctx->u.pw.nexthop = pw->nexthop;
ctx->u.pw.dest = pw->nexthop;
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;
}

View File

@ -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);
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);
zebra_nhlfe_t *dplane_ctx_get_nhlfe(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_nhlfe(const 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);
/* 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);
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);
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 union pw_protocol_fields *dplane_ctx_get_pw_proto(
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 */
const struct zebra_dplane_info *dplane_ctx_get_ns(

View File

@ -43,7 +43,7 @@ struct {
} kr_state;
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 rt_msghdr hdr;
@ -135,7 +135,7 @@ static int kernel_send_rtmsg_v4(int action, mpls_label_t in_label,
#endif
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 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)
{
zebra_nhlfe_t *nhlfe;
const zebra_nhlfe_t *nhlfe;
struct nexthop *nexthop = NULL;
unsigned int nexthop_num = 0;
int action;
@ -342,7 +342,7 @@ static enum zebra_dplane_result kmpw_install(struct zebra_dplane_ctx *ctx)
/* pseudowire nexthop */
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)) {
case AF_INET:
sa_in->sin_family = AF_INET;