summaryrefslogtreecommitdiffstats
path: root/zebra/rt_netlink.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-05 09:56:23 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-05 09:56:23 +0000
commitc15d6efd40655f717841d00839a43df1ead5cb26 (patch)
tree35d579f9a19170e2b39085669ca92533c2d161b4 /zebra/rt_netlink.c
parentAdding upstream version 10.0.1. (diff)
downloadfrr-upstream.tar.xz
frr-upstream.zip
Adding upstream version 10.1.upstream/10.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'zebra/rt_netlink.c')
-rw-r--r--zebra/rt_netlink.c163
1 files changed, 108 insertions, 55 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index f092fc5..01b527e 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -1550,7 +1550,7 @@ static ssize_t fill_seg6ipt_encap(char *buffer, size_t buflen,
srh->first_segment = segs->num_segs - 1;
for (i = 0; i < segs->num_segs; i++) {
- memcpy(&srh->segments[i], &segs->seg[i],
+ memcpy(&srh->segments[segs->num_segs - i - 1], &segs->seg[i],
sizeof(struct in6_addr));
}
@@ -1683,6 +1683,16 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
sizeof(struct in_addr)))
return false;
break;
+ case ZEBRA_SEG6_LOCAL_ACTION_END_DX6:
+ if (!nl_attr_put32(nlmsg, req_size,
+ SEG6_LOCAL_ACTION,
+ SEG6_LOCAL_ACTION_END_DX6))
+ return false;
+ if (!nl_attr_put(nlmsg, req_size,
+ SEG6_LOCAL_NH6, &ctx->nh6,
+ sizeof(struct in_addr)))
+ return false;
+ break;
case ZEBRA_SEG6_LOCAL_ACTION_END_DT6:
if (!nl_attr_put32(nlmsg, req_size,
SEG6_LOCAL_ACTION,
@@ -1714,7 +1724,6 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
return false;
break;
case ZEBRA_SEG6_LOCAL_ACTION_END_DX2:
- case ZEBRA_SEG6_LOCAL_ACTION_END_DX6:
case ZEBRA_SEG6_LOCAL_ACTION_END_B6:
case ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP:
case ZEBRA_SEG6_LOCAL_ACTION_END_BM:
@@ -1882,6 +1891,36 @@ static inline bool _netlink_set_tag(struct nlmsghdr *n, unsigned int maxlen,
return true;
}
+/*
+ * The function returns true if the attribute could be added
+ * to the message, otherwise false is returned.
+ */
+static int netlink_route_nexthop_encap(bool fpm, struct nlmsghdr *n,
+ size_t nlen, const struct nexthop *nh)
+{
+ struct rtattr *nest;
+
+ if (!fpm)
+ return true;
+
+ switch (nh->nh_encap_type) {
+ case NET_VXLAN:
+ if (!nl_attr_put16(n, nlen, RTA_ENCAP_TYPE, nh->nh_encap_type))
+ return false;
+
+ nest = nl_attr_nest(n, nlen, RTA_ENCAP);
+ if (!nest)
+ return false;
+
+ if (!nl_attr_put32(n, nlen, 0 /* VXLAN_VNI */, nh->nh_encap.vni))
+ return false;
+ nl_attr_nest_end(n, nest);
+ break;
+ }
+
+ return true;
+}
+
/* This function takes a nexthop as argument and
* appends to the given netlink msg. If the nexthop
* defines a preferred source, the src parameter
@@ -1900,10 +1939,13 @@ static inline bool _netlink_set_tag(struct nlmsghdr *n, unsigned int maxlen,
* The function returns true if the nexthop could be added
* to the message, otherwise false is returned.
*/
-static bool _netlink_route_build_multipath(
- const struct prefix *p, const char *routedesc, int bytelen,
- const struct nexthop *nexthop, struct nlmsghdr *nlmsg, size_t req_size,
- struct rtmsg *rtmsg, const union g_addr **src, route_tag_t tag)
+static bool _netlink_route_build_multipath(const struct prefix *p,
+ const char *routedesc, int bytelen,
+ const struct nexthop *nexthop,
+ struct nlmsghdr *nlmsg,
+ size_t req_size, struct rtmsg *rtmsg,
+ const union g_addr **src,
+ route_tag_t tag, bool fpm)
{
char label_buf[256];
struct vrf *vrf;
@@ -2011,6 +2053,13 @@ static bool _netlink_route_build_multipath(
if (!_netlink_set_tag(nlmsg, req_size, tag))
return false;
+ /*
+ * Add encapsulation information when installing via
+ * FPM.
+ */
+ if (!netlink_route_nexthop_encap(fpm, nlmsg, req_size, nexthop))
+ return false;
+
nl_attr_rtnh_end(nlmsg, rtnh);
return true;
}
@@ -2045,7 +2094,7 @@ _netlink_mpls_build_multipath(const struct prefix *p, const char *routedesc,
bytelen = (family == AF_INET ? 4 : 16);
return _netlink_route_build_multipath(p, routedesc, bytelen,
nhlfe->nexthop, nlmsg, req_size,
- rtmsg, src, 0);
+ rtmsg, src, 0, false);
}
static void _netlink_mpls_debug(int cmd, uint32_t label, const char *routedesc)
@@ -2141,34 +2190,6 @@ static bool nexthop_set_src(const struct nexthop *nexthop, int family,
}
/*
- * The function returns true if the attribute could be added
- * to the message, otherwise false is returned.
- */
-static int netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen,
- struct nexthop *nh)
-{
- struct rtattr *nest;
-
- switch (nh->nh_encap_type) {
- case NET_VXLAN:
- if (!nl_attr_put16(n, nlen, RTA_ENCAP_TYPE, nh->nh_encap_type))
- return false;
-
- nest = nl_attr_nest(n, nlen, RTA_ENCAP);
- if (!nest)
- return false;
-
- if (!nl_attr_put32(n, nlen, 0 /* VXLAN_VNI */,
- nh->nh_encap.vni))
- return false;
- nl_attr_nest_end(n, nest);
- break;
- }
-
- return true;
-}
-
-/*
* Routing table change via netlink interface, using a dataplane context object
*
* Returns -1 on failure, 0 when the msg doesn't fit entirely in the buffer
@@ -2360,6 +2381,14 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx
break;
setsrc = nexthop_set_src(nexthop, p->family, &src);
+ if (setsrc && IS_ZEBRA_DEBUG_KERNEL) {
+ if (p->family == AF_INET)
+ zlog_debug("%s: %pFX set src %pI4",
+ __func__, p, &src.ipv4);
+ else if (p->family == AF_INET6)
+ zlog_debug("%s: %pFX set src %pI6",
+ __func__, p, &src.ipv6);
+ }
}
if (setsrc) {
@@ -2402,6 +2431,16 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx
setsrc = nexthop_set_src(nexthop, p->family,
&src);
+ if (setsrc && IS_ZEBRA_DEBUG_KERNEL) {
+ if (p->family == AF_INET)
+ zlog_debug("%s: %pFX set src %pI4",
+ __func__, p,
+ &src.ipv4);
+ else if (p->family == AF_INET6)
+ zlog_debug("%s: %pFX set src %pI6",
+ __func__, p,
+ &src.ipv6);
+ }
continue;
}
@@ -2422,12 +2461,10 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx
* Add encapsulation information when
* installing via FPM.
*/
- if (fpm) {
- if (!netlink_route_nexthop_encap(&req->n,
- datalen,
- nexthop))
- return 0;
- }
+ if (!netlink_route_nexthop_encap(fpm, &req->n,
+ datalen,
+ nexthop))
+ return 0;
nexthop_num++;
break;
@@ -2463,6 +2500,16 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx
setsrc = nexthop_set_src(nexthop, p->family,
&src);
+ if (setsrc && IS_ZEBRA_DEBUG_KERNEL) {
+ if (p->family == AF_INET)
+ zlog_debug("%s: %pFX set src %pI4",
+ __func__, p,
+ &src.ipv4);
+ else if (p->family == AF_INET6)
+ zlog_debug("%s: %pFX set src %pI6",
+ __func__, p,
+ &src.ipv6);
+ }
continue;
}
@@ -2472,22 +2519,16 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx
: "multipath";
nexthop_num++;
- if (!_netlink_route_build_multipath(
- p, routedesc, bytelen, nexthop,
- &req->n, datalen, &req->r, &src1,
- tag))
+ if (!_netlink_route_build_multipath(p, routedesc,
+ bytelen,
+ nexthop,
+ &req->n,
+ datalen,
+ &req->r,
+ &src1, tag,
+ fpm))
return 0;
- /*
- * Add encapsulation information when installing via
- * FPM.
- */
- if (fpm) {
- if (!netlink_route_nexthop_encap(
- &req->n, datalen, nexthop))
- return 0;
- }
-
if (!setsrc && src1) {
if (p->family == AF_INET)
src.ipv4 = src1->ipv4;
@@ -2931,6 +2972,18 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
sizeof(struct in_addr)))
return 0;
break;
+ case SEG6_LOCAL_ACTION_END_DX6:
+ if (!nl_attr_put32(&req->n,
+ buflen,
+ SEG6_LOCAL_ACTION,
+ SEG6_LOCAL_ACTION_END_DX6))
+ return 0;
+ if (!nl_attr_put(&req->n, buflen,
+ SEG6_LOCAL_NH6,
+ &ctx->nh6,
+ sizeof(struct in_addr)))
+ return 0;
+ break;
case SEG6_LOCAL_ACTION_END_DT6:
if (!nl_attr_put32(
&req->n, buflen,