diff options
author | Volodymyr Bendiuga <volodymyr.bendiuga@westermo.com> | 2022-04-19 14:51:34 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2022-05-27 09:41:29 +0200 |
commit | f8eb2185656e7e224deb10666b7f3108e58e2acd (patch) | |
tree | 4348f4cc632d74109c66c6c83787d9c7917c8510 | |
parent | e5dc111f8c9c646b1fca3f3aabaa00165952b89c (diff) | |
download | libnl-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.h | 6 | ||||
-rw-r--r-- | include/netlink/route/cls/flower.h | 9 | ||||
-rw-r--r-- | lib/route/cls/flower.c | 174 | ||||
-rw-r--r-- | libnl-route-3.sym | 8 |
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; |