cregit-Linux how code gets into the kernel

Release 4.8 net/netfilter/xt_addrtype.c

Directory: net/netfilter
 *  iptables module to match inet_addr_type() of an ip.
 *  Copyright (c) 2004 Patrick McHardy <>
 *  (C) 2007 Laszlo Attila Toth <>
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/ip.h>
#include <net/route.h>

#include <net/ipv6.h>
#include <net/ip6_route.h>
#include <net/ip6_fib.h>

#include <linux/netfilter_ipv6.h>
#include <linux/netfilter/xt_addrtype.h>
#include <linux/netfilter/x_tables.h>

MODULE_AUTHOR("Patrick McHardy <>");
MODULE_DESCRIPTION("Xtables: address type match");


static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, const struct in6_addr *addr, u16 mask) { const struct nf_afinfo *afinfo; struct flowi6 flow; struct rt6_info *rt; u32 ret = 0; int route_err; memset(&flow, 0, sizeof(flow)); flow.daddr = *addr; if (dev) flow.flowi6_oif = dev->ifindex; rcu_read_lock(); afinfo = nf_get_afinfo(NFPROTO_IPV6); if (afinfo != NULL) { const struct nf_ipv6_ops *v6ops; if (dev && (mask & XT_ADDRTYPE_LOCAL)) { v6ops = nf_get_ipv6_ops(); if (v6ops && v6ops->chk_addr(net, addr, dev, true)) ret = XT_ADDRTYPE_LOCAL; } route_err = afinfo->route(net, (struct dst_entry **)&rt, flowi6_to_flowi(&flow), false); } else { route_err = 1; } rcu_read_unlock(); if (route_err) return XT_ADDRTYPE_UNREACHABLE; if (rt->rt6i_flags & RTF_REJECT) ret = XT_ADDRTYPE_UNREACHABLE; if (dev == NULL && rt->rt6i_flags & RTF_LOCAL) ret |= XT_ADDRTYPE_LOCAL; if (ipv6_anycast_destination((struct dst_entry *)rt, addr)) ret |= XT_ADDRTYPE_ANYCAST; dst_release(&rt->dst); return ret; }


florian westphalflorian westphal23195.06%360.00%
martin kafai laumartin kafai lau104.12%120.00%
alexey dobriyanalexey dobriyan20.82%120.00%

static bool match_type6(struct net *net, const struct net_device *dev, const struct in6_addr *addr, u16 mask) { int addr_type = ipv6_addr_type(addr); if ((mask & XT_ADDRTYPE_MULTICAST) && !(addr_type & IPV6_ADDR_MULTICAST)) return false; if ((mask & XT_ADDRTYPE_UNICAST) && !(addr_type & IPV6_ADDR_UNICAST)) return false; if ((mask & XT_ADDRTYPE_UNSPEC) && addr_type != IPV6_ADDR_ANY) return false; if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST | XT_ADDRTYPE_UNREACHABLE) & mask) return !!(mask & match_lookup_rt6(net, dev, addr, mask)); return true; }


florian westphalflorian westphal118100.00%3100.00%

static bool addrtype_mt6(struct net *net, const struct net_device *dev, const struct sk_buff *skb, const struct xt_addrtype_info_v1 *info) { const struct ipv6hdr *iph = ipv6_hdr(skb); bool ret = true; if (info->source) ret &= match_type6(net, dev, &iph->saddr, info->source) ^ (info->flags & XT_ADDRTYPE_INVERT_SOURCE); if (ret && info->dest) ret &= match_type6(net, dev, &iph->daddr, info->dest) ^ !!(info->flags & XT_ADDRTYPE_INVERT_DEST); return ret; }


florian westphalflorian westphal116100.00%1100.00%

static inline bool match_type(struct net *net, const struct net_device *dev, __be32 addr, u_int16_t mask) { return !!(mask & (1 << inet_dev_addr_type(net, dev, addr))); }


patrick mchardypatrick mchardy2659.09%116.67%
laszlo attila tothlaszlo attila toth920.45%116.67%
alexey dobriyanalexey dobriyan613.64%116.67%
eric w. biedermaneric w. biederman12.27%116.67%
jan engelhardtjan engelhardt12.27%116.67%
al viroal viro12.27%116.67%

static bool addrtype_mt_v0(const struct sk_buff *skb, struct xt_action_param *par) { struct net *net = par->net; const struct xt_addrtype_info *info = par->matchinfo; const struct iphdr *iph = ip_hdr(skb); bool ret = true; if (info->source) ret &= match_type(net, NULL, iph->saddr, info->source) ^ info->invert_source; if (info->dest) ret &= match_type(net, NULL, iph->daddr, info->dest) ^ info->invert_dest; return ret; }


patrick mchardypatrick mchardy8073.39%220.00%
alexey dobriyanalexey dobriyan1211.01%110.00%
jan engelhardtjan engelhardt76.42%330.00%
laszlo attila tothlaszlo attila toth54.59%110.00%
arnaldo carvalho de meloarnaldo carvalho de melo32.75%110.00%
florian westphalflorian westphal10.92%110.00%
eric w. biedermaneric w. biederman10.92%110.00%

static bool addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) { struct net *net = par->net; const struct xt_addrtype_info_v1 *info = par->matchinfo; const struct iphdr *iph; const struct net_device *dev = NULL; bool ret = true; if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN) dev = par->in; else if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) dev = par->out; #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) if (par->family == NFPROTO_IPV6) return addrtype_mt6(net, dev, skb, info); #endif iph = ip_hdr(skb); if (info->source) ret &= match_type(net, dev, iph->saddr, info->source) ^ (info->flags & XT_ADDRTYPE_INVERT_SOURCE); if (ret && info->dest) ret &= match_type(net, dev, iph->daddr, info->dest) ^ !!(info->flags & XT_ADDRTYPE_INVERT_DEST); return ret; }


laszlo attila tothlaszlo attila toth12566.49%111.11%
florian westphalflorian westphal3920.74%222.22%
alexey dobriyanalexey dobriyan126.38%111.11%
jan engelhardtjan engelhardt84.26%222.22%
anders grafstromanders grafstrom21.06%111.11%
igor maravicigor maravic10.53%111.11%
eric w. biedermaneric w. biederman10.53%111.11%

static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) { struct xt_addrtype_info_v1 *info = par->matchinfo; if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN && info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) { pr_info("both incoming and outgoing " "interface limitation cannot be selected\n"); return -EINVAL; } if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN)) && info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) { pr_info("output interface limitation " "not valid in PREROUTING and INPUT\n"); return -EINVAL; } if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) | (1 << NF_INET_LOCAL_OUT)) && info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN) { pr_info("input interface limitation " "not valid in POSTROUTING and OUTPUT\n"); return -EINVAL; } #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) if (par->family == NFPROTO_IPV6) { if ((info->source | info->dest) & XT_ADDRTYPE_BLACKHOLE) { pr_err("ipv6 BLACKHOLE matching not supported\n"); return -EINVAL; } if ((info->source | info->dest) >= XT_ADDRTYPE_PROHIBIT) { pr_err("ipv6 PROHIBIT (THROW, NAT ..) matching not supported\n"); return -EINVAL; } if ((info->source | info->dest) & XT_ADDRTYPE_BROADCAST) { pr_err("ipv6 does not support BROADCAST matching\n"); return -EINVAL; } } #endif return 0; }


florian westphalflorian westphal9643.84%222.22%
laszlo attila tothlaszlo attila toth8940.64%111.11%
jan engelhardtjan engelhardt3214.61%444.44%
phil oesterphil oester10.46%111.11%
igor maravicigor maravic10.46%111.11%

static struct xt_match addrtype_mt_reg[] __read_mostly = { { .name = "addrtype", .family = NFPROTO_IPV4, .match = addrtype_mt_v0, .matchsize = sizeof(struct xt_addrtype_info), .me = THIS_MODULE }, { .name = "addrtype", .family = NFPROTO_UNSPEC, .revision = 1, .match = addrtype_mt_v1, .checkentry = addrtype_mt_checkentry_v1, .matchsize = sizeof(struct xt_addrtype_info_v1), .me = THIS_MODULE } };
static int __init addrtype_mt_init(void) { return xt_register_matches(addrtype_mt_reg, ARRAY_SIZE(addrtype_mt_reg)); }


patrick mchardypatrick mchardy1260.00%133.33%
laszlo attila tothlaszlo attila toth630.00%133.33%
jan engelhardtjan engelhardt210.00%133.33%

static void __exit addrtype_mt_exit(void) { xt_unregister_matches(addrtype_mt_reg, ARRAY_SIZE(addrtype_mt_reg)); }


patrick mchardypatrick mchardy1157.89%133.33%
laszlo attila tothlaszlo attila toth631.58%133.33%
jan engelhardtjan engelhardt210.53%133.33%

module_init(addrtype_mt_init); module_exit(addrtype_mt_exit);

Overall Contributors

florian westphalflorian westphal64251.28%413.79%
laszlo attila tothlaszlo attila toth28422.68%13.45%
patrick mchardypatrick mchardy20116.05%413.79%
jan engelhardtjan engelhardt695.51%1034.48%
alexey dobriyanalexey dobriyan322.56%26.90%
martin kafai laumartin kafai lau100.80%13.45%
igor maravicigor maravic40.32%13.45%
arnaldo carvalho de meloarnaldo carvalho de melo30.24%13.45%
eric w. biedermaneric w. biederman30.24%26.90%
anders grafstromanders grafstrom20.16%13.45%
al viroal viro10.08%13.45%
phil oesterphil oester10.08%13.45%
Directory: net/netfilter
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.