Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zebra: ZEBRA_ROUTE_ADD api supports seg6local route #7680

Closed
wants to merge 9 commits into from
Prev Previous commit
Next Next commit
zebra: parse non-zebra seg6local configuration via netlink
FRRouting operator can install seg6local route via ZAPI,
But linux kernel operator also can install seg6local route
via Netlink directry (i.e. iproute2)

This commit make zebra to parse non-frr seg6local route
configuration via netlink and audit Zebra's RIB.

Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
  • Loading branch information
slankdev committed Dec 9, 2020
commit 8a81428f3d867203cd2bb885898def655c0aa366
48 changes: 48 additions & 0 deletions zebra/rt_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,32 @@ static int parse_encap_mpls(struct rtattr *tb, mpls_label_t *labels)
return num_labels;
}

static enum seg6local_action_t
parse_encap_seg6local(struct rtattr *tb,
struct seg6local_context *ctx)
{
struct rtattr *tb_encap[256] = {0};
enum seg6local_action_t act = ZEBRA_SEG6_LOCAL_ACTION_UNSPEC;

netlink_parse_rtattr_nested(tb_encap, 256, tb);

if (tb_encap[SEG6_LOCAL_ACTION])
act = *(uint32_t *)RTA_DATA(tb_encap[SEG6_LOCAL_ACTION]);

if (tb_encap[SEG6_LOCAL_NH4])
ctx->nh4 = *(struct in_addr *)RTA_DATA(
tb_encap[SEG6_LOCAL_NH4]);

if (tb_encap[SEG6_LOCAL_NH6])
ctx->nh6 = *(struct in6_addr *)RTA_DATA(
tb_encap[SEG6_LOCAL_NH6]);

if (tb_encap[SEG6_LOCAL_TABLE])
ctx->table = *(uint32_t *)RTA_DATA(tb_encap[SEG6_LOCAL_TABLE]);

return act;
}

static struct nexthop
parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb,
enum blackhole_type bh_type, int index, void *prefsrc,
Expand All @@ -426,6 +452,8 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb,
struct nexthop nh = {0};
mpls_label_t labels[MPLS_MAX_LABELS] = {0};
int num_labels = 0;
enum seg6local_action_t seg6l_act = SEG6_LOCAL_ACTION_UNSPEC;
struct seg6local_context seg6l_ctx = {0};

vrf_id_t nh_vrf_id = vrf_id;
size_t sz = (afi == AFI_IP) ? 4 : 16;
Expand Down Expand Up @@ -465,13 +493,21 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb,
== LWTUNNEL_ENCAP_MPLS) {
num_labels = parse_encap_mpls(tb[RTA_ENCAP], labels);
}
if (tb[RTA_ENCAP] && tb[RTA_ENCAP_TYPE]
&& *(uint16_t *)RTA_DATA(tb[RTA_ENCAP_TYPE])
== LWTUNNEL_ENCAP_SEG6_LOCAL) {
seg6l_act = parse_encap_seg6local(tb[RTA_ENCAP], &seg6l_ctx);
}

if (rtm->rtm_flags & RTNH_F_ONLINK)
SET_FLAG(nh.flags, NEXTHOP_FLAG_ONLINK);

if (num_labels)
nexthop_add_labels(&nh, ZEBRA_LSP_STATIC, num_labels, labels);

if (seg6l_act != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
nexthop_add_seg6local(&nh, seg6l_act, &seg6l_ctx);

return nh;
}

Expand All @@ -488,6 +524,8 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id,
/* MPLS labels */
mpls_label_t labels[MPLS_MAX_LABELS] = {0};
int num_labels = 0;
enum seg6local_action_t seg6l_act = SEG6_LOCAL_ACTION_UNSPEC;
struct seg6local_context seg6l_ctx = {0};
struct rtattr *rtnh_tb[RTA_MAX + 1] = {};

int len = RTA_PAYLOAD(tb[RTA_MULTIPATH]);
Expand Down Expand Up @@ -534,6 +572,12 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id,
num_labels = parse_encap_mpls(
rtnh_tb[RTA_ENCAP], labels);
}
if (rtnh_tb[RTA_ENCAP] && rtnh_tb[RTA_ENCAP_TYPE]
&& *(uint16_t *)RTA_DATA(rtnh_tb[RTA_ENCAP_TYPE])
== LWTUNNEL_ENCAP_SEG6_LOCAL) {
seg6l_act = parse_encap_seg6local(
rtnh_tb[RTA_ENCAP], &seg6l_ctx);
}
}

if (gate && rtm->rtm_family == AF_INET) {
Expand All @@ -559,6 +603,10 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id,
nexthop_add_labels(nh, ZEBRA_LSP_STATIC,
num_labels, labels);

if (seg6l_act != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
nexthop_add_seg6local(nh, seg6l_act,
&seg6l_ctx);

if (rtnh->rtnh_flags & RTNH_F_ONLINK)
SET_FLAG(nh->flags, NEXTHOP_FLAG_ONLINK);

Expand Down