1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * INET An implementation of the TCP/IP protocol suite for the LINUX 4 * operating system. INET is implemented using the BSD Socket 5 * interface as the means of communication with the user level. 6 * 7 * IPv4 Forwarding Information Base: policy rules. 8 * 9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10 * Thomas Graf <tgraf@suug.ch> 11 * 12 * Fixes: 13 * Rani Assaf : local_rule cannot be deleted 14 * Marc Boucher : routing by fwmark 15 */ 16 17 #include <linux/types.h> 18 #include <linux/kernel.h> 19 #include <linux/netdevice.h> 20 #include <linux/netlink.h> 21 #include <linux/inetdevice.h> 22 #include <linux/init.h> 23 #include <linux/list.h> 24 #include <linux/rcupdate.h> 25 #include <linux/export.h> 26 #include <net/ip.h> 27 #include <net/route.h> 28 #include <net/tcp.h> 29 #include <net/ip_fib.h> 30 #include <net/nexthop.h> 31 #include <net/fib_rules.h> 32 33 struct fib4_rule { 34 struct fib_rule common; 35 u8 dst_len; 36 u8 src_len; 37 u8 tos; 38 __be32 src; 39 __be32 srcmask; 40 __be32 dst; 41 __be32 dstmask; 42 #ifdef CONFIG_IP_ROUTE_CLASSID 43 u32 tclassid; 44 #endif 45 }; 46 47 static bool fib4_rule_matchall(const struct fib_rule *rule) 48 { 49 struct fib4_rule *r = container_of(rule, struct fib4_rule, common); 50 51 if (r->dst_len || r->src_len || r->tos) 52 return false; 53 return fib_rule_matchall(rule); 54 } 55 56 bool fib4_rule_default(const struct fib_rule *rule) 57 { 58 if (!fib4_rule_matchall(rule) || rule->action != FR_ACT_TO_TBL || 59 rule->l3mdev) 60 return false; 61 if (rule->table != RT_TABLE_LOCAL && rule->table != RT_TABLE_MAIN && 62 rule->table != RT_TABLE_DEFAULT) 63 return false; 64 return true; 65 } 66 EXPORT_SYMBOL_GPL(fib4_rule_default); 67 68 int fib4_rules_dump(struct net *net, struct notifier_block *nb, 69 struct netlink_ext_ack *extack) 70 { 71 return fib_rules_dump(net, nb, AF_INET, extack); 72 } 73 74 unsigned int fib4_rules_seq_read(struct net *net) 75 { 76 return fib_rules_seq_read(net, AF_INET); 77 } 78 79 int __fib_lookup(struct net *net, struct flowi4 *flp, 80 struct fib_result *res, unsigned int flags) 81 { 82 struct fib_lookup_arg arg = { 83 .result = res, 84 .flags = flags, 85 }; 86 int err; 87 88 /* update flow if oif or iif point to device enslaved to l3mdev */ 89 l3mdev_update_flow(net, flowi4_to_flowi(flp)); 90 91 err = fib_rules_lookup(net->ipv4.rules_ops, flowi4_to_flowi(flp), 0, &arg); 92 #ifdef CONFIG_IP_ROUTE_CLASSID 93 if (arg.rule) 94 res->tclassid = ((struct fib4_rule *)arg.rule)->tclassid; 95 else 96 res->tclassid = 0; 97 #endif 98 99 if (err == -ESRCH) 100 err = -ENETUNREACH; 101 102 return err; 103 } 104 EXPORT_SYMBOL_GPL(__fib_lookup); 105 106 static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp, 107 int flags, struct fib_lookup_arg *arg) 108 { 109 int err = -EAGAIN; 110 struct fib_table *tbl; 111 u32 tb_id; 112 113 switch (rule->action) { 114 case FR_ACT_TO_TBL: 115 break; 116 117 case FR_ACT_UNREACHABLE: 118 return -ENETUNREACH; 119 120 case FR_ACT_PROHIBIT: 121 return -EACCES; 122 123 case FR_ACT_BLACKHOLE: 124 default: 125 return -EINVAL; 126 } 127 128 rcu_read_lock(); 129 130 tb_id = fib_rule_get_table(rule, arg); 131 tbl = fib_get_table(rule->fr_net, tb_id); 132 if (tbl) 133 err = fib_table_lookup(tbl, &flp->u.ip4, 134 (struct fib_result *)arg->result, 135 arg->flags); 136 137 rcu_read_unlock(); 138 return err; 139 } 140 141 static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) 142 { 143 struct fib_result *result = (struct fib_result *) arg->result; 144 struct net_device *dev = NULL; 145 146 if (result->fi) { 147 struct fib_nh_common *nhc = fib_info_nhc(result->fi, 0); 148 149 dev = nhc->nhc_dev; 150 } 151 152 /* do not accept result if the route does 153 * not meet the required prefix length 154 */ 155 if (result->prefixlen <= rule->suppress_prefixlen) 156 goto suppress_route; 157 158 /* do not accept result if the route uses a device 159 * belonging to a forbidden interface group 160 */ 161 if (rule->suppress_ifgroup != -1 && dev && dev->group == rule->suppress_ifgroup) 162 goto suppress_route; 163 164 return false; 165 166 suppress_route: 167 if (!(arg->flags & FIB_LOOKUP_NOREF)) 168 fib_info_put(result->fi); 169 return true; 170 } 171 172 static int fib4_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) 173 { 174 struct fib4_rule *r = (struct fib4_rule *) rule; 175 struct flowi4 *fl4 = &fl->u.ip4; 176 __be32 daddr = fl4->daddr; 177 __be32 saddr = fl4->saddr; 178 179 if (((saddr ^ r->src) & r->srcmask) || 180 ((daddr ^ r->dst) & r->dstmask)) 181 return 0; 182 183 if (r->tos && (r->tos != fl4->flowi4_tos)) 184 return 0; 185 186 if (rule->ip_proto && (rule->ip_proto != fl4->flowi4_proto)) 187 return 0; 188 189 if (fib_rule_port_range_set(&rule->sport_range) && 190 !fib_rule_port_inrange(&rule->sport_range, fl4->fl4_sport)) 191 return 0; 192 193 if (fib_rule_port_range_set(&rule->dport_range) && 194 !fib_rule_port_inrange(&rule->dport_range, fl4->fl4_dport)) 195 return 0; 196 197 return 1; 198 } 199 200 static struct fib_table *fib_empty_table(struct net *net) 201 { 202 u32 id = 1; 203 204 while (1) { 205 if (!fib_get_table(net, id)) 206 return fib_new_table(net, id); 207 208 if (id++ == RT_TABLE_MAX) 209 break; 210 } 211 return NULL; 212 } 213 214 static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = { 215 FRA_GENERIC_POLICY, 216 [FRA_FLOW] = { .type = NLA_U32 }, 217 }; 218 219 static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, 220 struct fib_rule_hdr *frh, 221 struct nlattr **tb, 222 struct netlink_ext_ack *extack) 223 { 224 struct net *net = sock_net(skb->sk); 225 int err = -EINVAL; 226 struct fib4_rule *rule4 = (struct fib4_rule *) rule; 227 228 if (frh->tos & ~IPTOS_TOS_MASK) { 229 NL_SET_ERR_MSG(extack, "Invalid tos"); 230 goto errout; 231 } 232 233 /* split local/main if they are not already split */ 234 err = fib_unmerge(net); 235 if (err) 236 goto errout; 237 238 if (rule->table == RT_TABLE_UNSPEC && !rule->l3mdev) { 239 if (rule->action == FR_ACT_TO_TBL) { 240 struct fib_table *table; 241 242 table = fib_empty_table(net); 243 if (!table) { 244 err = -ENOBUFS; 245 goto errout; 246 } 247 248 rule->table = table->tb_id; 249 } 250 } 251 252 if (frh->src_len) 253 rule4->src = nla_get_in_addr(tb[FRA_SRC]); 254 255 if (frh->dst_len) 256 rule4->dst = nla_get_in_addr(tb[FRA_DST]); 257 258 #ifdef CONFIG_IP_ROUTE_CLASSID 259 if (tb[FRA_FLOW]) { 260 rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); 261 if (rule4->tclassid) 262 net->ipv4.fib_num_tclassid_users++; 263 } 264 #endif 265 266 if (fib_rule_requires_fldissect(rule)) 267 net->ipv4.fib_rules_require_fldissect++; 268 269 rule4->src_len = frh->src_len; 270 rule4->srcmask = inet_make_mask(rule4->src_len); 271 rule4->dst_len = frh->dst_len; 272 rule4->dstmask = inet_make_mask(rule4->dst_len); 273 rule4->tos = frh->tos; 274 275 net->ipv4.fib_has_custom_rules = true; 276 277 err = 0; 278 errout: 279 return err; 280 } 281 282 static int fib4_rule_delete(struct fib_rule *rule) 283 { 284 struct net *net = rule->fr_net; 285 int err; 286 287 /* split local/main if they are not already split */ 288 err = fib_unmerge(net); 289 if (err) 290 goto errout; 291 292 #ifdef CONFIG_IP_ROUTE_CLASSID 293 if (((struct fib4_rule *)rule)->tclassid) 294 net->ipv4.fib_num_tclassid_users--; 295 #endif 296 net->ipv4.fib_has_custom_rules = true; 297 298 if (net->ipv4.fib_rules_require_fldissect && 299 fib_rule_requires_fldissect(rule)) 300 net->ipv4.fib_rules_require_fldissect--; 301 errout: 302 return err; 303 } 304 305 static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, 306 struct nlattr **tb) 307 { 308 struct fib4_rule *rule4 = (struct fib4_rule *) rule; 309 310 if (frh->src_len && (rule4->src_len != frh->src_len)) 311 return 0; 312 313 if (frh->dst_len && (rule4->dst_len != frh->dst_len)) 314 return 0; 315 316 if (frh->tos && (rule4->tos != frh->tos)) 317 return 0; 318 319 #ifdef CONFIG_IP_ROUTE_CLASSID 320 if (tb[FRA_FLOW] && (rule4->tclassid != nla_get_u32(tb[FRA_FLOW]))) 321 return 0; 322 #endif 323 324 if (frh->src_len && (rule4->src != nla_get_in_addr(tb[FRA_SRC]))) 325 return 0; 326 327 if (frh->dst_len && (rule4->dst != nla_get_in_addr(tb[FRA_DST]))) 328 return 0; 329 330 return 1; 331 } 332 333 static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb, 334 struct fib_rule_hdr *frh) 335 { 336 struct fib4_rule *rule4 = (struct fib4_rule *) rule; 337 338 frh->dst_len = rule4->dst_len; 339 frh->src_len = rule4->src_len; 340 frh->tos = rule4->tos; 341 342 if ((rule4->dst_len && 343 nla_put_in_addr(skb, FRA_DST, rule4->dst)) || 344 (rule4->src_len && 345 nla_put_in_addr(skb, FRA_SRC, rule4->src))) 346 goto nla_put_failure; 347 #ifdef CONFIG_IP_ROUTE_CLASSID 348 if (rule4->tclassid && 349 nla_put_u32(skb, FRA_FLOW, rule4->tclassid)) 350 goto nla_put_failure; 351 #endif 352 return 0; 353 354 nla_put_failure: 355 return -ENOBUFS; 356 } 357 358 static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule) 359 { 360 return nla_total_size(4) /* dst */ 361 + nla_total_size(4) /* src */ 362 + nla_total_size(4); /* flow */ 363 } 364 365 static void fib4_rule_flush_cache(struct fib_rules_ops *ops) 366 { 367 rt_cache_flush(ops->fro_net); 368 } 369 370 static const struct fib_rules_ops __net_initconst fib4_rules_ops_template = { 371 .family = AF_INET, 372 .rule_size = sizeof(struct fib4_rule), 373 .addr_size = sizeof(u32), 374 .action = fib4_rule_action, 375 .suppress = fib4_rule_suppress, 376 .match = fib4_rule_match, 377 .configure = fib4_rule_configure, 378 .delete = fib4_rule_delete, 379 .compare = fib4_rule_compare, 380 .fill = fib4_rule_fill, 381 .nlmsg_payload = fib4_rule_nlmsg_payload, 382 .flush_cache = fib4_rule_flush_cache, 383 .nlgroup = RTNLGRP_IPV4_RULE, 384 .policy = fib4_rule_policy, 385 .owner = THIS_MODULE, 386 }; 387 388 static int fib_default_rules_init(struct fib_rules_ops *ops) 389 { 390 int err; 391 392 err = fib_default_rule_add(ops, 0, RT_TABLE_LOCAL, 0); 393 if (err < 0) 394 return err; 395 err = fib_default_rule_add(ops, 0x7FFE, RT_TABLE_MAIN, 0); 396 if (err < 0) 397 return err; 398 err = fib_default_rule_add(ops, 0x7FFF, RT_TABLE_DEFAULT, 0); 399 if (err < 0) 400 return err; 401 return 0; 402 } 403 404 int __net_init fib4_rules_init(struct net *net) 405 { 406 int err; 407 struct fib_rules_ops *ops; 408 409 ops = fib_rules_register(&fib4_rules_ops_template, net); 410 if (IS_ERR(ops)) 411 return PTR_ERR(ops); 412 413 err = fib_default_rules_init(ops); 414 if (err < 0) 415 goto fail; 416 net->ipv4.rules_ops = ops; 417 net->ipv4.fib_has_custom_rules = false; 418 net->ipv4.fib_rules_require_fldissect = 0; 419 return 0; 420 421 fail: 422 /* also cleans all rules already added */ 423 fib_rules_unregister(ops); 424 return err; 425 } 426 427 void __net_exit fib4_rules_exit(struct net *net) 428 { 429 fib_rules_unregister(net->ipv4.rules_ops); 430 } 431