static void nft_reject_bridge_eval(const struct nft_expr *expr, struct nft_data data[NFT_REG_MAX + 1], const struct nft_pktinfo *pkt) { struct nft_reject *priv = nft_expr_priv(expr); struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out); const unsigned char *dest = eth_hdr(pkt->skb)->h_dest; if (is_broadcast_ether_addr(dest) || is_multicast_ether_addr(dest)) goto out; switch (eth_hdr(pkt->skb)->h_proto) { case htons(ETH_P_IP): switch (priv->type) { case NFT_REJECT_ICMP_UNREACH: nft_reject_br_send_v4_unreach(pkt->skb, pkt->ops->hooknum, priv->icmp_code); break; case NFT_REJECT_TCP_RST: nft_reject_br_send_v4_tcp_reset(pkt->skb, pkt->ops->hooknum); break; case NFT_REJECT_ICMPX_UNREACH: nft_reject_br_send_v4_unreach(pkt->skb, pkt->ops->hooknum, nft_reject_icmp_code(priv->icmp_code)); break; } break; case htons(ETH_P_IPV6): switch (priv->type) { case NFT_REJECT_ICMP_UNREACH: nft_reject_br_send_v6_unreach(net, pkt->skb, pkt->ops->hooknum, priv->icmp_code); break; case NFT_REJECT_TCP_RST: nft_reject_br_send_v6_tcp_reset(net, pkt->skb, pkt->ops->hooknum); break; case NFT_REJECT_ICMPX_UNREACH: nft_reject_br_send_v6_unreach(net, pkt->skb, pkt->ops->hooknum, nft_reject_icmpv6_code(priv->icmp_code)); break; } break; default: /* No explicit way to reject this protocol, drop it. */ break; } out: data[NFT_REG_VERDICT].verdict = NF_DROP; }
static void nft_reject_bridge_eval(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt) { struct nft_reject *priv = nft_expr_priv(expr); const unsigned char *dest = eth_hdr(pkt->skb)->h_dest; if (is_broadcast_ether_addr(dest) || is_multicast_ether_addr(dest)) goto out; switch (eth_hdr(pkt->skb)->h_proto) { case htons(ETH_P_IP): switch (priv->type) { case NFT_REJECT_ICMP_UNREACH: nft_reject_br_send_v4_unreach(nft_net(pkt), pkt->skb, nft_in(pkt), nft_hook(pkt), priv->icmp_code); break; case NFT_REJECT_TCP_RST: nft_reject_br_send_v4_tcp_reset(nft_net(pkt), pkt->skb, nft_in(pkt), nft_hook(pkt)); break; case NFT_REJECT_ICMPX_UNREACH: nft_reject_br_send_v4_unreach(nft_net(pkt), pkt->skb, nft_in(pkt), nft_hook(pkt), nft_reject_icmp_code(priv->icmp_code)); break; } break; case htons(ETH_P_IPV6): switch (priv->type) { case NFT_REJECT_ICMP_UNREACH: nft_reject_br_send_v6_unreach(nft_net(pkt), pkt->skb, nft_in(pkt), nft_hook(pkt), priv->icmp_code); break; case NFT_REJECT_TCP_RST: nft_reject_br_send_v6_tcp_reset(nft_net(pkt), pkt->skb, nft_in(pkt), nft_hook(pkt)); break; case NFT_REJECT_ICMPX_UNREACH: nft_reject_br_send_v6_unreach(nft_net(pkt), pkt->skb, nft_in(pkt), nft_hook(pkt), nft_reject_icmpv6_code(priv->icmp_code)); break; } break; default: /* No explicit way to reject this protocol, drop it. */ break; } out: regs->verdict.code = NF_DROP; }