1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker * Copyright (c) 2018 Volodymyr Bendiuga <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker */
5*4dc78e53SAndroid Build Coastguard Worker
6*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
7*4dc78e53SAndroid Build Coastguard Worker
8*4dc78e53SAndroid Build Coastguard Worker #include <linux/ethtool.h>
9*4dc78e53SAndroid Build Coastguard Worker
10*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
11*4dc78e53SAndroid Build Coastguard Worker #include <netlink/attr.h>
12*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
13*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/classifier.h>
14*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/action.h>
15*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/cls/flower.h>
16*4dc78e53SAndroid Build Coastguard Worker
17*4dc78e53SAndroid Build Coastguard Worker #include "tc-api.h"
18*4dc78e53SAndroid Build Coastguard Worker #include "nl-aux-route/nl-route.h"
19*4dc78e53SAndroid Build Coastguard Worker
20*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
21*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower {
22*4dc78e53SAndroid Build Coastguard Worker struct rtnl_act *cf_act;
23*4dc78e53SAndroid Build Coastguard Worker int cf_mask;
24*4dc78e53SAndroid Build Coastguard Worker uint32_t cf_flags;
25*4dc78e53SAndroid Build Coastguard Worker uint16_t cf_proto;
26*4dc78e53SAndroid Build Coastguard Worker uint16_t cf_vlan_id;
27*4dc78e53SAndroid Build Coastguard Worker uint16_t cf_vlan_ethtype;
28*4dc78e53SAndroid Build Coastguard Worker uint8_t cf_vlan_prio;
29*4dc78e53SAndroid Build Coastguard Worker uint8_t cf_src_mac[ETH_ALEN];
30*4dc78e53SAndroid Build Coastguard Worker uint8_t cf_src_mac_mask[ETH_ALEN];
31*4dc78e53SAndroid Build Coastguard Worker uint8_t cf_dst_mac[ETH_ALEN];
32*4dc78e53SAndroid Build Coastguard Worker uint8_t cf_dst_mac_mask[ETH_ALEN];
33*4dc78e53SAndroid Build Coastguard Worker in_addr_t cf_ipv4_src;
34*4dc78e53SAndroid Build Coastguard Worker in_addr_t cf_ipv4_src_mask;
35*4dc78e53SAndroid Build Coastguard Worker in_addr_t cf_ipv4_dst;
36*4dc78e53SAndroid Build Coastguard Worker in_addr_t cf_ipv4_dst_mask;
37*4dc78e53SAndroid Build Coastguard Worker uint8_t cf_ip_dscp;
38*4dc78e53SAndroid Build Coastguard Worker uint8_t cf_ip_dscp_mask;
39*4dc78e53SAndroid Build Coastguard Worker };
40*4dc78e53SAndroid Build Coastguard Worker
41*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_FLAGS (1 << 0)
42*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_ACTION (1 << 1)
43*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_VLAN_ID (1 << 2)
44*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_VLAN_PRIO (1 << 3)
45*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_VLAN_ETH_TYPE (1 << 4)
46*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_DST_MAC (1 << 5)
47*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_DST_MAC_MASK (1 << 6)
48*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_SRC_MAC (1 << 7)
49*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_SRC_MAC_MASK (1 << 8)
50*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_IP_DSCP (1 << 9)
51*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_IP_DSCP_MASK (1 << 10)
52*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_PROTO (1 << 11)
53*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_IPV4_SRC (1 << 12)
54*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_IPV4_SRC_MASK (1 << 13)
55*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_IPV4_DST (1 << 14)
56*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_ATTR_IPV4_DST_MASK (1 << 15)
57*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
58*4dc78e53SAndroid Build Coastguard Worker
59*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_DSCP_MAX 0xe0
60*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_DSCP_MASK_MAX 0xe0
61*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_VID_MAX 4095
62*4dc78e53SAndroid Build Coastguard Worker #define FLOWER_VLAN_PRIO_MAX 7
63*4dc78e53SAndroid Build Coastguard Worker
64*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy flower_policy[TCA_FLOWER_MAX + 1] = {
65*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_FLAGS] = { .type = NLA_U32 },
66*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_ETH_TYPE] = { .type = NLA_U16 },
67*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_ETH_DST] = { .maxlen = ETH_ALEN },
68*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_ETH_DST_MASK] = { .maxlen = ETH_ALEN },
69*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_ETH_SRC] = { .maxlen = ETH_ALEN },
70*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_ETH_SRC_MASK] = { .maxlen = ETH_ALEN },
71*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_VLAN_ID] = { .type = NLA_U16 },
72*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_VLAN_PRIO] = { .type = NLA_U8 },
73*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_IP_TOS] = { .type = NLA_U8 },
74*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_IP_TOS_MASK] = { .type = NLA_U8 },
75*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_VLAN_ETH_TYPE] = { .type = NLA_U16 },
76*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_IPV4_SRC] = { .type = NLA_U32 },
77*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_IPV4_SRC_MASK] = { .type = NLA_U32 },
78*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_IPV4_DST] = { .type = NLA_U32 },
79*4dc78e53SAndroid Build Coastguard Worker [TCA_FLOWER_KEY_IPV4_DST_MASK] = { .type = NLA_U32 },
80*4dc78e53SAndroid Build Coastguard Worker };
81*4dc78e53SAndroid Build Coastguard Worker
flower_msg_parser(struct rtnl_tc * tc,void * data)82*4dc78e53SAndroid Build Coastguard Worker static int flower_msg_parser(struct rtnl_tc *tc, void *data)
83*4dc78e53SAndroid Build Coastguard Worker {
84*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f = data;
85*4dc78e53SAndroid Build Coastguard Worker struct nlattr *tb[TCA_FLOWER_MAX + 1];
86*4dc78e53SAndroid Build Coastguard Worker int err;
87*4dc78e53SAndroid Build Coastguard Worker
88*4dc78e53SAndroid Build Coastguard Worker err = tca_parse(tb, TCA_FLOWER_MAX, tc, flower_policy);
89*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
90*4dc78e53SAndroid Build Coastguard Worker return err;
91*4dc78e53SAndroid Build Coastguard Worker
92*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_FLAGS]) {
93*4dc78e53SAndroid Build Coastguard Worker f->cf_flags = nla_get_u32(tb[TCA_FLOWER_FLAGS]);
94*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_FLAGS;
95*4dc78e53SAndroid Build Coastguard Worker }
96*4dc78e53SAndroid Build Coastguard Worker
97*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_ACT]) {
98*4dc78e53SAndroid Build Coastguard Worker err = rtnl_act_parse(&f->cf_act, tb[TCA_FLOWER_ACT]);
99*4dc78e53SAndroid Build Coastguard Worker if (err)
100*4dc78e53SAndroid Build Coastguard Worker return err;
101*4dc78e53SAndroid Build Coastguard Worker
102*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_ACTION;
103*4dc78e53SAndroid Build Coastguard Worker }
104*4dc78e53SAndroid Build Coastguard Worker
105*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_ETH_TYPE]) {
106*4dc78e53SAndroid Build Coastguard Worker f->cf_proto = nla_get_u16(tb[TCA_FLOWER_KEY_ETH_TYPE]);
107*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_PROTO;
108*4dc78e53SAndroid Build Coastguard Worker }
109*4dc78e53SAndroid Build Coastguard Worker
110*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_VLAN_ID]) {
111*4dc78e53SAndroid Build Coastguard Worker f->cf_vlan_id = nla_get_u16(tb[TCA_FLOWER_KEY_VLAN_ID]);
112*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_VLAN_ID;
113*4dc78e53SAndroid Build Coastguard Worker }
114*4dc78e53SAndroid Build Coastguard Worker
115*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) {
116*4dc78e53SAndroid Build Coastguard Worker f->cf_vlan_prio = nla_get_u8(tb[TCA_FLOWER_KEY_VLAN_PRIO]);
117*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_VLAN_PRIO;
118*4dc78e53SAndroid Build Coastguard Worker }
119*4dc78e53SAndroid Build Coastguard Worker
120*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) {
121*4dc78e53SAndroid Build Coastguard Worker f->cf_vlan_ethtype = nla_get_u16(tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]);
122*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_VLAN_ETH_TYPE;
123*4dc78e53SAndroid Build Coastguard Worker }
124*4dc78e53SAndroid Build Coastguard Worker
125*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_ETH_DST]) {
126*4dc78e53SAndroid Build Coastguard Worker nla_memcpy(f->cf_dst_mac, tb[TCA_FLOWER_KEY_ETH_DST], ETH_ALEN);
127*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_DST_MAC;
128*4dc78e53SAndroid Build Coastguard Worker }
129*4dc78e53SAndroid Build Coastguard Worker
130*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_ETH_DST_MASK]) {
131*4dc78e53SAndroid Build Coastguard Worker nla_memcpy(f->cf_dst_mac_mask, tb[TCA_FLOWER_KEY_ETH_DST_MASK], ETH_ALEN);
132*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_DST_MAC_MASK;
133*4dc78e53SAndroid Build Coastguard Worker }
134*4dc78e53SAndroid Build Coastguard Worker
135*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_ETH_SRC]) {
136*4dc78e53SAndroid Build Coastguard Worker nla_memcpy(f->cf_src_mac, tb[TCA_FLOWER_KEY_ETH_SRC], ETH_ALEN);
137*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_SRC_MAC;
138*4dc78e53SAndroid Build Coastguard Worker }
139*4dc78e53SAndroid Build Coastguard Worker
140*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_ETH_SRC_MASK]) {
141*4dc78e53SAndroid Build Coastguard Worker nla_memcpy(f->cf_src_mac_mask, tb[TCA_FLOWER_KEY_ETH_SRC_MASK], ETH_ALEN);
142*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_SRC_MAC_MASK;
143*4dc78e53SAndroid Build Coastguard Worker }
144*4dc78e53SAndroid Build Coastguard Worker
145*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_IP_TOS]) {
146*4dc78e53SAndroid Build Coastguard Worker f->cf_ip_dscp = nla_get_u8(tb[TCA_FLOWER_KEY_IP_TOS]);
147*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_IP_DSCP;
148*4dc78e53SAndroid Build Coastguard Worker }
149*4dc78e53SAndroid Build Coastguard Worker
150*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_IP_TOS_MASK]) {
151*4dc78e53SAndroid Build Coastguard Worker f->cf_ip_dscp_mask = nla_get_u8(tb[TCA_FLOWER_KEY_IP_TOS_MASK]);
152*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_IP_DSCP_MASK;
153*4dc78e53SAndroid Build Coastguard Worker }
154*4dc78e53SAndroid Build Coastguard Worker
155*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_IPV4_SRC]) {
156*4dc78e53SAndroid Build Coastguard Worker f->cf_ipv4_src = nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_SRC]);
157*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_IPV4_SRC;
158*4dc78e53SAndroid Build Coastguard Worker }
159*4dc78e53SAndroid Build Coastguard Worker
160*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_IPV4_SRC_MASK]) {
161*4dc78e53SAndroid Build Coastguard Worker f->cf_ipv4_src_mask =
162*4dc78e53SAndroid Build Coastguard Worker nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_SRC_MASK]);
163*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_IPV4_SRC_MASK;
164*4dc78e53SAndroid Build Coastguard Worker }
165*4dc78e53SAndroid Build Coastguard Worker
166*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_IPV4_DST]) {
167*4dc78e53SAndroid Build Coastguard Worker f->cf_ipv4_dst = nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_DST]);
168*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_IPV4_DST;
169*4dc78e53SAndroid Build Coastguard Worker }
170*4dc78e53SAndroid Build Coastguard Worker
171*4dc78e53SAndroid Build Coastguard Worker if (tb[TCA_FLOWER_KEY_IPV4_DST_MASK]) {
172*4dc78e53SAndroid Build Coastguard Worker f->cf_ipv4_dst_mask =
173*4dc78e53SAndroid Build Coastguard Worker nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_DST_MASK]);
174*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_IPV4_DST_MASK;
175*4dc78e53SAndroid Build Coastguard Worker }
176*4dc78e53SAndroid Build Coastguard Worker
177*4dc78e53SAndroid Build Coastguard Worker return 0;
178*4dc78e53SAndroid Build Coastguard Worker }
179*4dc78e53SAndroid Build Coastguard Worker
flower_msg_fill(struct rtnl_tc * tc,void * data,struct nl_msg * msg)180*4dc78e53SAndroid Build Coastguard Worker static int flower_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
181*4dc78e53SAndroid Build Coastguard Worker {
182*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f = data;
183*4dc78e53SAndroid Build Coastguard Worker int err;
184*4dc78e53SAndroid Build Coastguard Worker
185*4dc78e53SAndroid Build Coastguard Worker if (!f)
186*4dc78e53SAndroid Build Coastguard Worker return 0;
187*4dc78e53SAndroid Build Coastguard Worker
188*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_FLAGS)
189*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, TCA_FLOWER_FLAGS, f->cf_flags);
190*4dc78e53SAndroid Build Coastguard Worker
191*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_ACTION) {
192*4dc78e53SAndroid Build Coastguard Worker err = rtnl_act_fill(msg, TCA_FLOWER_ACT, f->cf_act);
193*4dc78e53SAndroid Build Coastguard Worker if (err)
194*4dc78e53SAndroid Build Coastguard Worker return err;
195*4dc78e53SAndroid Build Coastguard Worker }
196*4dc78e53SAndroid Build Coastguard Worker
197*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_PROTO)
198*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U16(msg, TCA_FLOWER_KEY_ETH_TYPE, f->cf_proto);
199*4dc78e53SAndroid Build Coastguard Worker
200*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_VLAN_ID)
201*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U16(msg, TCA_FLOWER_KEY_VLAN_ID, f->cf_vlan_id);
202*4dc78e53SAndroid Build Coastguard Worker
203*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_VLAN_PRIO)
204*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U8(msg, TCA_FLOWER_KEY_VLAN_PRIO, f->cf_vlan_prio);
205*4dc78e53SAndroid Build Coastguard Worker
206*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_VLAN_ETH_TYPE)
207*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U16(msg, TCA_FLOWER_KEY_VLAN_ETH_TYPE, f->cf_vlan_ethtype);
208*4dc78e53SAndroid Build Coastguard Worker
209*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_DST_MAC)
210*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, TCA_FLOWER_KEY_ETH_DST, ETH_ALEN, f->cf_dst_mac);
211*4dc78e53SAndroid Build Coastguard Worker
212*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_DST_MAC_MASK)
213*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, TCA_FLOWER_KEY_ETH_DST_MASK, ETH_ALEN, f->cf_dst_mac_mask);
214*4dc78e53SAndroid Build Coastguard Worker
215*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_SRC_MAC)
216*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, TCA_FLOWER_KEY_ETH_SRC, ETH_ALEN, f->cf_src_mac);
217*4dc78e53SAndroid Build Coastguard Worker
218*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_SRC_MAC_MASK)
219*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, TCA_FLOWER_KEY_ETH_SRC_MASK, ETH_ALEN, f->cf_src_mac_mask);
220*4dc78e53SAndroid Build Coastguard Worker
221*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_IP_DSCP)
222*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U8(msg, TCA_FLOWER_KEY_IP_TOS, f->cf_ip_dscp);
223*4dc78e53SAndroid Build Coastguard Worker
224*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_IP_DSCP_MASK)
225*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U8(msg, TCA_FLOWER_KEY_IP_TOS_MASK, f->cf_ip_dscp_mask);
226*4dc78e53SAndroid Build Coastguard Worker
227*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_IPV4_SRC)
228*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_SRC, f->cf_ipv4_src);
229*4dc78e53SAndroid Build Coastguard Worker
230*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_IPV4_SRC_MASK)
231*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_SRC_MASK,
232*4dc78e53SAndroid Build Coastguard Worker f->cf_ipv4_src_mask);
233*4dc78e53SAndroid Build Coastguard Worker
234*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_IPV4_DST)
235*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_DST, f->cf_ipv4_dst);
236*4dc78e53SAndroid Build Coastguard Worker
237*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_IPV4_DST_MASK)
238*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_DST_MASK,
239*4dc78e53SAndroid Build Coastguard Worker f->cf_ipv4_dst_mask);
240*4dc78e53SAndroid Build Coastguard Worker
241*4dc78e53SAndroid Build Coastguard Worker return 0;
242*4dc78e53SAndroid Build Coastguard Worker
243*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
244*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
245*4dc78e53SAndroid Build Coastguard Worker }
246*4dc78e53SAndroid Build Coastguard Worker
flower_free_data(struct rtnl_tc * tc,void * data)247*4dc78e53SAndroid Build Coastguard Worker static void flower_free_data(struct rtnl_tc *tc, void *data)
248*4dc78e53SAndroid Build Coastguard Worker {
249*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f = data;
250*4dc78e53SAndroid Build Coastguard Worker
251*4dc78e53SAndroid Build Coastguard Worker if (f->cf_act)
252*4dc78e53SAndroid Build Coastguard Worker rtnl_act_put_all(&f->cf_act);
253*4dc78e53SAndroid Build Coastguard Worker }
254*4dc78e53SAndroid Build Coastguard Worker
flower_clone(void * _dst,void * _src)255*4dc78e53SAndroid Build Coastguard Worker static int flower_clone(void *_dst, void *_src)
256*4dc78e53SAndroid Build Coastguard Worker {
257*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *dst = _dst, *src = _src;
258*4dc78e53SAndroid Build Coastguard Worker
259*4dc78e53SAndroid Build Coastguard Worker if (src->cf_act) {
260*4dc78e53SAndroid Build Coastguard Worker if (!(dst->cf_act = rtnl_act_alloc()))
261*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
262*4dc78e53SAndroid Build Coastguard Worker
263*4dc78e53SAndroid Build Coastguard Worker memcpy(dst->cf_act, src->cf_act, sizeof(struct rtnl_act));
264*4dc78e53SAndroid Build Coastguard Worker
265*4dc78e53SAndroid Build Coastguard Worker /* action nl list next and prev pointers must be updated */
266*4dc78e53SAndroid Build Coastguard Worker nl_init_list_head(&dst->cf_act->ce_list);
267*4dc78e53SAndroid Build Coastguard Worker
268*4dc78e53SAndroid Build Coastguard Worker if ( src->cf_act->c_opts
269*4dc78e53SAndroid Build Coastguard Worker && !(dst->cf_act->c_opts = nl_data_clone(src->cf_act->c_opts)))
270*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
271*4dc78e53SAndroid Build Coastguard Worker
272*4dc78e53SAndroid Build Coastguard Worker if ( src->cf_act->c_xstats
273*4dc78e53SAndroid Build Coastguard Worker && !(dst->cf_act->c_xstats = nl_data_clone(src->cf_act->c_xstats)))
274*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
275*4dc78e53SAndroid Build Coastguard Worker
276*4dc78e53SAndroid Build Coastguard Worker if ( src->cf_act->c_subdata
277*4dc78e53SAndroid Build Coastguard Worker && !(dst->cf_act->c_subdata = nl_data_clone(src->cf_act->c_subdata)))
278*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
279*4dc78e53SAndroid Build Coastguard Worker
280*4dc78e53SAndroid Build Coastguard Worker if (dst->cf_act->c_link) {
281*4dc78e53SAndroid Build Coastguard Worker nl_object_get(OBJ_CAST(dst->cf_act->c_link));
282*4dc78e53SAndroid Build Coastguard Worker }
283*4dc78e53SAndroid Build Coastguard Worker
284*4dc78e53SAndroid Build Coastguard Worker dst->cf_act->a_next = NULL; /* Only clone first in chain */
285*4dc78e53SAndroid Build Coastguard Worker }
286*4dc78e53SAndroid Build Coastguard Worker
287*4dc78e53SAndroid Build Coastguard Worker return 0;
288*4dc78e53SAndroid Build Coastguard Worker }
289*4dc78e53SAndroid Build Coastguard Worker
flower_dump_details(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)290*4dc78e53SAndroid Build Coastguard Worker static void flower_dump_details(struct rtnl_tc *tc, void *data,
291*4dc78e53SAndroid Build Coastguard Worker struct nl_dump_params *p)
292*4dc78e53SAndroid Build Coastguard Worker {
293*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f = data;
294*4dc78e53SAndroid Build Coastguard Worker char addr_str[INET_ADDRSTRLEN];
295*4dc78e53SAndroid Build Coastguard Worker char mask_str[INET_ADDRSTRLEN];
296*4dc78e53SAndroid Build Coastguard Worker
297*4dc78e53SAndroid Build Coastguard Worker if (!f)
298*4dc78e53SAndroid Build Coastguard Worker return;
299*4dc78e53SAndroid Build Coastguard Worker
300*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_FLAGS)
301*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " flags %u", f->cf_flags);
302*4dc78e53SAndroid Build Coastguard Worker
303*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_PROTO)
304*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " protocol %u", f->cf_proto);
305*4dc78e53SAndroid Build Coastguard Worker
306*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_VLAN_ID)
307*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " vlan_id %u", f->cf_vlan_id);
308*4dc78e53SAndroid Build Coastguard Worker
309*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_VLAN_PRIO)
310*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " vlan_prio %u", f->cf_vlan_prio);
311*4dc78e53SAndroid Build Coastguard Worker
312*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_VLAN_ETH_TYPE)
313*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " vlan_ethtype %u", f->cf_vlan_ethtype);
314*4dc78e53SAndroid Build Coastguard Worker
315*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_DST_MAC)
316*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " dst_mac %02x:%02x:%02x:%02x:%02x:%02x",
317*4dc78e53SAndroid Build Coastguard Worker f->cf_dst_mac[0], f->cf_dst_mac[1],
318*4dc78e53SAndroid Build Coastguard Worker f->cf_dst_mac[2], f->cf_dst_mac[3],
319*4dc78e53SAndroid Build Coastguard Worker f->cf_dst_mac[4], f->cf_dst_mac[5]);
320*4dc78e53SAndroid Build Coastguard Worker
321*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_DST_MAC_MASK)
322*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " dst_mac_mask %02x:%02x:%02x:%02x:%02x:%02x",
323*4dc78e53SAndroid Build Coastguard Worker f->cf_dst_mac_mask[0], f->cf_dst_mac_mask[1],
324*4dc78e53SAndroid Build Coastguard Worker f->cf_dst_mac_mask[2], f->cf_dst_mac_mask[3],
325*4dc78e53SAndroid Build Coastguard Worker f->cf_dst_mac_mask[4], f->cf_dst_mac_mask[5]);
326*4dc78e53SAndroid Build Coastguard Worker
327*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_SRC_MAC)
328*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " src_mac %02x:%02x:%02x:%02x:%02x:%02x",
329*4dc78e53SAndroid Build Coastguard Worker f->cf_src_mac[0], f->cf_src_mac[1],
330*4dc78e53SAndroid Build Coastguard Worker f->cf_src_mac[2], f->cf_src_mac[3],
331*4dc78e53SAndroid Build Coastguard Worker f->cf_src_mac[4], f->cf_src_mac[5]);
332*4dc78e53SAndroid Build Coastguard Worker
333*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_SRC_MAC_MASK)
334*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " src_mac_mask %02x:%02x:%02x:%02x:%02x:%02x",
335*4dc78e53SAndroid Build Coastguard Worker f->cf_src_mac_mask[0], f->cf_src_mac_mask[1],
336*4dc78e53SAndroid Build Coastguard Worker f->cf_src_mac_mask[2], f->cf_src_mac_mask[3],
337*4dc78e53SAndroid Build Coastguard Worker f->cf_src_mac_mask[4], f->cf_src_mac_mask[5]);
338*4dc78e53SAndroid Build Coastguard Worker
339*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_IP_DSCP)
340*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " dscp %u", f->cf_ip_dscp);
341*4dc78e53SAndroid Build Coastguard Worker
342*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_IP_DSCP_MASK)
343*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " dscp_mask %u", f->cf_ip_dscp_mask);
344*4dc78e53SAndroid Build Coastguard Worker
345*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_IPV4_SRC) {
346*4dc78e53SAndroid Build Coastguard Worker inet_ntop(AF_INET, &f->cf_ipv4_src, addr_str, sizeof(addr_str));
347*4dc78e53SAndroid Build Coastguard Worker inet_ntop(AF_INET, &f->cf_ipv4_src_mask, mask_str, sizeof(mask_str));
348*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "IPv4 src %s mask %s\n", addr_str, mask_str);
349*4dc78e53SAndroid Build Coastguard Worker }
350*4dc78e53SAndroid Build Coastguard Worker
351*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_IPV4_DST) {
352*4dc78e53SAndroid Build Coastguard Worker inet_ntop(AF_INET, &f->cf_ipv4_dst, addr_str, sizeof(addr_str));
353*4dc78e53SAndroid Build Coastguard Worker inet_ntop(AF_INET, &f->cf_ipv4_dst_mask, mask_str, sizeof(mask_str));
354*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "IPv4 dst %s mask %s\n", addr_str, mask_str);
355*4dc78e53SAndroid Build Coastguard Worker }
356*4dc78e53SAndroid Build Coastguard Worker }
357*4dc78e53SAndroid Build Coastguard Worker
358*4dc78e53SAndroid Build Coastguard Worker /**
359*4dc78e53SAndroid Build Coastguard Worker * @name Attribute Modification
360*4dc78e53SAndroid Build Coastguard Worker * @{
361*4dc78e53SAndroid Build Coastguard Worker */
362*4dc78e53SAndroid Build Coastguard Worker
363*4dc78e53SAndroid Build Coastguard Worker /**
364*4dc78e53SAndroid Build Coastguard Worker * Set protocol for flower classifier
365*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
366*4dc78e53SAndroid Build Coastguard Worker * @arg proto protocol (ETH_P_*)
367*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
368*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_set_proto(struct rtnl_cls * cls,uint16_t proto)369*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_set_proto(struct rtnl_cls *cls, uint16_t proto)
370*4dc78e53SAndroid Build Coastguard Worker {
371*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
372*4dc78e53SAndroid Build Coastguard Worker
373*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
374*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
375*4dc78e53SAndroid Build Coastguard Worker
376*4dc78e53SAndroid Build Coastguard Worker f->cf_proto = htons(proto);
377*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_PROTO;
378*4dc78e53SAndroid Build Coastguard Worker
379*4dc78e53SAndroid Build Coastguard Worker return 0;
380*4dc78e53SAndroid Build Coastguard Worker }
381*4dc78e53SAndroid Build Coastguard Worker
382*4dc78e53SAndroid Build Coastguard Worker /**
383*4dc78e53SAndroid Build Coastguard Worker * Get protocol for flower classifier
384*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
385*4dc78e53SAndroid Build Coastguard Worker * @arg proto protocol
386*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
387*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_get_proto(struct rtnl_cls * cls,uint16_t * proto)388*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_get_proto(struct rtnl_cls *cls, uint16_t *proto)
389*4dc78e53SAndroid Build Coastguard Worker {
390*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
391*4dc78e53SAndroid Build Coastguard Worker
392*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
393*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
394*4dc78e53SAndroid Build Coastguard Worker
395*4dc78e53SAndroid Build Coastguard Worker if (!(f->cf_mask & FLOWER_ATTR_PROTO))
396*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
397*4dc78e53SAndroid Build Coastguard Worker
398*4dc78e53SAndroid Build Coastguard Worker *proto = ntohs(f->cf_proto);
399*4dc78e53SAndroid Build Coastguard Worker
400*4dc78e53SAndroid Build Coastguard Worker return 0;
401*4dc78e53SAndroid Build Coastguard Worker }
402*4dc78e53SAndroid Build Coastguard Worker
403*4dc78e53SAndroid Build Coastguard Worker /**
404*4dc78e53SAndroid Build Coastguard Worker * Set vlan id for flower classifier
405*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
406*4dc78e53SAndroid Build Coastguard Worker * @arg vid vlan id
407*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
408*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_set_vlan_id(struct rtnl_cls * cls,uint16_t vid)409*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_set_vlan_id(struct rtnl_cls *cls, uint16_t vid)
410*4dc78e53SAndroid Build Coastguard Worker {
411*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
412*4dc78e53SAndroid Build Coastguard Worker
413*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
414*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
415*4dc78e53SAndroid Build Coastguard Worker
416*4dc78e53SAndroid Build Coastguard Worker if (vid > FLOWER_VID_MAX)
417*4dc78e53SAndroid Build Coastguard Worker return -NLE_RANGE;
418*4dc78e53SAndroid Build Coastguard Worker
419*4dc78e53SAndroid Build Coastguard Worker f->cf_vlan_id = vid;
420*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_VLAN_ID;
421*4dc78e53SAndroid Build Coastguard Worker
422*4dc78e53SAndroid Build Coastguard Worker return 0;
423*4dc78e53SAndroid Build Coastguard Worker }
424*4dc78e53SAndroid Build Coastguard Worker
425*4dc78e53SAndroid Build Coastguard Worker /**
426*4dc78e53SAndroid Build Coastguard Worker * Get vlan id for flower classifier
427*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
428*4dc78e53SAndroid Build Coastguard Worker * @arg vid vlan id
429*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
430*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_get_vlan_id(struct rtnl_cls * cls,uint16_t * vid)431*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_get_vlan_id(struct rtnl_cls *cls, uint16_t *vid)
432*4dc78e53SAndroid Build Coastguard Worker {
433*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
434*4dc78e53SAndroid Build Coastguard Worker
435*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
436*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
437*4dc78e53SAndroid Build Coastguard Worker
438*4dc78e53SAndroid Build Coastguard Worker if (!(f->cf_mask & FLOWER_ATTR_VLAN_ID))
439*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
440*4dc78e53SAndroid Build Coastguard Worker
441*4dc78e53SAndroid Build Coastguard Worker *vid = f->cf_vlan_id;
442*4dc78e53SAndroid Build Coastguard Worker
443*4dc78e53SAndroid Build Coastguard Worker return 0;
444*4dc78e53SAndroid Build Coastguard Worker }
445*4dc78e53SAndroid Build Coastguard Worker
446*4dc78e53SAndroid Build Coastguard Worker /**
447*4dc78e53SAndroid Build Coastguard Worker * Set vlan priority for flower classifier
448*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
449*4dc78e53SAndroid Build Coastguard Worker * @arg prio vlan priority
450*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
451*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_set_vlan_prio(struct rtnl_cls * cls,uint8_t prio)452*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_set_vlan_prio(struct rtnl_cls *cls, uint8_t prio)
453*4dc78e53SAndroid Build Coastguard Worker {
454*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
455*4dc78e53SAndroid Build Coastguard Worker
456*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
457*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
458*4dc78e53SAndroid Build Coastguard Worker
459*4dc78e53SAndroid Build Coastguard Worker if (prio > FLOWER_VLAN_PRIO_MAX)
460*4dc78e53SAndroid Build Coastguard Worker return -NLE_RANGE;
461*4dc78e53SAndroid Build Coastguard Worker
462*4dc78e53SAndroid Build Coastguard Worker f->cf_vlan_prio = prio;
463*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_VLAN_PRIO;
464*4dc78e53SAndroid Build Coastguard Worker
465*4dc78e53SAndroid Build Coastguard Worker return 0;
466*4dc78e53SAndroid Build Coastguard Worker }
467*4dc78e53SAndroid Build Coastguard Worker
468*4dc78e53SAndroid Build Coastguard Worker /**
469*4dc78e53SAndroid Build Coastguard Worker * Get vlan prio for flower classifier
470*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
471*4dc78e53SAndroid Build Coastguard Worker * @arg prio vlan priority
472*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
473*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_get_vlan_prio(struct rtnl_cls * cls,uint8_t * prio)474*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_get_vlan_prio(struct rtnl_cls *cls, uint8_t *prio)
475*4dc78e53SAndroid Build Coastguard Worker {
476*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
477*4dc78e53SAndroid Build Coastguard Worker
478*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
479*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
480*4dc78e53SAndroid Build Coastguard Worker
481*4dc78e53SAndroid Build Coastguard Worker if (!(f->cf_mask & FLOWER_ATTR_VLAN_PRIO))
482*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
483*4dc78e53SAndroid Build Coastguard Worker
484*4dc78e53SAndroid Build Coastguard Worker *prio = f->cf_vlan_prio;
485*4dc78e53SAndroid Build Coastguard Worker
486*4dc78e53SAndroid Build Coastguard Worker return 0;
487*4dc78e53SAndroid Build Coastguard Worker }
488*4dc78e53SAndroid Build Coastguard Worker
489*4dc78e53SAndroid Build Coastguard Worker /**
490*4dc78e53SAndroid Build Coastguard Worker * Set vlan ethertype for flower classifier
491*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
492*4dc78e53SAndroid Build Coastguard Worker * @arg ethtype vlan ethertype
493*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
494*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_set_vlan_ethtype(struct rtnl_cls * cls,uint16_t ethtype)495*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_set_vlan_ethtype(struct rtnl_cls *cls, uint16_t ethtype)
496*4dc78e53SAndroid Build Coastguard Worker {
497*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
498*4dc78e53SAndroid Build Coastguard Worker
499*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
500*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
501*4dc78e53SAndroid Build Coastguard Worker
502*4dc78e53SAndroid Build Coastguard Worker if (!(f->cf_mask & FLOWER_ATTR_PROTO))
503*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
504*4dc78e53SAndroid Build Coastguard Worker
505*4dc78e53SAndroid Build Coastguard Worker if (f->cf_proto != htons(ETH_P_8021Q))
506*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
507*4dc78e53SAndroid Build Coastguard Worker
508*4dc78e53SAndroid Build Coastguard Worker f->cf_vlan_ethtype = htons(ethtype);
509*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_VLAN_ETH_TYPE;
510*4dc78e53SAndroid Build Coastguard Worker
511*4dc78e53SAndroid Build Coastguard Worker return 0;
512*4dc78e53SAndroid Build Coastguard Worker }
513*4dc78e53SAndroid Build Coastguard Worker
514*4dc78e53SAndroid Build Coastguard Worker /**
515*4dc78e53SAndroid Build Coastguard Worker * Set destination mac address for flower classifier
516*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
517*4dc78e53SAndroid Build Coastguard Worker * @arg mac destination mac address
518*4dc78e53SAndroid Build Coastguard Worker * @arg mask mask for mac address
519*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
520*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_set_dst_mac(struct rtnl_cls * cls,unsigned char * mac,unsigned char * mask)521*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_set_dst_mac(struct rtnl_cls *cls, unsigned char *mac,
522*4dc78e53SAndroid Build Coastguard Worker unsigned char *mask)
523*4dc78e53SAndroid Build Coastguard Worker {
524*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
525*4dc78e53SAndroid Build Coastguard Worker
526*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
527*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
528*4dc78e53SAndroid Build Coastguard Worker
529*4dc78e53SAndroid Build Coastguard Worker if (mac) {
530*4dc78e53SAndroid Build Coastguard Worker memcpy(f->cf_dst_mac, mac, ETH_ALEN);
531*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_DST_MAC;
532*4dc78e53SAndroid Build Coastguard Worker
533*4dc78e53SAndroid Build Coastguard Worker if (mask) {
534*4dc78e53SAndroid Build Coastguard Worker memcpy(f->cf_dst_mac_mask, mask, ETH_ALEN);
535*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_DST_MAC_MASK;
536*4dc78e53SAndroid Build Coastguard Worker }
537*4dc78e53SAndroid Build Coastguard Worker
538*4dc78e53SAndroid Build Coastguard Worker return 0;
539*4dc78e53SAndroid Build Coastguard Worker }
540*4dc78e53SAndroid Build Coastguard Worker
541*4dc78e53SAndroid Build Coastguard Worker return -NLE_FAILURE;
542*4dc78e53SAndroid Build Coastguard Worker }
543*4dc78e53SAndroid Build Coastguard Worker
544*4dc78e53SAndroid Build Coastguard Worker /**
545*4dc78e53SAndroid Build Coastguard Worker * Get destination mac address for flower classifier
546*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
547*4dc78e53SAndroid Build Coastguard Worker * @arg mac destination mac address
548*4dc78e53SAndroid Build Coastguard Worker * @arg mask mask for mac address
549*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
550*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_get_dst_mac(struct rtnl_cls * cls,unsigned char * mac,unsigned char * mask)551*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_get_dst_mac(struct rtnl_cls *cls, unsigned char *mac,
552*4dc78e53SAndroid Build Coastguard Worker unsigned char *mask)
553*4dc78e53SAndroid Build Coastguard Worker {
554*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
555*4dc78e53SAndroid Build Coastguard Worker
556*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
557*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
558*4dc78e53SAndroid Build Coastguard Worker
559*4dc78e53SAndroid Build Coastguard Worker if (!(f->cf_mask & FLOWER_ATTR_DST_MAC))
560*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
561*4dc78e53SAndroid Build Coastguard Worker
562*4dc78e53SAndroid Build Coastguard Worker if (mac)
563*4dc78e53SAndroid Build Coastguard Worker memcpy(mac, f->cf_dst_mac, ETH_ALEN);
564*4dc78e53SAndroid Build Coastguard Worker
565*4dc78e53SAndroid Build Coastguard Worker if (mask)
566*4dc78e53SAndroid Build Coastguard Worker memcpy(mask, f->cf_dst_mac_mask, ETH_ALEN);
567*4dc78e53SAndroid Build Coastguard Worker
568*4dc78e53SAndroid Build Coastguard Worker return 0;
569*4dc78e53SAndroid Build Coastguard Worker }
570*4dc78e53SAndroid Build Coastguard Worker
571*4dc78e53SAndroid Build Coastguard Worker /**
572*4dc78e53SAndroid Build Coastguard Worker * Set source mac address for flower classifier
573*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
574*4dc78e53SAndroid Build Coastguard Worker * @arg mac source mac address
575*4dc78e53SAndroid Build Coastguard Worker * @arg mask mask for mac address
576*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
577*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_set_src_mac(struct rtnl_cls * cls,unsigned char * mac,unsigned char * mask)578*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_set_src_mac(struct rtnl_cls *cls, unsigned char *mac,
579*4dc78e53SAndroid Build Coastguard Worker unsigned char *mask)
580*4dc78e53SAndroid Build Coastguard Worker {
581*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
582*4dc78e53SAndroid Build Coastguard Worker
583*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
584*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
585*4dc78e53SAndroid Build Coastguard Worker
586*4dc78e53SAndroid Build Coastguard Worker if (mac) {
587*4dc78e53SAndroid Build Coastguard Worker memcpy(f->cf_src_mac, mac, ETH_ALEN);
588*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_SRC_MAC;
589*4dc78e53SAndroid Build Coastguard Worker
590*4dc78e53SAndroid Build Coastguard Worker if (mask) {
591*4dc78e53SAndroid Build Coastguard Worker memcpy(f->cf_src_mac_mask, mask, ETH_ALEN);
592*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_SRC_MAC_MASK;
593*4dc78e53SAndroid Build Coastguard Worker }
594*4dc78e53SAndroid Build Coastguard Worker
595*4dc78e53SAndroid Build Coastguard Worker return 0;
596*4dc78e53SAndroid Build Coastguard Worker }
597*4dc78e53SAndroid Build Coastguard Worker
598*4dc78e53SAndroid Build Coastguard Worker return -NLE_FAILURE;
599*4dc78e53SAndroid Build Coastguard Worker }
600*4dc78e53SAndroid Build Coastguard Worker
601*4dc78e53SAndroid Build Coastguard Worker /**
602*4dc78e53SAndroid Build Coastguard Worker * Get source mac address for flower classifier
603*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
604*4dc78e53SAndroid Build Coastguard Worker * @arg mac source mac address
605*4dc78e53SAndroid Build Coastguard Worker * @arg mask mask for mac address
606*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
607*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_get_src_mac(struct rtnl_cls * cls,unsigned char * mac,unsigned char * mask)608*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_get_src_mac(struct rtnl_cls *cls, unsigned char *mac,
609*4dc78e53SAndroid Build Coastguard Worker unsigned char *mask)
610*4dc78e53SAndroid Build Coastguard Worker {
611*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
612*4dc78e53SAndroid Build Coastguard Worker
613*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
614*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
615*4dc78e53SAndroid Build Coastguard Worker
616*4dc78e53SAndroid Build Coastguard Worker if (!(f->cf_mask & FLOWER_ATTR_SRC_MAC))
617*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
618*4dc78e53SAndroid Build Coastguard Worker
619*4dc78e53SAndroid Build Coastguard Worker if (mac)
620*4dc78e53SAndroid Build Coastguard Worker memcpy(mac, f->cf_src_mac, ETH_ALEN);
621*4dc78e53SAndroid Build Coastguard Worker
622*4dc78e53SAndroid Build Coastguard Worker if (mask)
623*4dc78e53SAndroid Build Coastguard Worker memcpy(mask, f->cf_src_mac_mask, ETH_ALEN);
624*4dc78e53SAndroid Build Coastguard Worker
625*4dc78e53SAndroid Build Coastguard Worker return 0;
626*4dc78e53SAndroid Build Coastguard Worker }
627*4dc78e53SAndroid Build Coastguard Worker
628*4dc78e53SAndroid Build Coastguard Worker /**
629*4dc78e53SAndroid Build Coastguard Worker * Set dscp value for flower classifier
630*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
631*4dc78e53SAndroid Build Coastguard Worker * @arg dscp dscp value
632*4dc78e53SAndroid Build Coastguard Worker * @arg mask mask for dscp value
633*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
634*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_set_ip_dscp(struct rtnl_cls * cls,uint8_t dscp,uint8_t mask)635*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_set_ip_dscp(struct rtnl_cls *cls, uint8_t dscp, uint8_t mask)
636*4dc78e53SAndroid Build Coastguard Worker {
637*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
638*4dc78e53SAndroid Build Coastguard Worker
639*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
640*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
641*4dc78e53SAndroid Build Coastguard Worker
642*4dc78e53SAndroid Build Coastguard Worker if (dscp > FLOWER_DSCP_MAX)
643*4dc78e53SAndroid Build Coastguard Worker return -NLE_RANGE;
644*4dc78e53SAndroid Build Coastguard Worker
645*4dc78e53SAndroid Build Coastguard Worker if (mask > FLOWER_DSCP_MASK_MAX)
646*4dc78e53SAndroid Build Coastguard Worker return -NLE_RANGE;
647*4dc78e53SAndroid Build Coastguard Worker
648*4dc78e53SAndroid Build Coastguard Worker f->cf_ip_dscp = dscp;
649*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_IP_DSCP;
650*4dc78e53SAndroid Build Coastguard Worker
651*4dc78e53SAndroid Build Coastguard Worker if (mask) {
652*4dc78e53SAndroid Build Coastguard Worker f->cf_ip_dscp_mask = mask;
653*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_IP_DSCP_MASK;
654*4dc78e53SAndroid Build Coastguard Worker }
655*4dc78e53SAndroid Build Coastguard Worker
656*4dc78e53SAndroid Build Coastguard Worker return 0;
657*4dc78e53SAndroid Build Coastguard Worker }
658*4dc78e53SAndroid Build Coastguard Worker
659*4dc78e53SAndroid Build Coastguard Worker /**
660*4dc78e53SAndroid Build Coastguard Worker * Get dscp value for flower classifier
661*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
662*4dc78e53SAndroid Build Coastguard Worker * @arg dscp dscp value
663*4dc78e53SAndroid Build Coastguard Worker * @arg mask mask for dscp value
664*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
665*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_get_ip_dscp(struct rtnl_cls * cls,uint8_t * dscp,uint8_t * mask)666*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_get_ip_dscp(struct rtnl_cls *cls, uint8_t *dscp, uint8_t *mask)
667*4dc78e53SAndroid Build Coastguard Worker {
668*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
669*4dc78e53SAndroid Build Coastguard Worker
670*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
671*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
672*4dc78e53SAndroid Build Coastguard Worker
673*4dc78e53SAndroid Build Coastguard Worker if (!(f->cf_mask & FLOWER_ATTR_IP_DSCP))
674*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
675*4dc78e53SAndroid Build Coastguard Worker
676*4dc78e53SAndroid Build Coastguard Worker *dscp = f->cf_ip_dscp;
677*4dc78e53SAndroid Build Coastguard Worker *mask = f->cf_ip_dscp_mask;
678*4dc78e53SAndroid Build Coastguard Worker
679*4dc78e53SAndroid Build Coastguard Worker return 0;
680*4dc78e53SAndroid Build Coastguard Worker }
681*4dc78e53SAndroid Build Coastguard Worker
682*4dc78e53SAndroid Build Coastguard Worker /**
683*4dc78e53SAndroid Build Coastguard Worker * Set IPv4 source address for flower classifier
684*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
685*4dc78e53SAndroid Build Coastguard Worker * @arg addr IPv4 source address
686*4dc78e53SAndroid Build Coastguard Worker * @arg mask mask for IPv4 source address
687*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
688*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_set_ipv4_src(struct rtnl_cls * cls,in_addr_t addr,in_addr_t mask)689*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_set_ipv4_src(struct rtnl_cls *cls, in_addr_t addr,
690*4dc78e53SAndroid Build Coastguard Worker in_addr_t mask)
691*4dc78e53SAndroid Build Coastguard Worker {
692*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
693*4dc78e53SAndroid Build Coastguard Worker
694*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
695*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
696*4dc78e53SAndroid Build Coastguard Worker
697*4dc78e53SAndroid Build Coastguard Worker if (addr) {
698*4dc78e53SAndroid Build Coastguard Worker f->cf_ipv4_src = addr;
699*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_IPV4_SRC;
700*4dc78e53SAndroid Build Coastguard Worker
701*4dc78e53SAndroid Build Coastguard Worker if (mask) {
702*4dc78e53SAndroid Build Coastguard Worker f->cf_ipv4_src_mask = mask;
703*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_IPV4_SRC_MASK;
704*4dc78e53SAndroid Build Coastguard Worker }
705*4dc78e53SAndroid Build Coastguard Worker
706*4dc78e53SAndroid Build Coastguard Worker return 0;
707*4dc78e53SAndroid Build Coastguard Worker }
708*4dc78e53SAndroid Build Coastguard Worker
709*4dc78e53SAndroid Build Coastguard Worker return -NLE_FAILURE;
710*4dc78e53SAndroid Build Coastguard Worker }
711*4dc78e53SAndroid Build Coastguard Worker
712*4dc78e53SAndroid Build Coastguard Worker /**
713*4dc78e53SAndroid Build Coastguard Worker * Get IPv4 source address for flower classifier
714*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
715*4dc78e53SAndroid Build Coastguard Worker * @arg addr IPv4 source address
716*4dc78e53SAndroid Build Coastguard Worker * @arg mask mask for IPv4 source address
717*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
718*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_get_ipv4_src(struct rtnl_cls * cls,in_addr_t * out_addr,in_addr_t * out_mask)719*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_get_ipv4_src(struct rtnl_cls *cls, in_addr_t *out_addr,
720*4dc78e53SAndroid Build Coastguard Worker in_addr_t *out_mask)
721*4dc78e53SAndroid Build Coastguard Worker {
722*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
723*4dc78e53SAndroid Build Coastguard Worker
724*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
725*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
726*4dc78e53SAndroid Build Coastguard Worker
727*4dc78e53SAndroid Build Coastguard Worker if (!(f->cf_mask & FLOWER_ATTR_IPV4_SRC))
728*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
729*4dc78e53SAndroid Build Coastguard Worker
730*4dc78e53SAndroid Build Coastguard Worker if (out_addr)
731*4dc78e53SAndroid Build Coastguard Worker *out_addr = f->cf_ipv4_src;
732*4dc78e53SAndroid Build Coastguard Worker
733*4dc78e53SAndroid Build Coastguard Worker if (out_mask) {
734*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_IPV4_SRC_MASK)
735*4dc78e53SAndroid Build Coastguard Worker *out_mask = f->cf_ipv4_src_mask;
736*4dc78e53SAndroid Build Coastguard Worker else
737*4dc78e53SAndroid Build Coastguard Worker *out_mask = 0xffffffff;
738*4dc78e53SAndroid Build Coastguard Worker }
739*4dc78e53SAndroid Build Coastguard Worker
740*4dc78e53SAndroid Build Coastguard Worker return 0;
741*4dc78e53SAndroid Build Coastguard Worker }
742*4dc78e53SAndroid Build Coastguard Worker
743*4dc78e53SAndroid Build Coastguard Worker /**
744*4dc78e53SAndroid Build Coastguard Worker * Set IPv4 destination address for flower classifier
745*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
746*4dc78e53SAndroid Build Coastguard Worker * @arg addr IPv4 destination address
747*4dc78e53SAndroid Build Coastguard Worker * @arg mask mask for IPv4 destination address
748*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
749*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_set_ipv4_dst(struct rtnl_cls * cls,in_addr_t addr,in_addr_t mask)750*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_set_ipv4_dst(struct rtnl_cls *cls, in_addr_t addr,
751*4dc78e53SAndroid Build Coastguard Worker in_addr_t mask)
752*4dc78e53SAndroid Build Coastguard Worker {
753*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
754*4dc78e53SAndroid Build Coastguard Worker
755*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
756*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
757*4dc78e53SAndroid Build Coastguard Worker
758*4dc78e53SAndroid Build Coastguard Worker if (addr) {
759*4dc78e53SAndroid Build Coastguard Worker f->cf_ipv4_dst = addr;
760*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_IPV4_DST;
761*4dc78e53SAndroid Build Coastguard Worker
762*4dc78e53SAndroid Build Coastguard Worker if (mask) {
763*4dc78e53SAndroid Build Coastguard Worker f->cf_ipv4_dst_mask = mask;
764*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_IPV4_DST_MASK;
765*4dc78e53SAndroid Build Coastguard Worker }
766*4dc78e53SAndroid Build Coastguard Worker
767*4dc78e53SAndroid Build Coastguard Worker return 0;
768*4dc78e53SAndroid Build Coastguard Worker }
769*4dc78e53SAndroid Build Coastguard Worker
770*4dc78e53SAndroid Build Coastguard Worker return -NLE_FAILURE;
771*4dc78e53SAndroid Build Coastguard Worker }
772*4dc78e53SAndroid Build Coastguard Worker
773*4dc78e53SAndroid Build Coastguard Worker /**
774*4dc78e53SAndroid Build Coastguard Worker * Get IPv4 destination address for flower classifier
775*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
776*4dc78e53SAndroid Build Coastguard Worker * @arg addr IPv4 destination address
777*4dc78e53SAndroid Build Coastguard Worker * @arg mask mask for IPv4 destination address
778*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
779*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_get_ipv4_dst(struct rtnl_cls * cls,in_addr_t * out_addr,in_addr_t * out_mask)780*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_get_ipv4_dst(struct rtnl_cls *cls, in_addr_t *out_addr,
781*4dc78e53SAndroid Build Coastguard Worker in_addr_t *out_mask)
782*4dc78e53SAndroid Build Coastguard Worker {
783*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
784*4dc78e53SAndroid Build Coastguard Worker
785*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
786*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
787*4dc78e53SAndroid Build Coastguard Worker
788*4dc78e53SAndroid Build Coastguard Worker if (!(f->cf_mask & FLOWER_ATTR_IPV4_DST))
789*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
790*4dc78e53SAndroid Build Coastguard Worker
791*4dc78e53SAndroid Build Coastguard Worker if (out_addr)
792*4dc78e53SAndroid Build Coastguard Worker *out_addr = f->cf_ipv4_dst;
793*4dc78e53SAndroid Build Coastguard Worker
794*4dc78e53SAndroid Build Coastguard Worker if (out_mask) {
795*4dc78e53SAndroid Build Coastguard Worker if (f->cf_mask & FLOWER_ATTR_IPV4_DST_MASK)
796*4dc78e53SAndroid Build Coastguard Worker *out_mask = f->cf_ipv4_dst_mask;
797*4dc78e53SAndroid Build Coastguard Worker else
798*4dc78e53SAndroid Build Coastguard Worker *out_mask = 0xffffffff;
799*4dc78e53SAndroid Build Coastguard Worker }
800*4dc78e53SAndroid Build Coastguard Worker
801*4dc78e53SAndroid Build Coastguard Worker return 0;
802*4dc78e53SAndroid Build Coastguard Worker }
803*4dc78e53SAndroid Build Coastguard Worker
804*4dc78e53SAndroid Build Coastguard Worker /**
805*4dc78e53SAndroid Build Coastguard Worker * Append action for flower classifier
806*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
807*4dc78e53SAndroid Build Coastguard Worker * @arg act action to append
808*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
809*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_append_action(struct rtnl_cls * cls,struct rtnl_act * act)810*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_append_action(struct rtnl_cls *cls, struct rtnl_act *act)
811*4dc78e53SAndroid Build Coastguard Worker {
812*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
813*4dc78e53SAndroid Build Coastguard Worker int err;
814*4dc78e53SAndroid Build Coastguard Worker
815*4dc78e53SAndroid Build Coastguard Worker if (!act)
816*4dc78e53SAndroid Build Coastguard Worker return 0;
817*4dc78e53SAndroid Build Coastguard Worker
818*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
819*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
820*4dc78e53SAndroid Build Coastguard Worker
821*4dc78e53SAndroid Build Coastguard Worker if ((err = _rtnl_act_append_get(&f->cf_act, act)) < 0)
822*4dc78e53SAndroid Build Coastguard Worker return err;
823*4dc78e53SAndroid Build Coastguard Worker
824*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_ACTION;
825*4dc78e53SAndroid Build Coastguard Worker return 0;
826*4dc78e53SAndroid Build Coastguard Worker }
827*4dc78e53SAndroid Build Coastguard Worker
828*4dc78e53SAndroid Build Coastguard Worker /**
829*4dc78e53SAndroid Build Coastguard Worker * Delete action from flower classifier
830*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
831*4dc78e53SAndroid Build Coastguard Worker * @arg act action to delete
832*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
833*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_del_action(struct rtnl_cls * cls,struct rtnl_act * act)834*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_del_action(struct rtnl_cls *cls, struct rtnl_act *act)
835*4dc78e53SAndroid Build Coastguard Worker {
836*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
837*4dc78e53SAndroid Build Coastguard Worker int ret;
838*4dc78e53SAndroid Build Coastguard Worker
839*4dc78e53SAndroid Build Coastguard Worker if (!act)
840*4dc78e53SAndroid Build Coastguard Worker return 0;
841*4dc78e53SAndroid Build Coastguard Worker
842*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
843*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
844*4dc78e53SAndroid Build Coastguard Worker
845*4dc78e53SAndroid Build Coastguard Worker if (!(f->cf_mask & FLOWER_ATTR_ACTION))
846*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
847*4dc78e53SAndroid Build Coastguard Worker
848*4dc78e53SAndroid Build Coastguard Worker ret = rtnl_act_remove(&f->cf_act, act);
849*4dc78e53SAndroid Build Coastguard Worker if (ret)
850*4dc78e53SAndroid Build Coastguard Worker return ret;
851*4dc78e53SAndroid Build Coastguard Worker
852*4dc78e53SAndroid Build Coastguard Worker if (!f->cf_act)
853*4dc78e53SAndroid Build Coastguard Worker f->cf_mask &= ~FLOWER_ATTR_ACTION;
854*4dc78e53SAndroid Build Coastguard Worker rtnl_act_put(act);
855*4dc78e53SAndroid Build Coastguard Worker
856*4dc78e53SAndroid Build Coastguard Worker return 0;
857*4dc78e53SAndroid Build Coastguard Worker }
858*4dc78e53SAndroid Build Coastguard Worker
859*4dc78e53SAndroid Build Coastguard Worker /**
860*4dc78e53SAndroid Build Coastguard Worker * Get action from flower classifier
861*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
862*4dc78e53SAndroid Build Coastguard Worker * @return action on success or NULL on error.
863*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_get_action(struct rtnl_cls * cls)864*4dc78e53SAndroid Build Coastguard Worker struct rtnl_act* rtnl_flower_get_action(struct rtnl_cls *cls)
865*4dc78e53SAndroid Build Coastguard Worker {
866*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
867*4dc78e53SAndroid Build Coastguard Worker
868*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
869*4dc78e53SAndroid Build Coastguard Worker return NULL;
870*4dc78e53SAndroid Build Coastguard Worker
871*4dc78e53SAndroid Build Coastguard Worker if (!(f->cf_mask & FLOWER_ATTR_ACTION))
872*4dc78e53SAndroid Build Coastguard Worker return NULL;
873*4dc78e53SAndroid Build Coastguard Worker
874*4dc78e53SAndroid Build Coastguard Worker rtnl_act_get(f->cf_act);
875*4dc78e53SAndroid Build Coastguard Worker
876*4dc78e53SAndroid Build Coastguard Worker return f->cf_act;
877*4dc78e53SAndroid Build Coastguard Worker }
878*4dc78e53SAndroid Build Coastguard Worker
879*4dc78e53SAndroid Build Coastguard Worker /**
880*4dc78e53SAndroid Build Coastguard Worker * Set flags for flower classifier
881*4dc78e53SAndroid Build Coastguard Worker * @arg cls Flower classifier.
882*4dc78e53SAndroid Build Coastguard Worker * @arg flags (TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW)
883*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
884*4dc78e53SAndroid Build Coastguard Worker */
rtnl_flower_set_flags(struct rtnl_cls * cls,int flags)885*4dc78e53SAndroid Build Coastguard Worker int rtnl_flower_set_flags(struct rtnl_cls *cls, int flags)
886*4dc78e53SAndroid Build Coastguard Worker {
887*4dc78e53SAndroid Build Coastguard Worker struct rtnl_flower *f;
888*4dc78e53SAndroid Build Coastguard Worker
889*4dc78e53SAndroid Build Coastguard Worker if (!(f = rtnl_tc_data(TC_CAST(cls))))
890*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
891*4dc78e53SAndroid Build Coastguard Worker
892*4dc78e53SAndroid Build Coastguard Worker f->cf_flags = flags;
893*4dc78e53SAndroid Build Coastguard Worker f->cf_mask |= FLOWER_ATTR_FLAGS;
894*4dc78e53SAndroid Build Coastguard Worker
895*4dc78e53SAndroid Build Coastguard Worker return 0;
896*4dc78e53SAndroid Build Coastguard Worker }
897*4dc78e53SAndroid Build Coastguard Worker
898*4dc78e53SAndroid Build Coastguard Worker /** @} */
899*4dc78e53SAndroid Build Coastguard Worker
900*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_ops flower_ops = {
901*4dc78e53SAndroid Build Coastguard Worker .to_kind = "flower",
902*4dc78e53SAndroid Build Coastguard Worker .to_type = RTNL_TC_TYPE_CLS,
903*4dc78e53SAndroid Build Coastguard Worker .to_size = sizeof(struct rtnl_flower),
904*4dc78e53SAndroid Build Coastguard Worker .to_msg_parser = flower_msg_parser,
905*4dc78e53SAndroid Build Coastguard Worker .to_free_data = flower_free_data,
906*4dc78e53SAndroid Build Coastguard Worker .to_clone = flower_clone,
907*4dc78e53SAndroid Build Coastguard Worker .to_msg_fill = flower_msg_fill,
908*4dc78e53SAndroid Build Coastguard Worker .to_dump = {
909*4dc78e53SAndroid Build Coastguard Worker [NL_DUMP_DETAILS] = flower_dump_details,
910*4dc78e53SAndroid Build Coastguard Worker },
911*4dc78e53SAndroid Build Coastguard Worker };
912*4dc78e53SAndroid Build Coastguard Worker
flower_init(void)913*4dc78e53SAndroid Build Coastguard Worker static void _nl_init flower_init(void)
914*4dc78e53SAndroid Build Coastguard Worker {
915*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_register(&flower_ops);
916*4dc78e53SAndroid Build Coastguard Worker }
917*4dc78e53SAndroid Build Coastguard Worker
flower_exit(void)918*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit flower_exit(void)
919*4dc78e53SAndroid Build Coastguard Worker {
920*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_unregister(&flower_ops);
921*4dc78e53SAndroid Build Coastguard Worker }
922