cregit-Linux how code gets into the kernel

Release 4.11 net/netfilter/xt_addrtype.c

Directory: net/netfilter
/*
 *  iptables module to match inet_addr_type() of an ip.
 *
 *  Copyright (c) 2004 Patrick McHardy <kaber@trash.net>
 *  (C) 2007 Laszlo Attila Toth <panther@balabit.hu>
 *
 *  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>

#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
#include <net/ipv6.h>
#include <net/ip6_route.h>
#include <net/ip6_fib.h>
#endif

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

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_DESCRIPTION("Xtables: address type match");
MODULE_ALIAS("ipt_addrtype");
MODULE_ALIAS("ip6t_addrtype");

#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)

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; }

Contributors

PersonTokensPropCommitsCommitProp
Florian Westphal23195.06%360.00%
Martin KaFai Lau104.12%120.00%
Alexey Dobriyan20.82%120.00%
Total243100.00%5100.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; }

Contributors

PersonTokensPropCommitsCommitProp
Florian Westphal118100.00%3100.00%
Total118100.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; }

Contributors

PersonTokensPropCommitsCommitProp
Florian Westphal116100.00%1100.00%
Total116100.00%1100.00%

#endif
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))); }

Contributors

PersonTokensPropCommitsCommitProp
Patrick McHardy2659.09%116.67%
Tóth László Attila920.45%116.67%
Alexey Dobriyan613.64%116.67%
Eric W. Biedermann12.27%116.67%
Jan Engelhardt12.27%116.67%
Al Viro12.27%116.67%
Total44100.00%6100.00%


static bool addrtype_mt_v0(const struct sk_buff *skb, struct xt_action_param *par) { struct net *net = xt_net(par); 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; }

Contributors

PersonTokensPropCommitsCommitProp
Patrick McHardy8072.73%220.00%
Alexey Dobriyan1110.00%110.00%
Jan Engelhardt76.36%330.00%
Tóth László Attila54.55%110.00%
Pablo Neira Ayuso32.73%110.00%
Arnaldo Carvalho de Melo32.73%110.00%
Florian Westphal10.91%110.00%
Total110100.00%10100.00%


static bool addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) { struct net *net = xt_net(par); 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 = xt_in(par); else if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) dev = xt_out(par); #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) if (xt_family(par) == 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; }

Contributors

PersonTokensPropCommitsCommitProp
Tóth László Attila12364.06%111.11%
Florian Westphal3719.27%222.22%
Pablo Neira Ayuso126.25%111.11%
Alexey Dobriyan115.73%111.11%
Jan Engelhardt63.12%222.22%
Anders Grafström21.04%111.11%
Igor Maravić10.52%111.11%
Total192100.00%9100.00%


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; }

Contributors

PersonTokensPropCommitsCommitProp
Florian Westphal9643.84%222.22%
Tóth László Attila8940.64%111.11%
Jan Engelhardt3214.61%444.44%
Phil Oester10.46%111.11%
Igor Maravić10.46%111.11%
Total219100.00%9100.00%

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)); }

Contributors

PersonTokensPropCommitsCommitProp
Patrick McHardy1260.00%133.33%
Tóth László Attila630.00%133.33%
Jan Engelhardt210.00%133.33%
Total20100.00%3100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Patrick McHardy1157.89%133.33%
Tóth László Attila631.58%133.33%
Jan Engelhardt210.53%133.33%
Total19100.00%3100.00%

module_init(addrtype_mt_init); module_exit(addrtype_mt_exit);

Overall Contributors

PersonTokensPropCommitsCommitProp
Florian Westphal64050.91%413.79%
Tóth László Attila28222.43%13.45%
Patrick McHardy20115.99%413.79%
Jan Engelhardt675.33%1034.48%
Alexey Dobriyan302.39%26.90%
Pablo Neira Ayuso151.19%13.45%
Martin KaFai Lau100.80%13.45%
Igor Maravić40.32%13.45%
Arnaldo Carvalho de Melo30.24%13.45%
Anders Grafström20.16%13.45%
Phil Oester10.08%13.45%
Al Viro10.08%13.45%
Eric W. Biedermann10.08%13.45%
Total1257100.00%29100.00%
Directory: net/netfilter
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.