diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2019-03-12 17:44:42 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-12 17:44:42 +0100 |
commit | 6ac9718a2af66a796bf953e4ab9e7dd48f57754e (patch) | |
tree | faad9ea7e5c69abcb72b16e50b420d5515a79af7 /zebra | |
parent | Merge pull request #3908 from Tuetuopay/fix-unnumbered-no-ip (diff) | |
parent | zebra: use const in dplane pw nhlfe accessors (diff) | |
download | frr-6ac9718a2af66a796bf953e4ab9e7dd48f57754e.tar.xz frr-6ac9718a2af66a796bf953e4ab9e7dd48f57754e.zip |
Merge pull request #3893 from mjstapp/dplane_pw_nexthops
zebra: include nexthop info when installing pseudowires
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/rt_netlink.c | 26 | ||||
-rw-r--r-- | zebra/zebra_dplane.c | 67 | ||||
-rw-r--r-- | zebra/zebra_dplane.h | 9 | ||||
-rw-r--r-- | zebra/zebra_mpls_openbsd.c | 8 |
4 files changed, 84 insertions, 26 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 2a297409f..c56e2f316 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -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); diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 894914e57..df26a8534 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -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; } diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index 81226961e..149ff8dc6 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -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( diff --git a/zebra/zebra_mpls_openbsd.c b/zebra/zebra_mpls_openbsd.c index ade36cbce..977a8eaf3 100644 --- a/zebra/zebra_mpls_openbsd.c +++ b/zebra/zebra_mpls_openbsd.c @@ -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; |