aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/fib_rules.h2
-rw-r--r--include/net/fib_rules.h2
-rw-r--r--net/core/fib_rules.c29
-rw-r--r--net/decnet/dn_rules.c27
-rw-r--r--net/ipv4/fib_rules.c29
-rw-r--r--net/ipv6/fib6_rules.c32
6 files changed, 32 insertions, 89 deletions
diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h
index 4418c8d9d479..adcdfbdd14d5 100644
--- a/include/linux/fib_rules.h
+++ b/include/linux/fib_rules.h
@@ -34,7 +34,7 @@ enum
34 FRA_UNUSED3, 34 FRA_UNUSED3,
35 FRA_UNUSED4, 35 FRA_UNUSED4,
36 FRA_UNUSED5, 36 FRA_UNUSED5,
37 FRA_FWMARK, /* netfilter mark */ 37 FRA_FWMARK, /* mark */
38 FRA_FLOW, /* flow/class id */ 38 FRA_FLOW, /* flow/class id */
39 FRA_UNUSED6, 39 FRA_UNUSED6,
40 FRA_UNUSED7, 40 FRA_UNUSED7,
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index 8e2f473d3e82..68542b565cf7 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -13,6 +13,8 @@ struct fib_rule
13 atomic_t refcnt; 13 atomic_t refcnt;
14 int ifindex; 14 int ifindex;
15 char ifname[IFNAMSIZ]; 15 char ifname[IFNAMSIZ];
16 u32 mark;
17 u32 mark_mask;
16 u32 pref; 18 u32 pref;
17 u32 flags; 19 u32 flags;
18 u32 table; 20 u32 table;
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 6b0e63cacd93..da91bf2e6151 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -119,6 +119,9 @@ int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
119 if (rule->ifindex && (rule->ifindex != fl->iif)) 119 if (rule->ifindex && (rule->ifindex != fl->iif))
120 continue; 120 continue;
121 121
122 if ((rule->mark ^ fl->mark) & rule->mark_mask)
123 continue;
124
122 if (!ops->match(rule, fl, flags)) 125 if (!ops->match(rule, fl, flags))
123 continue; 126 continue;
124 127
@@ -179,6 +182,18 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
179 rule->ifindex = dev->ifindex; 182 rule->ifindex = dev->ifindex;
180 } 183 }
181 184
185 if (tb[FRA_FWMARK]) {
186 rule->mark = nla_get_u32(tb[FRA_FWMARK]);
187 if (rule->mark)
188 /* compatibility: if the mark value is non-zero all bits
189 * are compared unless a mask is explicitly specified.
190 */
191 rule->mark_mask = 0xFFFFFFFF;
192 }
193
194 if (tb[FRA_FWMASK])
195 rule->mark_mask = nla_get_u32(tb[FRA_FWMASK]);
196
182 rule->action = frh->action; 197 rule->action = frh->action;
183 rule->flags = frh->flags; 198 rule->flags = frh->flags;
184 rule->table = frh_get_table(frh, tb); 199 rule->table = frh_get_table(frh, tb);
@@ -250,6 +265,14 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
250 nla_strcmp(tb[FRA_IFNAME], rule->ifname)) 265 nla_strcmp(tb[FRA_IFNAME], rule->ifname))
251 continue; 266 continue;
252 267
268 if (tb[FRA_FWMARK] &&
269 (rule->mark != nla_get_u32(tb[FRA_FWMARK])))
270 continue;
271
272 if (tb[FRA_FWMASK] &&
273 (rule->mark_mask != nla_get_u32(tb[FRA_FWMASK])))
274 continue;
275
253 if (!ops->compare(rule, frh, tb)) 276 if (!ops->compare(rule, frh, tb))
254 continue; 277 continue;
255 278
@@ -298,6 +321,12 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
298 if (rule->pref) 321 if (rule->pref)
299 NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref); 322 NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref);
300 323
324 if (rule->mark)
325 NLA_PUT_U32(skb, FRA_FWMARK, rule->mark);
326
327 if (rule->mark_mask || rule->mark)
328 NLA_PUT_U32(skb, FRA_FWMASK, rule->mark_mask);
329
301 if (ops->fill(rule, skb, nlh, frh) < 0) 330 if (ops->fill(rule, skb, nlh, frh) < 0)
302 goto nla_put_failure; 331 goto nla_put_failure;
303 332
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index a09c09f5572d..1f5d23c96681 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -45,8 +45,6 @@ struct dn_fib_rule
45 __le16 dstmask; 45 __le16 dstmask;
46 __le16 srcmap; 46 __le16 srcmap;
47 u8 flags; 47 u8 flags;
48 u32 fwmark;
49 u32 fwmask;
50}; 48};
51 49
52static struct dn_fib_rule default_rule = { 50static struct dn_fib_rule default_rule = {
@@ -129,9 +127,6 @@ static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
129 ((daddr ^ r->dst) & r->dstmask)) 127 ((daddr ^ r->dst) & r->dstmask))
130 return 0; 128 return 0;
131 129
132 if ((r->fwmark ^ fl->mark) & r->fwmask)
133 return 0;
134
135 return 1; 130 return 1;
136} 131}
137 132
@@ -165,18 +160,6 @@ static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
165 if (tb[FRA_DST]) 160 if (tb[FRA_DST])
166 r->dst = nla_get_u16(tb[FRA_DST]); 161 r->dst = nla_get_u16(tb[FRA_DST]);
167 162
168 if (tb[FRA_FWMARK]) {
169 r->fwmark = nla_get_u32(tb[FRA_FWMARK]);
170 if (r->fwmark)
171 /* compatibility: if the mark value is non-zero all bits
172 * are compared unless a mask is explicitly specified.
173 */
174 r->fwmask = 0xFFFFFFFF;
175 }
176
177 if (tb[FRA_FWMASK])
178 r->fwmask = nla_get_u32(tb[FRA_FWMASK]);
179
180 r->src_len = frh->src_len; 163 r->src_len = frh->src_len;
181 r->srcmask = dnet_make_mask(r->src_len); 164 r->srcmask = dnet_make_mask(r->src_len);
182 r->dst_len = frh->dst_len; 165 r->dst_len = frh->dst_len;
@@ -197,12 +180,6 @@ static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
197 if (frh->dst_len && (r->dst_len != frh->dst_len)) 180 if (frh->dst_len && (r->dst_len != frh->dst_len))
198 return 0; 181 return 0;
199 182
200 if (tb[FRA_FWMARK] && (r->fwmark != nla_get_u32(tb[FRA_FWMARK])))
201 return 0;
202
203 if (tb[FRA_FWMASK] && (r->fwmask != nla_get_u32(tb[FRA_FWMASK])))
204 return 0;
205
206 if (tb[FRA_SRC] && (r->src != nla_get_u16(tb[FRA_SRC]))) 183 if (tb[FRA_SRC] && (r->src != nla_get_u16(tb[FRA_SRC])))
207 return 0; 184 return 0;
208 185
@@ -240,10 +217,6 @@ static int dn_fib_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
240 frh->src_len = r->src_len; 217 frh->src_len = r->src_len;
241 frh->tos = 0; 218 frh->tos = 0;
242 219
243 if (r->fwmark)
244 NLA_PUT_U32(skb, FRA_FWMARK, r->fwmark);
245 if (r->fwmask || r->fwmark)
246 NLA_PUT_U32(skb, FRA_FWMASK, r->fwmask);
247 if (r->dst_len) 220 if (r->dst_len)
248 NLA_PUT_U16(skb, FRA_DST, r->dst); 221 NLA_PUT_U16(skb, FRA_DST, r->dst);
249 if (r->src_len) 222 if (r->src_len)
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index de8d5dd7099b..d2a190a35d65 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -44,8 +44,6 @@ struct fib4_rule
44 __be32 srcmask; 44 __be32 srcmask;
45 __be32 dst; 45 __be32 dst;
46 __be32 dstmask; 46 __be32 dstmask;
47 u32 fwmark;
48 u32 fwmask;
49#ifdef CONFIG_NET_CLS_ROUTE 47#ifdef CONFIG_NET_CLS_ROUTE
50 u32 tclassid; 48 u32 tclassid;
51#endif 49#endif
@@ -158,9 +156,6 @@ static int fib4_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
158 if (r->tos && (r->tos != fl->fl4_tos)) 156 if (r->tos && (r->tos != fl->fl4_tos))
159 return 0; 157 return 0;
160 158
161 if ((r->fwmark ^ fl->mark) & r->fwmask)
162 return 0;
163
164 return 1; 159 return 1;
165} 160}
166 161
@@ -216,18 +211,6 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
216 if (tb[FRA_DST]) 211 if (tb[FRA_DST])
217 rule4->dst = nla_get_be32(tb[FRA_DST]); 212 rule4->dst = nla_get_be32(tb[FRA_DST]);
218 213
219 if (tb[FRA_FWMARK]) {
220 rule4->fwmark = nla_get_u32(tb[FRA_FWMARK]);
221 if (rule4->fwmark)
222 /* compatibility: if the mark value is non-zero all bits
223 * are compared unless a mask is explicitly specified.
224 */
225 rule4->fwmask = 0xFFFFFFFF;
226 }
227
228 if (tb[FRA_FWMASK])
229 rule4->fwmask = nla_get_u32(tb[FRA_FWMASK]);
230
231#ifdef CONFIG_NET_CLS_ROUTE 214#ifdef CONFIG_NET_CLS_ROUTE
232 if (tb[FRA_FLOW]) 215 if (tb[FRA_FLOW])
233 rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); 216 rule4->tclassid = nla_get_u32(tb[FRA_FLOW]);
@@ -258,12 +241,6 @@ static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
258 if (frh->tos && (rule4->tos != frh->tos)) 241 if (frh->tos && (rule4->tos != frh->tos))
259 return 0; 242 return 0;
260 243
261 if (tb[FRA_FWMARK] && (rule4->fwmark != nla_get_u32(tb[FRA_FWMARK])))
262 return 0;
263
264 if (tb[FRA_FWMASK] && (rule4->fwmask != nla_get_u32(tb[FRA_FWMASK])))
265 return 0;
266
267#ifdef CONFIG_NET_CLS_ROUTE 244#ifdef CONFIG_NET_CLS_ROUTE
268 if (tb[FRA_FLOW] && (rule4->tclassid != nla_get_u32(tb[FRA_FLOW]))) 245 if (tb[FRA_FLOW] && (rule4->tclassid != nla_get_u32(tb[FRA_FLOW])))
269 return 0; 246 return 0;
@@ -288,12 +265,6 @@ static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
288 frh->src_len = rule4->src_len; 265 frh->src_len = rule4->src_len;
289 frh->tos = rule4->tos; 266 frh->tos = rule4->tos;
290 267
291 if (rule4->fwmark)
292 NLA_PUT_U32(skb, FRA_FWMARK, rule4->fwmark);
293
294 if (rule4->fwmask || rule4->fwmark)
295 NLA_PUT_U32(skb, FRA_FWMASK, rule4->fwmask);
296
297 if (rule4->dst_len) 268 if (rule4->dst_len)
298 NLA_PUT_BE32(skb, FRA_DST, rule4->dst); 269 NLA_PUT_BE32(skb, FRA_DST, rule4->dst);
299 270
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 89bea64eee1c..26374cbe2bc2 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -25,8 +25,6 @@ struct fib6_rule
25 struct fib_rule common; 25 struct fib_rule common;
26 struct rt6key src; 26 struct rt6key src;
27 struct rt6key dst; 27 struct rt6key dst;
28 u32 fwmark;
29 u32 fwmask;
30 u8 tclass; 28 u8 tclass;
31}; 29};
32 30
@@ -128,9 +126,6 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
128 if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff)) 126 if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff))
129 return 0; 127 return 0;
130 128
131 if ((r->fwmark ^ fl->mark) & r->fwmask)
132 return 0;
133
134 return 1; 129 return 1;
135} 130}
136 131
@@ -173,21 +168,6 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
173 nla_memcpy(&rule6->dst.addr, tb[FRA_DST], 168 nla_memcpy(&rule6->dst.addr, tb[FRA_DST],
174 sizeof(struct in6_addr)); 169 sizeof(struct in6_addr));
175 170
176 if (tb[FRA_FWMARK]) {
177 rule6->fwmark = nla_get_u32(tb[FRA_FWMARK]);
178 if (rule6->fwmark) {
179 /*
180 * if the mark value is non-zero,
181 * all bits are compared by default
182 * unless a mask is explicitly specified.
183 */
184 rule6->fwmask = 0xFFFFFFFF;
185 }
186 }
187
188 if (tb[FRA_FWMASK])
189 rule6->fwmask = nla_get_u32(tb[FRA_FWMASK]);
190
191 rule6->src.plen = frh->src_len; 171 rule6->src.plen = frh->src_len;
192 rule6->dst.plen = frh->dst_len; 172 rule6->dst.plen = frh->dst_len;
193 rule6->tclass = frh->tos; 173 rule6->tclass = frh->tos;
@@ -219,12 +199,6 @@ static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
219 nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr))) 199 nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr)))
220 return 0; 200 return 0;
221 201
222 if (tb[FRA_FWMARK] && (rule6->fwmark != nla_get_u32(tb[FRA_FWMARK])))
223 return 0;
224
225 if (tb[FRA_FWMASK] && (rule6->fwmask != nla_get_u32(tb[FRA_FWMASK])))
226 return 0;
227
228 return 1; 202 return 1;
229} 203}
230 204
@@ -246,12 +220,6 @@ static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
246 NLA_PUT(skb, FRA_SRC, sizeof(struct in6_addr), 220 NLA_PUT(skb, FRA_SRC, sizeof(struct in6_addr),
247 &rule6->src.addr); 221 &rule6->src.addr);
248 222
249 if (rule6->fwmark)
250 NLA_PUT_U32(skb, FRA_FWMARK, rule6->fwmark);
251
252 if (rule6->fwmask || rule6->fwmark)
253 NLA_PUT_U32(skb, FRA_FWMASK, rule6->fwmask);
254
255 return 0; 223 return 0;
256 224
257nla_put_failure: 225nla_put_failure: