diff options
| author | Stephen Worley <sworley@nvidia.com> | 2021-04-01 11:50:31 -0400 | 
|---|---|---|
| committer | Stephen Worley <sworley@nvidia.com> | 2023-02-13 18:12:05 -0500 | 
| commit | 5fa6bfffb1201c98960ea8a3808d6e1e7ed8c312 (patch) | |
| tree | c49c7323b12e1c28e3172d08a0c10e74573e28a7 /zebra | |
| parent | 31e1a1033d95a14d24bd87cb4bec480067c01a89 (diff) | |
zebra: encode vni label via lwt encap
Encode the vni label during route install on linux
systems via lwt encap 64bit LWTUNNEL_IP_ID. The kernel expects
this in network byte order, so we convert it.
Signed-off-by: Stephen Worley <sworley@nvidia.com>
Diffstat (limited to 'zebra')
| -rw-r--r-- | zebra/kernel_netlink.c | 6 | ||||
| -rw-r--r-- | zebra/kernel_netlink.h | 2 | ||||
| -rw-r--r-- | zebra/rt_netlink.c | 78 | 
3 files changed, 68 insertions, 18 deletions
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 42afe61469..0c45350700 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -705,6 +705,12 @@ bool nl_attr_put32(struct nlmsghdr *n, unsigned int maxlen, int type,  	return nl_attr_put(n, maxlen, type, &data, sizeof(uint32_t));  } +bool nl_attr_put64(struct nlmsghdr *n, unsigned int maxlen, int type, +		   uint64_t data) +{ +	return nl_attr_put(n, maxlen, type, &data, sizeof(uint64_t)); +} +  struct rtattr *nl_attr_nest(struct nlmsghdr *n, unsigned int maxlen, int type)  {  	struct rtattr *nest = NLMSG_TAIL(n); diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h index 08cd706a9f..ad6e639b42 100644 --- a/zebra/kernel_netlink.h +++ b/zebra/kernel_netlink.h @@ -48,6 +48,8 @@ extern bool nl_attr_put16(struct nlmsghdr *n, unsigned int maxlen, int type,  			  uint16_t data);  extern bool nl_attr_put32(struct nlmsghdr *n, unsigned int maxlen, int type,  			  uint32_t data); +extern bool nl_attr_put64(struct nlmsghdr *n, unsigned int maxlen, int type, +			  uint64_t data);  /*   * nl_attr_nest - start an attribute nest. diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index d09318a5a5..390c78b7ac 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1325,6 +1325,7 @@ static bool _netlink_route_add_gateway_info(uint8_t route_family,  }  static int build_label_stack(struct mpls_label_stack *nh_label, +			     enum lsp_types_t nh_label_type,  			     mpls_lse_t *out_lse, char *label_buf,  			     size_t label_buf_size)  { @@ -1332,7 +1333,8 @@ static int build_label_stack(struct mpls_label_stack *nh_label,  	int num_labels = 0;  	for (int i = 0; nh_label && i < nh_label->num_labels; i++) { -		if (nh_label->label[i] == MPLS_LABEL_IMPLICIT_NULL) +		if (nh_label_type == ZEBRA_LSP_EVPN +		    && nh_label->label[i] == MPLS_LABEL_IMPLICIT_NULL)  			continue;  		if (IS_ZEBRA_DEBUG_KERNEL) { @@ -1346,15 +1348,18 @@ static int build_label_stack(struct mpls_label_stack *nh_label,  			}  		} -		out_lse[num_labels] = -			mpls_lse_encode(nh_label->label[i], 0, 0, 0); +		if (nh_label_type == ZEBRA_LSP_EVPN) +			out_lse[num_labels] = label2vni(&nh_label->label[i]); +		else +			out_lse[num_labels] = +				mpls_lse_encode(nh_label->label[i], 0, 0, 0);  		num_labels++;  	}  	return num_labels;  } -static bool _netlink_route_encode_label_info(struct mpls_label_stack *nh_label, +static bool _netlink_route_encode_label_info(const struct nexthop *nexthop,  					     struct nlmsghdr *nlmsg,  					     size_t buflen, struct rtmsg *rtmsg,  					     char *label_buf, @@ -1362,6 +1367,12 @@ static bool _netlink_route_encode_label_info(struct mpls_label_stack *nh_label,  {  	mpls_lse_t out_lse[MPLS_MAX_LABELS];  	int num_labels; +	struct rtattr *nest; +	struct mpls_label_stack *nh_label; +	enum lsp_types_t nh_label_type; + +	nh_label = nexthop->nh_label; +	nh_label_type = nexthop->nh_label_type;  	/*  	 * label_buf is *only* currently used within debugging. @@ -1371,10 +1382,45 @@ static bool _netlink_route_encode_label_info(struct mpls_label_stack *nh_label,  	 */  	label_buf[0] = '\0'; -	num_labels = -		build_label_stack(nh_label, out_lse, label_buf, label_buf_size); +	num_labels = build_label_stack(nh_label, nh_label_type, out_lse, +				       label_buf, label_buf_size); + +	if (num_labels && nh_label_type == ZEBRA_LSP_EVPN) { + +		if (!nl_attr_put16(nlmsg, buflen, RTA_ENCAP_TYPE, +				   LWTUNNEL_ENCAP_IP)) +			return false; + +		nest = nl_attr_nest(nlmsg, buflen, RTA_ENCAP); +		if (!nest) +			return false; + +		if (!nl_attr_put64(nlmsg, buflen, LWTUNNEL_IP_ID, +				   htonll((uint64_t)out_lse[0]))) +			return false; + +		if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) { +			if (!nl_attr_put(nlmsg, buflen, LWTUNNEL_IP_DST, +					 &nexthop->gate.ipv4, 4)) +				return false; -	if (num_labels) { +		} else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) { +			if (!nl_attr_put(nlmsg, buflen, LWTUNNEL_IP_DST, +					 &nexthop->gate.ipv6, 16)) +				return false; + +		} else { +			if (IS_ZEBRA_DEBUG_KERNEL) +				zlog_debug( +					"%s: nexthop %pNHv %s must NEXTHOP_TYPE_IPV*_IFINDEX to be vxlan encapped", +					__func__, nexthop, label_buf); + +			return false; +		} + +		nl_attr_nest_end(nlmsg, nest); + +	} else if (num_labels) {  		/* Set the BoS bit */  		out_lse[num_labels - 1] |= htonl(1 << MPLS_LS_S_SHIFT); @@ -1383,8 +1429,6 @@ static bool _netlink_route_encode_label_info(struct mpls_label_stack *nh_label,  					 num_labels * sizeof(mpls_lse_t)))  				return false;  		} else { -			struct rtattr *nest; -  			if (!nl_attr_put16(nlmsg, buflen, RTA_ENCAP_TYPE,  					   LWTUNNEL_ENCAP_MPLS))  				return false; @@ -1498,9 +1542,8 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,  	vrf = vrf_lookup_by_id(nexthop->vrf_id); -	if (!_netlink_route_encode_label_info(nexthop->nh_label, nlmsg, -					      req_size, rtmsg, label_buf, -					      sizeof(label_buf))) +	if (!_netlink_route_encode_label_info(nexthop, nlmsg, req_size, rtmsg, +					      label_buf, sizeof(label_buf)))  		return false;  	if (nexthop->nh_srv6) { @@ -1781,9 +1824,8 @@ static bool _netlink_route_build_multipath(  	vrf = vrf_lookup_by_id(nexthop->vrf_id); -	if (!_netlink_route_encode_label_info(nexthop->nh_label, nlmsg, -					      req_size, rtmsg, label_buf, -					      sizeof(label_buf))) +	if (!_netlink_route_encode_label_info(nexthop, nlmsg, req_size, rtmsg, +					      label_buf, sizeof(label_buf)))  		return false;  	if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) @@ -2665,9 +2707,9 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,  			if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ONLINK))  				req->nhm.nh_flags |= RTNH_F_ONLINK; -			num_labels = -				build_label_stack(nh->nh_label, out_lse, -						  label_buf, sizeof(label_buf)); +			num_labels = build_label_stack( +				nh->nh_label, nh->nh_label_type, out_lse, +				label_buf, sizeof(label_buf));  			if (num_labels) {  				/* Set the BoS bit */  | 
