summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolodymyr Bendiuga <volodymyr.bendiuga@westermo.com>2022-04-19 14:51:34 +0200
committerThomas Haller <thaller@redhat.com>2022-05-27 09:41:29 +0200
commitf8eb2185656e7e224deb10666b7f3108e58e2acd (patch)
tree4348f4cc632d74109c66c6c83787d9c7917c8510
parente5dc111f8c9c646b1fca3f3aabaa00165952b89c (diff)
downloadlibnl-f8eb2185656e7e224deb10666b7f3108e58e2acd.tar.gz
cls: flower: extend flower API
The following API has been added: rtnl_flower_set_ipv4_src rtnl_flower_get_ipv4_src rtnl_flower_set_ipv4_dst rtnl_flower_get_ipv4_dst Signed-off-by: Volodymyr Bendiuga <volodymyr.bendiuga@westermo.com> https://github.com/thom311/libnl/pull/309
-rw-r--r--include/netlink-private/types.h6
-rw-r--r--include/netlink/route/cls/flower.h9
-rw-r--r--lib/route/cls/flower.c174
-rw-r--r--libnl-route-3.sym8
4 files changed, 197 insertions, 0 deletions
diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h
index 750f1917..b8f785af 100644
--- a/include/netlink-private/types.h
+++ b/include/netlink-private/types.h
@@ -29,6 +29,8 @@
#include <linux/fib_rules.h>
#include <linux/if_ether.h>
+#include <netinet/in.h>
+
#define NL_SOCK_PASSCRED (1<<1)
#define NL_OWN_PORT (1<<2)
#define NL_MSG_PEEK (1<<3)
@@ -624,6 +626,10 @@ struct rtnl_flower
uint8_t cf_src_mac_mask[ETH_ALEN];
uint8_t cf_dst_mac[ETH_ALEN];
uint8_t cf_dst_mac_mask[ETH_ALEN];
+ in_addr_t cf_ipv4_src;
+ in_addr_t cf_ipv4_src_mask;
+ in_addr_t cf_ipv4_dst;
+ in_addr_t cf_ipv4_dst_mask;
uint8_t cf_ip_dscp;
uint8_t cf_ip_dscp_mask;
};
diff --git a/include/netlink/route/cls/flower.h b/include/netlink/route/cls/flower.h
index dab910f8..733cccca 100644
--- a/include/netlink/route/cls/flower.h
+++ b/include/netlink/route/cls/flower.h
@@ -39,6 +39,15 @@ extern int rtnl_flower_get_src_mac(struct rtnl_cls *, unsigned char *,
extern int rtnl_flower_set_ip_dscp(struct rtnl_cls *, uint8_t, uint8_t);
extern int rtnl_flower_get_ip_dscp(struct rtnl_cls *, uint8_t *, uint8_t *);
+extern int rtnl_flower_set_ipv4_src(struct rtnl_cls *, in_addr_t,
+ in_addr_t);
+extern int rtnl_flower_get_ipv4_src(struct rtnl_cls *, in_addr_t *,
+ in_addr_t *);
+extern int rtnl_flower_set_ipv4_dst(struct rtnl_cls *, in_addr_t,
+ in_addr_t);
+extern int rtnl_flower_get_ipv4_dst(struct rtnl_cls *, in_addr_t *,
+ in_addr_t *);
+
extern int rtnl_flower_set_flags(struct rtnl_cls *, int);
extern int rtnl_flower_append_action(struct rtnl_cls *, struct rtnl_act *);
diff --git a/lib/route/cls/flower.c b/lib/route/cls/flower.c
index 6b1e41b0..c6a53fcb 100644
--- a/lib/route/cls/flower.c
+++ b/lib/route/cls/flower.c
@@ -27,6 +27,10 @@
#define FLOWER_ATTR_IP_DSCP (1 << 9)
#define FLOWER_ATTR_IP_DSCP_MASK (1 << 10)
#define FLOWER_ATTR_PROTO (1 << 11)
+#define FLOWER_ATTR_IPV4_SRC (1 << 12)
+#define FLOWER_ATTR_IPV4_SRC_MASK (1 << 13)
+#define FLOWER_ATTR_IPV4_DST (1 << 14)
+#define FLOWER_ATTR_IPV4_DST_MASK (1 << 15)
/** @endcond */
#define FLOWER_DSCP_MAX 0xe0
@@ -46,6 +50,10 @@ static struct nla_policy flower_policy[TCA_FLOWER_MAX + 1] = {
[TCA_FLOWER_KEY_IP_TOS] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_IP_TOS_MASK] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_VLAN_ETH_TYPE] = { .type = NLA_U16 },
+ [TCA_FLOWER_KEY_IPV4_SRC] = { .type = NLA_U32 },
+ [TCA_FLOWER_KEY_IPV4_SRC_MASK] = { .type = NLA_U32 },
+ [TCA_FLOWER_KEY_IPV4_DST] = { .type = NLA_U32 },
+ [TCA_FLOWER_KEY_IPV4_DST_MASK] = { .type = NLA_U32 },
};
static int flower_msg_parser(struct rtnl_tc *tc, void *data)
@@ -121,6 +129,26 @@ static int flower_msg_parser(struct rtnl_tc *tc, void *data)
f->cf_mask |= FLOWER_ATTR_IP_DSCP_MASK;
}
+ if (tb[TCA_FLOWER_KEY_IPV4_SRC]) {
+ f->cf_ipv4_src = nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_SRC]);
+ f->cf_mask |= FLOWER_ATTR_IPV4_SRC;
+ }
+
+ if (tb[TCA_FLOWER_KEY_IPV4_SRC_MASK]) {
+ f->cf_ipv4_src_mask = nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_SRC_MASK]);
+ f->cf_mask |= FLOWER_ATTR_IPV4_SRC_MASK;
+ }
+
+ if (tb[TCA_FLOWER_KEY_IPV4_DST]) {
+ f->cf_ipv4_dst = nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_DST]);
+ f->cf_mask |= FLOWER_ATTR_IPV4_DST;
+ }
+
+ if (tb[TCA_FLOWER_KEY_IPV4_DST_MASK]) {
+ f->cf_ipv4_dst_mask = nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_DST_MASK]);
+ f->cf_mask |= FLOWER_ATTR_IPV4_DST_MASK;
+ }
+
return 0;
}
@@ -171,6 +199,18 @@ static int flower_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
if (f->cf_mask & FLOWER_ATTR_IP_DSCP_MASK)
NLA_PUT_U8(msg, TCA_FLOWER_KEY_IP_TOS_MASK, f->cf_ip_dscp_mask);
+ if (f->cf_mask & FLOWER_ATTR_IPV4_SRC)
+ NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_SRC, f->cf_ipv4_src);
+
+ if (f->cf_mask & FLOWER_ATTR_IPV4_SRC_MASK)
+ NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_SRC_MASK, f->cf_ipv4_src_mask);
+
+ if (f->cf_mask & FLOWER_ATTR_IPV4_DST)
+ NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_DST, f->cf_ipv4_dst);
+
+ if (f->cf_mask & FLOWER_ATTR_IPV4_DST_MASK)
+ NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_DST_MASK, f->cf_ipv4_dst_mask);
+
return 0;
nla_put_failure:
@@ -224,6 +264,8 @@ static void flower_dump_details(struct rtnl_tc *tc, void *data,
struct nl_dump_params *p)
{
struct rtnl_flower *f = data;
+ char addr_str[INET_ADDRSTRLEN];
+ char mask_str[INET_ADDRSTRLEN];
if (!f)
return;
@@ -272,6 +314,18 @@ static void flower_dump_details(struct rtnl_tc *tc, void *data,
if (f->cf_mask & FLOWER_ATTR_IP_DSCP_MASK)
nl_dump(p, " dscp_mask %u", f->cf_ip_dscp_mask);
+
+ if (f->cf_mask & FLOWER_ATTR_IPV4_SRC) {
+ inet_ntop(AF_INET, &f->cf_ipv4_src, addr_str, sizeof(addr_str));
+ inet_ntop(AF_INET, &f->cf_ipv4_src_mask, mask_str, sizeof(mask_str));
+ nl_dump(p, "IPv4 src %s mask %s\n", addr_str, mask_str);
+ }
+
+ if (f->cf_mask & FLOWER_ATTR_IPV4_DST) {
+ inet_ntop(AF_INET, &f->cf_ipv4_dst, addr_str, sizeof(addr_str));
+ inet_ntop(AF_INET, &f->cf_ipv4_dst_mask, mask_str, sizeof(mask_str));
+ nl_dump(p, "IPv4 dst %s mask %s\n", addr_str, mask_str);
+ }
}
/**
@@ -599,6 +653,126 @@ int rtnl_flower_get_ip_dscp(struct rtnl_cls *cls, uint8_t *dscp, uint8_t *mask)
}
/**
+ * Set IPv4 source address for flower classifier
+ * @arg cls Flower classifier.
+ * @arg addr IPv4 source address
+ * @arg mask mask for IPv4 source address
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_set_ipv4_src(struct rtnl_cls *cls, in_addr_t addr, in_addr_t mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ if (addr) {
+ f->cf_ipv4_src = addr;
+ f->cf_mask |= FLOWER_ATTR_IPV4_SRC;
+
+ if (mask) {
+ f->cf_ipv4_src_mask = mask;
+ f->cf_mask |= FLOWER_ATTR_IPV4_SRC_MASK;
+ }
+
+ return 0;
+ }
+
+ return -NLE_FAILURE;
+}
+
+/**
+ * Get IPv4 source address for flower classifier
+ * @arg cls Flower classifier.
+ * @arg addr IPv4 source address
+ * @arg mask mask for IPv4 source address
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_get_ipv4_src(struct rtnl_cls *cls, in_addr_t *out_addr,
+ in_addr_t *out_mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
+ return -NLE_INVAL;
+
+ if (!(f->cf_mask & FLOWER_ATTR_IPV4_SRC))
+ return -NLE_MISSING_ATTR;
+
+ if (out_addr)
+ *out_addr = f->cf_ipv4_src;
+
+ if (out_mask) {
+ if (f->cf_mask & FLOWER_ATTR_IPV4_SRC_MASK)
+ *out_mask = f->cf_ipv4_src_mask;
+ else
+ *out_mask = 0xffffffff;
+ }
+
+ return 0;
+}
+
+/**
+ * Set IPv4 destination address for flower classifier
+ * @arg cls Flower classifier.
+ * @arg addr IPv4 destination address
+ * @arg mask mask for IPv4 destination address
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_set_ipv4_dst(struct rtnl_cls *cls, in_addr_t addr, in_addr_t mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ if (addr) {
+ f->cf_ipv4_dst = addr;
+ f->cf_mask |= FLOWER_ATTR_IPV4_DST;
+
+ if (mask) {
+ f->cf_ipv4_dst_mask = mask;
+ f->cf_mask |= FLOWER_ATTR_IPV4_DST_MASK;
+ }
+
+ return 0;
+ }
+
+ return -NLE_FAILURE;
+}
+
+/**
+ * Get IPv4 destination address for flower classifier
+ * @arg cls Flower classifier.
+ * @arg addr IPv4 destination address
+ * @arg mask mask for IPv4 destination address
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_get_ipv4_dst(struct rtnl_cls *cls, in_addr_t *out_addr,
+ in_addr_t *out_mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
+ return -NLE_INVAL;
+
+ if (!(f->cf_mask & FLOWER_ATTR_IPV4_DST))
+ return -NLE_MISSING_ATTR;
+
+ if (out_addr)
+ *out_addr = f->cf_ipv4_dst;
+
+ if (out_mask) {
+ if (f->cf_mask & FLOWER_ATTR_IPV4_DST_MASK)
+ *out_mask = f->cf_ipv4_dst_mask;
+ else
+ *out_mask = 0xffffffff;
+ }
+
+ return 0;
+}
+
+/**
* Append action for flower classifier
* @arg cls Flower classifier.
* @arg act action to append
diff --git a/libnl-route-3.sym b/libnl-route-3.sym
index 85617051..c6df91f0 100644
--- a/libnl-route-3.sym
+++ b/libnl-route-3.sym
@@ -1250,3 +1250,11 @@ global:
rtnl_route_nh_get_encap_mpls_dst;
rtnl_route_nh_get_encap_mpls_ttl;
} libnl_3_5;
+
+libnl_3_7 {
+global:
+ rtnl_flower_set_ipv4_src;
+ rtnl_flower_get_ipv4_src;
+ rtnl_flower_set_ipv4_dst;
+ rtnl_flower_get_ipv4_dst;
+} libnl_3_6;