1 /* 2 * Copyright (c) 2014 Pablo Neira Ayuso <pablo@netfilter.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 */ 8 9 #include <linux/kernel.h> 10 #include <linux/init.h> 11 #include <linux/module.h> 12 #include <linux/netlink.h> 13 #include <linux/netfilter.h> 14 #include <linux/netfilter/nf_tables.h> 15 #include <net/netfilter/nf_tables.h> 16 #include <net/netfilter/nft_reject.h> 17 #include <net/netfilter/ipv4/nf_reject.h> 18 #include <net/netfilter/ipv6/nf_reject.h> 19 #include <linux/ip.h> 20 #include <net/ip.h> 21 #include <net/ip6_checksum.h> 22 #include <linux/netfilter_bridge.h> 23 #include <linux/netfilter_ipv6.h> 24 #include "../br_private.h" 25 26 static void nft_reject_br_push_etherhdr(struct sk_buff *oldskb, 27 struct sk_buff *nskb) 28 { 29 struct ethhdr *eth; 30 31 eth = (struct ethhdr *)skb_push(nskb, ETH_HLEN); 32 skb_reset_mac_header(nskb); 33 ether_addr_copy(eth->h_source, eth_hdr(oldskb)->h_dest); 34 ether_addr_copy(eth->h_dest, eth_hdr(oldskb)->h_source); 35 eth->h_proto = eth_hdr(oldskb)->h_proto; 36 skb_pull(nskb, ETH_HLEN); 37 } 38 39 static int nft_bridge_iphdr_validate(struct sk_buff *skb) 40 { 41 struct iphdr *iph; 42 u32 len; 43 44 if (!pskb_may_pull(skb, sizeof(struct iphdr))) 45 return 0; 46 47 iph = ip_hdr(skb); 48 if (iph->ihl < 5 || iph->version != 4) 49 return 0; 50 51 len = ntohs(iph->tot_len); 52 if (skb->len < len) 53 return 0; 54 else if (len < (iph->ihl*4)) 55 return 0; 56 57 if (!pskb_may_pull(skb, iph->ihl*4)) 58 return 0; 59 60 return 1; 61 } 62 63 /* We cannot use oldskb->dev, it can be either bridge device (NF_BRIDGE INPUT) 64 * or the bridge port (NF_BRIDGE PREROUTING). 65 */ 66 static void nft_reject_br_send_v4_tcp_reset(struct net *net, 67 struct sk_buff *oldskb, 68 const struct net_device *dev, 69 int hook) 70 { 71 struct sk_buff *nskb; 72 struct iphdr *niph; 73 const struct tcphdr *oth; 74 struct tcphdr _oth; 75 76 if (!nft_bridge_iphdr_validate(oldskb)) 77 return; 78 79 oth = nf_reject_ip_tcphdr_get(oldskb, &_oth, hook); 80 if (!oth) 81 return; 82 83 nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) + 84 LL_MAX_HEADER, GFP_ATOMIC); 85 if (!nskb) 86 return; 87 88 skb_reserve(nskb, LL_MAX_HEADER); 89 niph = nf_reject_iphdr_put(nskb, oldskb, IPPROTO_TCP, 90 net->ipv4.sysctl_ip_default_ttl); 91 nf_reject_ip_tcphdr_put(nskb, oldskb, oth); 92 niph->ttl = net->ipv4.sysctl_ip_default_ttl; 93 niph->tot_len = htons(nskb->len); 94 ip_send_check(niph); 95 96 nft_reject_br_push_etherhdr(oldskb, nskb); 97 98 br_forward(br_port_get_rcu(dev), nskb, false, true); 99 } 100 101 static void nft_reject_br_send_v4_unreach(struct net *net, 102 struct sk_buff *oldskb, 103 const struct net_device *dev, 104 int hook, u8 code) 105 { 106 struct sk_buff *nskb; 107 struct iphdr *niph; 108 struct icmphdr *icmph; 109 unsigned int len; 110 void *payload; 111 __wsum csum; 112 u8 proto; 113 114 if (oldskb->csum_bad || !nft_bridge_iphdr_validate(oldskb)) 115 return; 116 117 /* IP header checks: fragment. */ 118 if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET)) 119 return; 120 121 /* RFC says return as much as we can without exceeding 576 bytes. */ 122 len = min_t(unsigned int, 536, oldskb->len); 123 124 if (!pskb_may_pull(oldskb, len)) 125 return; 126 127 if (pskb_trim_rcsum(oldskb, ntohs(ip_hdr(oldskb)->tot_len))) 128 return; 129 130 if (ip_hdr(oldskb)->protocol == IPPROTO_TCP || 131 ip_hdr(oldskb)->protocol == IPPROTO_UDP) 132 proto = ip_hdr(oldskb)->protocol; 133 else 134 proto = 0; 135 136 if (!skb_csum_unnecessary(oldskb) && 137 nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), proto)) 138 return; 139 140 nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct icmphdr) + 141 LL_MAX_HEADER + len, GFP_ATOMIC); 142 if (!nskb) 143 return; 144 145 skb_reserve(nskb, LL_MAX_HEADER); 146 niph = nf_reject_iphdr_put(nskb, oldskb, IPPROTO_ICMP, 147 net->ipv4.sysctl_ip_default_ttl); 148 149 skb_reset_transport_header(nskb); 150 icmph = (struct icmphdr *)skb_put(nskb, sizeof(struct icmphdr)); 151 memset(icmph, 0, sizeof(*icmph)); 152 icmph->type = ICMP_DEST_UNREACH; 153 icmph->code = code; 154 155 payload = skb_put(nskb, len); 156 memcpy(payload, skb_network_header(oldskb), len); 157 158 csum = csum_partial((void *)icmph, len + sizeof(struct icmphdr), 0); 159 icmph->checksum = csum_fold(csum); 160 161 niph->tot_len = htons(nskb->len); 162 ip_send_check(niph); 163 164 nft_reject_br_push_etherhdr(oldskb, nskb); 165 166 br_forward(br_port_get_rcu(dev), nskb, false, true); 167 } 168 169 static int nft_bridge_ip6hdr_validate(struct sk_buff *skb) 170 { 171 struct ipv6hdr *hdr; 172 u32 pkt_len; 173 174 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 175 return 0; 176 177 hdr = ipv6_hdr(skb); 178 if (hdr->version != 6) 179 return 0; 180 181 pkt_len = ntohs(hdr->payload_len); 182 if (pkt_len + sizeof(struct ipv6hdr) > skb->len) 183 return 0; 184 185 return 1; 186 } 187 188 static void nft_reject_br_send_v6_tcp_reset(struct net *net, 189 struct sk_buff *oldskb, 190 const struct net_device *dev, 191 int hook) 192 { 193 struct sk_buff *nskb; 194 const struct tcphdr *oth; 195 struct tcphdr _oth; 196 unsigned int otcplen; 197 struct ipv6hdr *nip6h; 198 199 if (!nft_bridge_ip6hdr_validate(oldskb)) 200 return; 201 202 oth = nf_reject_ip6_tcphdr_get(oldskb, &_oth, &otcplen, hook); 203 if (!oth) 204 return; 205 206 nskb = alloc_skb(sizeof(struct ipv6hdr) + sizeof(struct tcphdr) + 207 LL_MAX_HEADER, GFP_ATOMIC); 208 if (!nskb) 209 return; 210 211 skb_reserve(nskb, LL_MAX_HEADER); 212 nip6h = nf_reject_ip6hdr_put(nskb, oldskb, IPPROTO_TCP, 213 net->ipv6.devconf_all->hop_limit); 214 nf_reject_ip6_tcphdr_put(nskb, oldskb, oth, otcplen); 215 nip6h->payload_len = htons(nskb->len - sizeof(struct ipv6hdr)); 216 217 nft_reject_br_push_etherhdr(oldskb, nskb); 218 219 br_forward(br_port_get_rcu(dev), nskb, false, true); 220 } 221 222 static bool reject6_br_csum_ok(struct sk_buff *skb, int hook) 223 { 224 const struct ipv6hdr *ip6h = ipv6_hdr(skb); 225 int thoff; 226 __be16 fo; 227 u8 proto = ip6h->nexthdr; 228 229 if (skb->csum_bad) 230 return false; 231 232 if (skb_csum_unnecessary(skb)) 233 return true; 234 235 if (ip6h->payload_len && 236 pskb_trim_rcsum(skb, ntohs(ip6h->payload_len) + sizeof(*ip6h))) 237 return false; 238 239 thoff = ipv6_skip_exthdr(skb, ((u8*)(ip6h+1) - skb->data), &proto, &fo); 240 if (thoff < 0 || thoff >= skb->len || (fo & htons(~0x7)) != 0) 241 return false; 242 243 return nf_ip6_checksum(skb, hook, thoff, proto) == 0; 244 } 245 246 static void nft_reject_br_send_v6_unreach(struct net *net, 247 struct sk_buff *oldskb, 248 const struct net_device *dev, 249 int hook, u8 code) 250 { 251 struct sk_buff *nskb; 252 struct ipv6hdr *nip6h; 253 struct icmp6hdr *icmp6h; 254 unsigned int len; 255 void *payload; 256 257 if (!nft_bridge_ip6hdr_validate(oldskb)) 258 return; 259 260 /* Include "As much of invoking packet as possible without the ICMPv6 261 * packet exceeding the minimum IPv6 MTU" in the ICMP payload. 262 */ 263 len = min_t(unsigned int, 1220, oldskb->len); 264 265 if (!pskb_may_pull(oldskb, len)) 266 return; 267 268 if (!reject6_br_csum_ok(oldskb, hook)) 269 return; 270 271 nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct icmp6hdr) + 272 LL_MAX_HEADER + len, GFP_ATOMIC); 273 if (!nskb) 274 return; 275 276 skb_reserve(nskb, LL_MAX_HEADER); 277 nip6h = nf_reject_ip6hdr_put(nskb, oldskb, IPPROTO_ICMPV6, 278 net->ipv6.devconf_all->hop_limit); 279 280 skb_reset_transport_header(nskb); 281 icmp6h = (struct icmp6hdr *)skb_put(nskb, sizeof(struct icmp6hdr)); 282 memset(icmp6h, 0, sizeof(*icmp6h)); 283 icmp6h->icmp6_type = ICMPV6_DEST_UNREACH; 284 icmp6h->icmp6_code = code; 285 286 payload = skb_put(nskb, len); 287 memcpy(payload, skb_network_header(oldskb), len); 288 nip6h->payload_len = htons(nskb->len - sizeof(struct ipv6hdr)); 289 290 icmp6h->icmp6_cksum = 291 csum_ipv6_magic(&nip6h->saddr, &nip6h->daddr, 292 nskb->len - sizeof(struct ipv6hdr), 293 IPPROTO_ICMPV6, 294 csum_partial(icmp6h, 295 nskb->len - sizeof(struct ipv6hdr), 296 0)); 297 298 nft_reject_br_push_etherhdr(oldskb, nskb); 299 300 br_forward(br_port_get_rcu(dev), nskb, false, true); 301 } 302 303 static void nft_reject_bridge_eval(const struct nft_expr *expr, 304 struct nft_regs *regs, 305 const struct nft_pktinfo *pkt) 306 { 307 struct nft_reject *priv = nft_expr_priv(expr); 308 const unsigned char *dest = eth_hdr(pkt->skb)->h_dest; 309 310 if (is_broadcast_ether_addr(dest) || 311 is_multicast_ether_addr(dest)) 312 goto out; 313 314 switch (eth_hdr(pkt->skb)->h_proto) { 315 case htons(ETH_P_IP): 316 switch (priv->type) { 317 case NFT_REJECT_ICMP_UNREACH: 318 nft_reject_br_send_v4_unreach(nft_net(pkt), pkt->skb, 319 nft_in(pkt), 320 nft_hook(pkt), 321 priv->icmp_code); 322 break; 323 case NFT_REJECT_TCP_RST: 324 nft_reject_br_send_v4_tcp_reset(nft_net(pkt), pkt->skb, 325 nft_in(pkt), 326 nft_hook(pkt)); 327 break; 328 case NFT_REJECT_ICMPX_UNREACH: 329 nft_reject_br_send_v4_unreach(nft_net(pkt), pkt->skb, 330 nft_in(pkt), 331 nft_hook(pkt), 332 nft_reject_icmp_code(priv->icmp_code)); 333 break; 334 } 335 break; 336 case htons(ETH_P_IPV6): 337 switch (priv->type) { 338 case NFT_REJECT_ICMP_UNREACH: 339 nft_reject_br_send_v6_unreach(nft_net(pkt), pkt->skb, 340 nft_in(pkt), 341 nft_hook(pkt), 342 priv->icmp_code); 343 break; 344 case NFT_REJECT_TCP_RST: 345 nft_reject_br_send_v6_tcp_reset(nft_net(pkt), pkt->skb, 346 nft_in(pkt), 347 nft_hook(pkt)); 348 break; 349 case NFT_REJECT_ICMPX_UNREACH: 350 nft_reject_br_send_v6_unreach(nft_net(pkt), pkt->skb, 351 nft_in(pkt), 352 nft_hook(pkt), 353 nft_reject_icmpv6_code(priv->icmp_code)); 354 break; 355 } 356 break; 357 default: 358 /* No explicit way to reject this protocol, drop it. */ 359 break; 360 } 361 out: 362 regs->verdict.code = NF_DROP; 363 } 364 365 static int nft_reject_bridge_validate(const struct nft_ctx *ctx, 366 const struct nft_expr *expr, 367 const struct nft_data **data) 368 { 369 return nft_chain_validate_hooks(ctx->chain, (1 << NF_BR_PRE_ROUTING) | 370 (1 << NF_BR_LOCAL_IN)); 371 } 372 373 static int nft_reject_bridge_init(const struct nft_ctx *ctx, 374 const struct nft_expr *expr, 375 const struct nlattr * const tb[]) 376 { 377 struct nft_reject *priv = nft_expr_priv(expr); 378 int icmp_code; 379 380 if (tb[NFTA_REJECT_TYPE] == NULL) 381 return -EINVAL; 382 383 priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE])); 384 switch (priv->type) { 385 case NFT_REJECT_ICMP_UNREACH: 386 case NFT_REJECT_ICMPX_UNREACH: 387 if (tb[NFTA_REJECT_ICMP_CODE] == NULL) 388 return -EINVAL; 389 390 icmp_code = nla_get_u8(tb[NFTA_REJECT_ICMP_CODE]); 391 if (priv->type == NFT_REJECT_ICMPX_UNREACH && 392 icmp_code > NFT_REJECT_ICMPX_MAX) 393 return -EINVAL; 394 395 priv->icmp_code = icmp_code; 396 break; 397 case NFT_REJECT_TCP_RST: 398 break; 399 default: 400 return -EINVAL; 401 } 402 return 0; 403 } 404 405 static int nft_reject_bridge_dump(struct sk_buff *skb, 406 const struct nft_expr *expr) 407 { 408 const struct nft_reject *priv = nft_expr_priv(expr); 409 410 if (nla_put_be32(skb, NFTA_REJECT_TYPE, htonl(priv->type))) 411 goto nla_put_failure; 412 413 switch (priv->type) { 414 case NFT_REJECT_ICMP_UNREACH: 415 case NFT_REJECT_ICMPX_UNREACH: 416 if (nla_put_u8(skb, NFTA_REJECT_ICMP_CODE, priv->icmp_code)) 417 goto nla_put_failure; 418 break; 419 default: 420 break; 421 } 422 423 return 0; 424 425 nla_put_failure: 426 return -1; 427 } 428 429 static struct nft_expr_type nft_reject_bridge_type; 430 static const struct nft_expr_ops nft_reject_bridge_ops = { 431 .type = &nft_reject_bridge_type, 432 .size = NFT_EXPR_SIZE(sizeof(struct nft_reject)), 433 .eval = nft_reject_bridge_eval, 434 .init = nft_reject_bridge_init, 435 .dump = nft_reject_bridge_dump, 436 .validate = nft_reject_bridge_validate, 437 }; 438 439 static struct nft_expr_type nft_reject_bridge_type __read_mostly = { 440 .family = NFPROTO_BRIDGE, 441 .name = "reject", 442 .ops = &nft_reject_bridge_ops, 443 .policy = nft_reject_policy, 444 .maxattr = NFTA_REJECT_MAX, 445 .owner = THIS_MODULE, 446 }; 447 448 static int __init nft_reject_bridge_module_init(void) 449 { 450 return nft_register_expr(&nft_reject_bridge_type); 451 } 452 453 static void __exit nft_reject_bridge_module_exit(void) 454 { 455 nft_unregister_expr(&nft_reject_bridge_type); 456 } 457 458 module_init(nft_reject_bridge_module_init); 459 module_exit(nft_reject_bridge_module_exit); 460 461 MODULE_LICENSE("GPL"); 462 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); 463 MODULE_ALIAS_NFT_AF_EXPR(AF_BRIDGE, "reject"); 464