cregit-Linux how code gets into the kernel

Release 4.11 net/ipv4/xfrm4_policy.c

Directory: net/ipv4
/*
 * xfrm4_policy.c
 *
 * Changes:
 *      Kazunori MIYAZAWA @USAGI
 *      YOSHIFUJI Hideaki @USAGI
 *              Split up af-specific portion
 *
 */

#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/inetdevice.h>
#include <linux/if_tunnel.h>
#include <net/dst.h>
#include <net/xfrm.h>
#include <net/ip.h>
#include <net/l3mdev.h>


static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4, int tos, int oif, const xfrm_address_t *saddr, const xfrm_address_t *daddr) { struct rtable *rt; memset(fl4, 0, sizeof(*fl4)); fl4->daddr = daddr->a4; fl4->flowi4_tos = tos; fl4->flowi4_oif = l3mdev_master_ifindex_by_index(net, oif); if (saddr) fl4->saddr = saddr->a4; fl4->flowi4_flags = FLOWI_FLAG_SKIP_NH_OIF; rt = __ip_route_output_key(net, fl4); if (!IS_ERR(rt)) return &rt->dst; return ERR_CAST(rt); }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller5141.13%433.33%
Herbert Xu3326.61%18.33%
David Ahern2016.13%325.00%
Hideaki Yoshifuji / 吉藤英明118.87%18.33%
Alexey Dobriyan64.84%18.33%
Changli Gao21.61%18.33%
Denis V. Lunev10.81%18.33%
Total124100.00%12100.00%


static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, int oif, const xfrm_address_t *saddr, const xfrm_address_t *daddr) { struct flowi4 fl4; return __xfrm4_dst_lookup(net, &fl4, tos, oif, saddr, daddr); }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller4590.00%150.00%
David Ahern510.00%150.00%
Total50100.00%2100.00%


static int xfrm4_get_saddr(struct net *net, int oif, xfrm_address_t *saddr, xfrm_address_t *daddr) { struct dst_entry *dst; struct flowi4 fl4; dst = __xfrm4_dst_lookup(net, &fl4, 0, oif, NULL, daddr); if (IS_ERR(dst)) return -EHOSTUNREACH; saddr->a4 = fl4.saddr; dst_release(dst); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Patrick McHardy3444.74%116.67%
Herbert Xu2127.63%116.67%
David S. Miller911.84%116.67%
Alexey Dobriyan79.21%233.33%
David Ahern56.58%116.67%
Total76100.00%6100.00%


static int xfrm4_get_tos(const struct flowi *fl) { return IPTOS_RT_MASK & fl->u.ip4.flowi4_tos; /* Strip ECN bits */ }

Contributors

PersonTokensPropCommitsCommitProp
Hideaki Yoshifuji / 吉藤英明937.50%116.67%
Herbert Xu625.00%233.33%
David S. Miller625.00%233.33%
Ulrich Weber312.50%116.67%
Total24100.00%6100.00%


static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, int nfheader_len) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Masahide Nakamura22100.00%1100.00%
Total22100.00%1100.00%


static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, const struct flowi *fl) { struct rtable *rt = (struct rtable *)xdst->route; const struct flowi4 *fl4 = &fl->u.ip4; xdst->u.rt.rt_iif = fl4->flowi4_iif; xdst->u.dst.dev = dev; dev_hold(dev); /* Sheit... I remember I did this right. Apparently, * it was magically lost, so this code needs audit */ xdst->u.rt.rt_is_input = rt->rt_is_input; xdst->u.rt.rt_flags = rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST | RTCF_LOCAL); xdst->u.rt.rt_type = rt->rt_type; xdst->u.rt.rt_gateway = rt->rt_gateway; xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway; xdst->u.rt.rt_pmtu = rt->rt_pmtu; xdst->u.rt.rt_table_id = rt->rt_table_id; INIT_LIST_HEAD(&xdst->u.rt.rt_uncached); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller5730.98%746.67%
Hideaki Yoshifuji / 吉藤英明5529.89%16.67%
Herbert Xu4021.74%426.67%
David Ahern126.52%16.67%
Julian Anastasov126.52%16.67%
Zheng Yan84.35%16.67%
Total184100.00%15100.00%


static void _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) { const struct iphdr *iph = ip_hdr(skb); u8 *xprth = skb_network_header(skb) + iph->ihl * 4; struct flowi4 *fl4 = &fl->u.ip4; int oif = 0; if (skb_dst(skb)) oif = skb_dst(skb)->dev->ifindex; memset(fl4, 0, sizeof(struct flowi4)); fl4->flowi4_mark = skb->mark; fl4->flowi4_oif = reverse ? skb->skb_iif : oif; if (!ip_is_fragment(iph)) { switch (iph->protocol) { case IPPROTO_UDP: case IPPROTO_UDPLITE: case IPPROTO_TCP: case IPPROTO_SCTP: case IPPROTO_DCCP: if (xprth + 4 < skb->data || pskb_may_pull(skb, xprth + 4 - skb->data)) { __be16 *ports; xprth = skb_network_header(skb) + iph->ihl * 4; ports = (__be16 *)xprth; fl4->fl4_sport = ports[!!reverse]; fl4->fl4_dport = ports[!reverse]; } break; case IPPROTO_ICMP: if (xprth + 2 < skb->data || pskb_may_pull(skb, xprth + 2 - skb->data)) { u8 *icmp; xprth = skb_network_header(skb) + iph->ihl * 4; icmp = xprth; fl4->fl4_icmp_type = icmp[0]; fl4->fl4_icmp_code = icmp[1]; } break; case IPPROTO_ESP: if (xprth + 4 < skb->data || pskb_may_pull(skb, xprth + 4 - skb->data)) { __be32 *ehdr; xprth = skb_network_header(skb) + iph->ihl * 4; ehdr = (__be32 *)xprth; fl4->fl4_ipsec_spi = ehdr[0]; } break; case IPPROTO_AH: if (xprth + 8 < skb->data || pskb_may_pull(skb, xprth + 8 - skb->data)) { __be32 *ah_hdr; xprth = skb_network_header(skb) + iph->ihl * 4; ah_hdr = (__be32 *)xprth; fl4->fl4_ipsec_spi = ah_hdr[1]; } break; case IPPROTO_COMP: if (xprth + 4 < skb->data || pskb_may_pull(skb, xprth + 4 - skb->data)) { __be16 *ipcomp_hdr; xprth = skb_network_header(skb) + iph->ihl * 4; ipcomp_hdr = (__be16 *)xprth; fl4->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); } break; case IPPROTO_GRE: if (xprth + 12 < skb->data || pskb_may_pull(skb, xprth + 12 - skb->data)) { __be16 *greflags; __be32 *gre_hdr; xprth = skb_network_header(skb) + iph->ihl * 4; greflags = (__be16 *)xprth; gre_hdr = (__be32 *)xprth; if (greflags[0] & GRE_KEY) { if (greflags[0] & GRE_CSUM) gre_hdr++; fl4->fl4_gre_key = gre_hdr[1]; } } break; default: fl4->fl4_ipsec_spi = 0; break; } } fl4->flowi4_proto = iph->protocol; fl4->daddr = reverse ? iph->saddr : iph->daddr; fl4->saddr = reverse ? iph->daddr : iph->saddr; fl4->flowi4_tos = iph->tos; }

Contributors

PersonTokensPropCommitsCommitProp
Hideaki Yoshifuji / 吉藤英明18829.79%13.85%
Steffen Klassert17527.73%415.38%
Timo Teräs6510.30%13.85%
David S. Miller426.66%27.69%
Masahide Nakamura396.18%13.85%
James Morris396.18%13.85%
Herbert Xu375.86%311.54%
Al Viro81.27%27.69%
Wei Yongjun81.27%13.85%
David Ahern81.27%27.69%
Arnaldo Carvalho de Melo60.95%27.69%
Peter Kosyh60.95%13.85%
Gerrit Renker30.48%13.85%
Patrick McHardy30.48%13.85%
Paul Gortmaker20.32%13.85%
Alexey Dobriyan10.16%13.85%
Eric Dumazet10.16%13.85%
Total631100.00%26100.00%


static inline int xfrm4_garbage_collect(struct dst_ops *ops) { struct net *net = container_of(ops, struct net, xfrm.xfrm4_dst_ops); xfrm_garbage_collect_deferred(net); return (dst_entries_get_slow(ops) > ops->gc_thresh * 2); }

Contributors

PersonTokensPropCommitsCommitProp
Alexey Dobriyan2347.92%233.33%
Hideaki Yoshifuji / 吉藤英明1939.58%116.67%
Daniel Lezcano48.33%116.67%
Eric Dumazet12.08%116.67%
Florian Westphal12.08%116.67%
Total48100.00%6100.00%


static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, u32 mtu) { struct xfrm_dst *xdst = (struct xfrm_dst *)dst; struct dst_entry *path = xdst->route; path->ops->update_pmtu(path, sk, skb, mtu); }

Contributors

PersonTokensPropCommitsCommitProp
Hideaki Yoshifuji / 吉藤英明3253.33%133.33%
David S. Miller1423.33%133.33%
Herbert Xu1423.33%133.33%
Total60100.00%3100.00%


static void xfrm4_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb) { struct xfrm_dst *xdst = (struct xfrm_dst *)dst; struct dst_entry *path = xdst->route; path->ops->redirect(path, sk, skb); }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller55100.00%2100.00%
Total55100.00%2100.00%


static void xfrm4_dst_destroy(struct dst_entry *dst) { struct xfrm_dst *xdst = (struct xfrm_dst *)dst; dst_destroy_metrics_generic(dst); xfrm_dst_destroy(xdst); }

Contributors

PersonTokensPropCommitsCommitProp
Herbert Xu2884.85%150.00%
David S. Miller515.15%150.00%
Total33100.00%2100.00%


static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, int unregister) { if (!unregister) return; xfrm_dst_ifdown(dst, dev); }

Contributors

PersonTokensPropCommitsCommitProp
Herbert Xu32100.00%1100.00%
Total32100.00%1100.00%

static struct dst_ops xfrm4_dst_ops_template = { .family = AF_INET, .gc = xfrm4_garbage_collect, .update_pmtu = xfrm4_update_pmtu, .redirect = xfrm4_redirect, .cow_metrics = dst_cow_metrics_generic, .destroy = xfrm4_dst_destroy, .ifdown = xfrm4_dst_ifdown, .local_out = __ip_local_out, .gc_thresh = INT_MAX, }; static const struct xfrm_policy_afinfo xfrm4_policy_afinfo = { .dst_ops = &xfrm4_dst_ops_template, .dst_lookup = xfrm4_dst_lookup, .get_saddr = xfrm4_get_saddr, .decode_session = _decode_session4, .get_tos = xfrm4_get_tos, .init_path = xfrm4_init_path, .fill_dst = xfrm4_fill_dst, .blackhole_route = ipv4_blackhole_route, }; #ifdef CONFIG_SYSCTL static struct ctl_table xfrm4_policy_table[] = { { .procname = "xfrm4_gc_thresh", .data = &init_net.xfrm.xfrm4_dst_ops.gc_thresh, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec, }, { } };
static __net_init int xfrm4_net_sysctl_init(struct net *net) { struct ctl_table *table; struct ctl_table_header *hdr; table = xfrm4_policy_table; if (!net_eq(net, &init_net)) { table = kmemdup(table, sizeof(xfrm4_policy_table), GFP_KERNEL); if (!table) goto err_alloc; table[0].data = &net->xfrm.xfrm4_dst_ops.gc_thresh; } hdr = register_net_sysctl(net, "net/ipv4", table); if (!hdr) goto err_reg; net->ipv4.xfrm4_hdr = hdr; return 0; err_reg: if (!net_eq(net, &init_net)) kfree(table); err_alloc: return -ENOMEM; }

Contributors

PersonTokensPropCommitsCommitProp
Michal Kubeček12595.42%125.00%
Neil Horman43.05%125.00%
Dan Streetman10.76%125.00%
Arnd Bergmann10.76%125.00%
Total131100.00%4100.00%


static __net_exit void xfrm4_net_sysctl_exit(struct net *net) { struct ctl_table *table; if (!net->ipv4.xfrm4_hdr) return; table = net->ipv4.xfrm4_hdr->ctl_table_arg; unregister_net_sysctl_table(net->ipv4.xfrm4_hdr); if (!net_eq(net, &init_net)) kfree(table); }

Contributors

PersonTokensPropCommitsCommitProp
Michal Kubeček5995.16%125.00%
Ian Morris11.61%125.00%
Dan Streetman11.61%125.00%
Arnd Bergmann11.61%125.00%
Total62100.00%4100.00%

#else /* CONFIG_SYSCTL */
static inline int xfrm4_net_sysctl_init(struct net *net) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Dan Streetman1493.33%150.00%
Arnd Bergmann16.67%150.00%
Total15100.00%2100.00%


static inline void xfrm4_net_sysctl_exit(struct net *net) { }

Contributors

PersonTokensPropCommitsCommitProp
Dan Streetman1090.91%150.00%
Arnd Bergmann19.09%150.00%
Total11100.00%2100.00%

#endif
static int __net_init xfrm4_net_init(struct net *net) { int ret; memcpy(&net->xfrm.xfrm4_dst_ops, &xfrm4_dst_ops_template, sizeof(xfrm4_dst_ops_template)); ret = dst_entries_init(&net->xfrm.xfrm4_dst_ops); if (ret) return ret; ret = xfrm4_net_sysctl_init(net); if (ret) dst_entries_destroy(&net->xfrm.xfrm4_dst_ops); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Dan Streetman76100.00%1100.00%
Total76100.00%1100.00%


static void __net_exit xfrm4_net_exit(struct net *net) { xfrm4_net_sysctl_exit(net); dst_entries_destroy(&net->xfrm.xfrm4_dst_ops); }

Contributors

PersonTokensPropCommitsCommitProp
Dan Streetman27100.00%1100.00%
Total27100.00%1100.00%

static struct pernet_operations __net_initdata xfrm4_net_ops = { .init = xfrm4_net_init, .exit = xfrm4_net_exit, };
static void __init xfrm4_policy_init(void) { xfrm_policy_register_afinfo(&xfrm4_policy_afinfo, AF_INET); }

Contributors

PersonTokensPropCommitsCommitProp
Hideaki Yoshifuji / 吉藤英明1482.35%133.33%
Florian Westphal211.76%133.33%
Patrick McHardy15.88%133.33%
Total17100.00%3100.00%


void __init xfrm4_init(void) { xfrm4_state_init(); xfrm4_policy_init(); xfrm4_protocol_init(); register_pernet_subsys(&xfrm4_net_ops); }

Contributors

PersonTokensPropCommitsCommitProp
Hideaki Yoshifuji / 吉藤英明730.43%116.67%
Alexey Dobriyan626.09%116.67%
Neil Horman417.39%116.67%
Steffen Klassert417.39%233.33%
Michal Kubeček28.70%116.67%
Total23100.00%6100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Hideaki Yoshifuji / 吉藤英明38820.42%22.44%
David S. Miller29915.74%1720.73%
Herbert Xu24713.00%1214.63%
Michal Kubeček20310.68%11.22%
Steffen Klassert1809.47%78.54%
Dan Streetman1367.16%11.22%
Timo Teräs683.58%11.22%
Masahide Nakamura663.47%22.44%
David Ahern532.79%78.54%
Neil Horman522.74%11.22%
Alexey Dobriyan472.47%56.10%
Patrick McHardy452.37%33.66%
James Morris392.05%11.22%
Julian Anastasov120.63%11.22%
Zheng Yan80.42%11.22%
Al Viro80.42%22.44%
Wei Yongjun80.42%11.22%
Arnaldo Carvalho de Melo60.32%22.44%
Peter Kosyh60.32%11.22%
Florian Westphal40.21%33.66%
Daniel Lezcano40.21%11.22%
Arnd Bergmann40.21%11.22%
Gerrit Renker30.16%11.22%
Ulrich Weber30.16%11.22%
Randy Dunlap30.16%11.22%
Changli Gao20.11%11.22%
Eric Dumazet20.11%22.44%
Paul Gortmaker20.11%11.22%
Denis V. Lunev10.05%11.22%
Ian Morris10.05%11.22%
Total1900100.00%82100.00%
Directory: net/ipv4
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.