summaryrefslogtreecommitdiff
path: root/zebra/rt_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/rt_netlink.c')
-rw-r--r--zebra/rt_netlink.c66
1 files changed, 44 insertions, 22 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index be7feb21a3..ad9e13a0f8 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -1641,6 +1641,27 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
return true;
}
+/* This function appends tag value as rtnl flow attribute
+ * to the given netlink msg only if value is less than 256.
+ * Used only if SUPPORT_REALMS enabled.
+ *
+ * @param nlmsg: nlmsghdr structure to fill in.
+ * @param maxlen: The size allocated for the message.
+ * @param tag: The route tag.
+ *
+ * The function returns true if the flow attribute could
+ * be added to the message, otherwise false is returned.
+ */
+static inline bool _netlink_set_tag(struct nlmsghdr *n, unsigned int maxlen,
+ route_tag_t tag)
+{
+ if (tag > 0 && tag <= 255) {
+ if (!nl_attr_put32(n, maxlen, RTA_FLOW, tag))
+ return false;
+ }
+ 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
@@ -1659,12 +1680,10 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
* 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)
+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)
{
char label_buf[256];
struct vrf *vrf;
@@ -1770,6 +1789,9 @@ static bool _netlink_route_build_multipath(const struct prefix *p,
if (nexthop->weight)
rtnh->rtnh_hops = nexthop->weight - 1;
+ if (!_netlink_set_tag(nlmsg, req_size, tag))
+ return false;
+
nl_attr_rtnh_end(nlmsg, rtnh);
return true;
}
@@ -1804,7 +1826,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);
+ rtmsg, src, 0);
}
static void _netlink_mpls_debug(int cmd, uint32_t label, const char *routedesc)
@@ -1928,6 +1950,7 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
const struct prefix *p, *src_p;
uint32_t table_id;
struct nlsock *nl;
+ route_tag_t tag = 0;
struct {
struct nlmsghdr n;
@@ -1999,20 +2022,12 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
return 0;
#if defined(SUPPORT_REALMS)
- {
- route_tag_t tag;
-
- if (cmd == RTM_DELROUTE)
- tag = dplane_ctx_get_old_tag(ctx);
- else
- tag = dplane_ctx_get_tag(ctx);
-
- if (tag > 0 && tag <= 255) {
- if (!nl_attr_put32(&req->n, datalen, RTA_FLOW, tag))
- return 0;
- }
- }
+ if (cmd == RTM_DELROUTE)
+ tag = dplane_ctx_get_old_tag(ctx);
+ else
+ tag = dplane_ctx_get_tag(ctx);
#endif
+
/* Table corresponding to this route. */
table_id = dplane_ctx_get_table(ctx);
if (table_id < 256)
@@ -2035,8 +2050,11 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
* prefix information to tell the kernel to schwack
* it.
*/
- if (cmd == RTM_DELROUTE)
+ if (cmd == RTM_DELROUTE) {
+ if (!_netlink_set_tag(&req->n, datalen, tag))
+ return 0;
return NLMSG_ALIGN(req->n.nlmsg_len);
+ }
if (dplane_ctx_get_mtu(ctx) || dplane_ctx_get_nh_mtu(ctx)) {
struct rtattr *nest;
@@ -2151,6 +2169,9 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
? "recursive, single-path"
: "single-path";
+ if (!_netlink_set_tag(&req->n, datalen, tag))
+ return 0;
+
if (!_netlink_route_build_singlepath(
p, routedesc, bytelen, nexthop,
&req->n, &req->r, datalen, cmd))
@@ -2210,7 +2231,8 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
if (!_netlink_route_build_multipath(
p, routedesc, bytelen, nexthop,
- &req->n, datalen, &req->r, &src1))
+ &req->n, datalen, &req->r, &src1,
+ tag))
return 0;
if (!setsrc && src1) {