return true;
}
+static size_t fill_seg6ipt_encap(char *buffer, size_t buflen,
+ struct in6_addr *seg)
+{
+ struct seg6_iptunnel_encap *ipt;
+ struct ipv6_sr_hdr *srh;
+ const size_t srhlen = 24;
+ memset(buffer, 0, buflen);
+
+ ipt = (struct seg6_iptunnel_encap *)buffer;
+ ipt->mode = SEG6_IPTUN_MODE_ENCAP;
+ srh = ipt->srh;
+ srh->hdrlen = (srhlen >> 3) - 1;
+ srh->type = 4;
+ srh->segments_left = 0;
+ srh->first_segment = 0;
+ memcpy(&srh->segments[0], seg, sizeof(struct in6_addr));
+
+ return srhlen + 4;
+}
+
/* This function takes a nexthop as argument and adds
* the appropriate netlink attributes to an existing
* netlink message.
nl_attr_nest_end(nlmsg, nest);
}
+ if (nexthop->nh_seg6_segs) {
+ char tun_buf[4096];
+ size_t tun_len;
+ struct rtattr *nest;
+
+ nl_attr_put16(nlmsg, req_size, RTA_ENCAP_TYPE,
+ LWTUNNEL_ENCAP_SEG6);
+ nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP);
+ tun_len = fill_seg6ipt_encap(tun_buf, sizeof(tun_buf),
+ nexthop->nh_seg6_segs);
+ nl_attr_put(nlmsg, req_size, SEG6_IPTUNNEL_SRH,
+ tun_buf, tun_len);
+ nl_attr_nest_end(nlmsg, nest);
+ }
+
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
rtmsg->rtm_flags |= RTNH_F_ONLINK;
nl_attr_nest_end(&req->n, nest);
}
+ if (nh->nh_seg6_segs) {
+ char tun_buf[4096];
+ size_t tun_len;
+ struct rtattr *nest;
+
+ nl_attr_put16(&req->n, buflen, NHA_ENCAP_TYPE,
+ LWTUNNEL_ENCAP_SEG6);
+ nest = nl_attr_nest(&req->n, buflen,
+ NHA_ENCAP | NLA_F_NESTED);
+ tun_len = fill_seg6ipt_encap(tun_buf,
+ sizeof(tun_buf),
+ nh->nh_seg6_segs);
+ nl_attr_put(&req->n, buflen, SEG6_IPTUNNEL_SRH,
+ tun_buf, tun_len);
+ nl_attr_nest_end(&req->n, nest);
+ }
+
nexthop_done:
if (IS_ZEBRA_DEBUG_KERNEL)
nexthop_del_labels(nh);
nexthop_del_seg6local(nh);
+ nexthop_del_seg6(nh);
done:
XFREE(MTYPE_NHG_CTX, *ctx);
/* The copy may have allocated labels; free them if necessary. */
nexthop_del_labels(&lookup);
nexthop_del_seg6local(&lookup);
+ nexthop_del_seg6(&lookup);
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
zlog_debug("%s: nh %pNHv => %p (%u)",
buf);
}
+ if (nexthop->nh_seg6_segs) {
+ inet_ntop(AF_INET6, nexthop->nh_seg6_segs, buf, sizeof(buf));
+ vty_out(vty, ", seg6 %s", buf);
+ }
+
if (nexthop->weight)
vty_out(vty, ", weight %u", nexthop->weight);
json_object *json_labels = NULL;
json_object *json_backups = NULL;
json_object *json_seg6local = NULL;
+ json_object *json_seg6 = NULL;
int i;
json_object_int_add(json_nexthop, "flags",
json_object_object_add(json_nexthop, "seg6local",
json_seg6local);
}
+
+ if (nexthop->nh_seg6_segs) {
+ json_seg6 = json_object_new_object();
+ inet_ntop(AF_INET6, nexthop->nh_seg6_segs, buf, sizeof(buf));
+ json_object_string_add(json_seg6, "segs", buf);
+ json_object_object_add(json_nexthop, "seg6", json_seg6);
+ }
}
static void vty_show_ip_route(struct vty *vty, struct route_node *rn,