summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorHiroki Shirokura <slank.dev@gmail.com>2020-12-18 13:41:19 +0100
committerMark Stapp <mjs@voltanet.io>2021-06-02 16:24:48 +0200
commitf16de90b8c4d29f28cf9829389325a5e9bb09293 (patch)
treecb7130dcfa79278a98f3651decf67a4e596fa1ff /zebra
parentzebra: ZEBRA_ROUTE_ADD supports seg6 route (step3) (diff)
downloadfrr-f16de90b8c4d29f28cf9829389325a5e9bb09293.tar.xz
frr-f16de90b8c4d29f28cf9829389325a5e9bb09293.zip
zebra: parse non-zebra seg6 configuration via netlink (step3)
FRRouting operator can install seg6 route via ZAPI, But linux kernel operator also can install seg6 route via Netlink directry (i.e. iproute2) This commit make zebra to parse non-frr seg6 route configuration via netlink and audit Zebra's RIB. Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
Diffstat (limited to 'zebra')
-rw-r--r--zebra/rt_netlink.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 00eb0b664..705a035de 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -441,6 +441,29 @@ parse_encap_seg6local(struct rtattr *tb,
return act;
}
+static int parse_encap_seg6(struct rtattr *tb, struct in6_addr *segs)
+{
+ struct rtattr *tb_encap[256] = {0};
+ struct seg6_iptunnel_encap *ipt = NULL;
+ struct in6_addr *segments = NULL;
+
+ netlink_parse_rtattr_nested(tb_encap, 256, tb);
+
+ /*
+ * TODO: It's not support multiple SID list.
+ */
+ if (tb_encap[SEG6_IPTUNNEL_SRH]) {
+ ipt = (struct seg6_iptunnel_encap *)
+ RTA_DATA(tb_encap[SEG6_IPTUNNEL_SRH]);
+ segments = ipt->srh[0].segments;
+ *segs = segments[0];
+ return 1;
+ }
+
+ return 0;
+}
+
+
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,
@@ -452,6 +475,8 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb,
int num_labels = 0;
enum seg6local_action_t seg6l_act = SEG6_LOCAL_ACTION_UNSPEC;
struct seg6local_context seg6l_ctx = {{0}};
+ struct in6_addr seg6_segs = {0};
+ int num_segs = 0;
vrf_id_t nh_vrf_id = vrf_id;
size_t sz = (afi == AFI_IP) ? 4 : 16;
@@ -496,6 +521,11 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb,
== LWTUNNEL_ENCAP_SEG6_LOCAL) {
seg6l_act = parse_encap_seg6local(tb[RTA_ENCAP], &seg6l_ctx);
}
+ if (tb[RTA_ENCAP] && tb[RTA_ENCAP_TYPE]
+ && *(uint16_t *)RTA_DATA(tb[RTA_ENCAP_TYPE])
+ == LWTUNNEL_ENCAP_SEG6) {
+ num_segs = parse_encap_seg6(tb[RTA_ENCAP], &seg6_segs);
+ }
if (rtm->rtm_flags & RTNH_F_ONLINK)
SET_FLAG(nh.flags, NEXTHOP_FLAG_ONLINK);
@@ -506,6 +536,9 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb,
if (seg6l_act != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
nexthop_add_seg6local(&nh, seg6l_act, &seg6l_ctx);
+ if (num_segs)
+ nexthop_add_seg6(&nh, &seg6_segs);
+
return nh;
}
@@ -524,6 +557,8 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id,
int num_labels = 0;
enum seg6local_action_t seg6l_act = SEG6_LOCAL_ACTION_UNSPEC;
struct seg6local_context seg6l_ctx = {{0}};
+ struct in6_addr seg6_segs = {0};
+ int num_segs = 0;
struct rtattr *rtnh_tb[RTA_MAX + 1] = {};
int len = RTA_PAYLOAD(tb[RTA_MULTIPATH]);
@@ -574,6 +609,12 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id,
seg6l_act = parse_encap_seg6local(
rtnh_tb[RTA_ENCAP], &seg6l_ctx);
}
+ if (rtnh_tb[RTA_ENCAP] && rtnh_tb[RTA_ENCAP_TYPE]
+ && *(uint16_t *)RTA_DATA(rtnh_tb[RTA_ENCAP_TYPE])
+ == LWTUNNEL_ENCAP_SEG6) {
+ num_segs = parse_encap_seg6(rtnh_tb[RTA_ENCAP],
+ &seg6_segs);
+ }
}
if (gate && rtm->rtm_family == AF_INET) {
@@ -603,6 +644,9 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id,
nexthop_add_seg6local(nh, seg6l_act,
&seg6l_ctx);
+ if (num_segs)
+ nexthop_add_seg6(nh, &seg6_segs);
+
if (rtnh->rtnh_flags & RTNH_F_ONLINK)
SET_FLAG(nh->flags, NEXTHOP_FLAG_ONLINK);