aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/net/netfilter/nft_meta.c
diff options
context:
space:
mode:
authorAna Rey <anarey@gmail.com>2014-08-06 13:52:49 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2014-08-24 14:06:39 +0200
commite2a093ff0dbfa4c5d99f25241cf33325e9691d91 (patch)
treefc8538f532be4897462c3a0c77618c97356e7fac /net/netfilter/nft_meta.c
parentuapi: netfilter_arp: use __u8 instead of u_int8_t (diff)
downloadwireguard-linux-e2a093ff0dbfa4c5d99f25241cf33325e9691d91.tar.xz
wireguard-linux-e2a093ff0dbfa4c5d99f25241cf33325e9691d91.zip
netfilter: nft_meta: add pkttype support
Add pkttype support for ip, ipv6 and inet families of tables. This allows you to fetch the meta packet type based on the link layer information. The loopback traffic is a special case, the packet type is guessed from the network layer header. No special handling for bridge and arp since we're not going to see such traffic in the loopback interface. Joint work with Alvaro Neira Ayuso <alvaroneay@gmail.com> Signed-off-by: Alvaro Neira Ayuso <alvaroneay@gmail.com> Signed-off-by: Ana Rey <anarey@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nft_meta.c')
-rw-r--r--net/netfilter/nft_meta.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 852b178c6ae7..4f2862fc12c2 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -14,6 +14,9 @@
#include <linux/netlink.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
#include <net/dst.h>
#include <net/sock.h>
#include <net/tcp_states.h> /* for TCP_TIME_WAIT */
@@ -124,6 +127,30 @@ void nft_meta_get_eval(const struct nft_expr *expr,
dest->data[0] = skb->secmark;
break;
#endif
+ case NFT_META_PKTTYPE:
+ if (skb->pkt_type != PACKET_LOOPBACK) {
+ dest->data[0] = skb->pkt_type;
+ break;
+ }
+
+ switch (pkt->ops->pf) {
+ case NFPROTO_IPV4:
+ if (ipv4_is_multicast(ip_hdr(skb)->daddr))
+ dest->data[0] = PACKET_MULTICAST;
+ else
+ dest->data[0] = PACKET_BROADCAST;
+ break;
+ case NFPROTO_IPV6:
+ if (ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF)
+ dest->data[0] = PACKET_MULTICAST;
+ else
+ dest->data[0] = PACKET_BROADCAST;
+ break;
+ default:
+ WARN_ON(1);
+ goto err;
+ }
+ break;
default:
WARN_ON(1);
goto err;
@@ -195,6 +222,7 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
#ifdef CONFIG_NETWORK_SECMARK
case NFT_META_SECMARK:
#endif
+ case NFT_META_PKTTYPE:
break;
default:
return -EOPNOTSUPP;