cregit-Linux how code gets into the kernel

Release 4.8 net/ipv6/xfrm6_policy.c

Directory: net/ipv6
/*
 * xfrm6_policy.c: based on xfrm4_policy.c
 *
 * Authors:
 *      Mitsuru KANDA @USAGI
 *      Kazunori MIYAZAWA @USAGI
 *      Kunihiro Ishiguro <kunihiro@ipinfusion.com>
 *              IPv6 support
 *      YOSHIFUJI Hideaki
 *              Split up af-specific portion
 *
 */

#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <net/addrconf.h>
#include <net/dst.h>
#include <net/xfrm.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <net/ip6_route.h>
#include <net/l3mdev.h>
#if IS_ENABLED(CONFIG_IPV6_MIP6)
#include <net/mip6.h>
#endif


static struct xfrm_policy_afinfo xfrm6_policy_afinfo;


static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif, const xfrm_address_t *saddr, const xfrm_address_t *daddr) { struct flowi6 fl6; struct dst_entry *dst; int err; memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_oif = l3mdev_master_ifindex_by_index(net, oif); fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF; memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr)); if (saddr) memcpy(&fl6.saddr, saddr, sizeof(fl6.saddr)); dst = ip6_route_output(net, NULL, &fl6); err = dst->error; if (dst->error) { dst_release(dst); dst = ERR_PTR(err); } return dst; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu6543.33%19.09%
david s. millerdavid s. miller2718.00%218.18%
david aherndavid ahern2013.33%327.27%
ville nuorvalaville nuorvala1711.33%19.09%
hideaki yoshifujihideaki yoshifuji138.67%19.09%
alexey dobriyanalexey dobriyan64.00%19.09%
daniel lezcanodaniel lezcano10.67%19.09%
patrick mchardypatrick mchardy10.67%19.09%
Total150100.00%11100.00%


static int xfrm6_get_saddr(struct net *net, int oif, xfrm_address_t *saddr, xfrm_address_t *daddr) { struct dst_entry *dst; struct net_device *dev; dst = xfrm6_dst_lookup(net, 0, oif, NULL, daddr); if (IS_ERR(dst)) return -EHOSTUNREACH; dev = ip6_dst_idev(dst)->dev; ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6); dst_release(dst); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
patrick mchardypatrick mchardy4445.36%111.11%
herbert xuherbert xu1717.53%111.11%
brian haleybrian haley1616.49%111.11%
alexey dobriyanalexey dobriyan77.22%222.22%
hideaki yoshifujihideaki yoshifuji66.19%222.22%
david aherndavid ahern55.15%111.11%
jiri bencjiri benc22.06%111.11%
Total97100.00%9100.00%


static int xfrm6_get_tos(const struct flowi *fl) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu1386.67%133.33%
hideaki yoshifujihideaki yoshifuji16.67%133.33%
david s. millerdavid s. miller16.67%133.33%
Total15100.00%3100.00%


static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst, int nfheader_len) { if (dst->ops->family == AF_INET6) { struct rt6_info *rt = (struct rt6_info *)dst; path->path_cookie = rt6_get_cookie(rt); } path->u.rt6.rt6i_nfheader_len = nfheader_len; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
masahide nakamuramasahide nakamura6295.38%150.00%
martin kafai laumartin kafai lau34.62%150.00%
Total65100.00%2100.00%


static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, const struct flowi *fl) { struct rt6_info *rt = (struct rt6_info *)xdst->route; xdst->u.dst.dev = dev; dev_hold(dev); xdst->u.rt6.rt6i_idev = in6_dev_get(dev); if (!xdst->u.rt6.rt6i_idev) { dev_put(dev); return -ENODEV; } /* Sheit... I remember I did this right. Apparently, * it was magically lost, so this code needs audit */ xdst->u.rt6.rt6i_flags = rt->rt6i_flags & (RTF_ANYCAST | RTF_LOCAL); xdst->u.rt6.rt6i_metric = rt->rt6i_metric; xdst->u.rt6.rt6i_node = rt->rt6i_node; xdst->route_cookie = rt6_get_cookie(rt); xdst->u.rt6.rt6i_gateway = rt->rt6i_gateway; xdst->u.rt6.rt6i_dst = rt->rt6i_dst; xdst->u.rt6.rt6i_src = rt->rt6i_src; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
hideaki yoshifujihideaki yoshifuji7140.11%218.18%
herbert xuherbert xu6938.98%436.36%
tom lendackytom lendacky2011.30%19.09%
americo wangamerico wang73.95%19.09%
masahide nakamuramasahide nakamura63.39%19.09%
martin kafai laumartin kafai lau31.69%19.09%
david s. millerdavid s. miller10.56%19.09%
Total177100.00%11100.00%


static inline void _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) { struct flowi6 *fl6 = &fl->u.ip6; int onlyproto = 0; const struct ipv6hdr *hdr = ipv6_hdr(skb); u16 offset = sizeof(*hdr); struct ipv6_opt_hdr *exthdr; const unsigned char *nh = skb_network_header(skb); u16 nhoff = IP6CB(skb)->nhoff; int oif = 0; u8 nexthdr; if (!nhoff) nhoff = offsetof(struct ipv6hdr, nexthdr); nexthdr = nh[nhoff]; if (skb_dst(skb)) oif = l3mdev_fib_oif(skb_dst(skb)->dev); memset(fl6, 0, sizeof(struct flowi6)); fl6->flowi6_mark = skb->mark; fl6->flowi6_oif = reverse ? skb->skb_iif : oif; fl6->daddr = reverse ? hdr->saddr : hdr->daddr; fl6->saddr = reverse ? hdr->daddr : hdr->saddr; while (nh + offset + 1 < skb->data || pskb_may_pull(skb, nh + offset + 1 - skb->data)) { nh = skb_network_header(skb); exthdr = (struct ipv6_opt_hdr *)(nh + offset); switch (nexthdr) { case NEXTHDR_FRAGMENT: onlyproto = 1; case NEXTHDR_ROUTING: case NEXTHDR_HOP: case NEXTHDR_DEST: offset += ipv6_optlen(exthdr); nexthdr = exthdr->nexthdr; exthdr = (struct ipv6_opt_hdr *)(nh + offset); break; case IPPROTO_UDP: case IPPROTO_UDPLITE: case IPPROTO_TCP: case IPPROTO_SCTP: case IPPROTO_DCCP: if (!onlyproto && (nh + offset + 4 < skb->data || pskb_may_pull(skb, nh + offset + 4 - skb->data))) { __be16 *ports; nh = skb_network_header(skb); ports = (__be16 *)(nh + offset); fl6->fl6_sport = ports[!!reverse]; fl6->fl6_dport = ports[!reverse]; } fl6->flowi6_proto = nexthdr; return; case IPPROTO_ICMPV6: if (!onlyproto && (nh + offset + 2 < skb->data || pskb_may_pull(skb, nh + offset + 2 - skb->data))) { u8 *icmp; nh = skb_network_header(skb); icmp = (u8 *)(nh + offset); fl6->fl6_icmp_type = icmp[0]; fl6->fl6_icmp_code = icmp[1]; } fl6->flowi6_proto = nexthdr; return; #if IS_ENABLED(CONFIG_IPV6_MIP6) case IPPROTO_MH: offset += ipv6_optlen(exthdr); if (!onlyproto && (nh + offset + 3 < skb->data || pskb_may_pull(skb, nh + offset + 3 - skb->data))) { struct ip6_mh *mh; nh = skb_network_header(skb); mh = (struct ip6_mh *)(nh + offset); fl6->fl6_mh_type = mh->ip6mh_type; } fl6->flowi6_proto = nexthdr; return; #endif /* XXX Why are there these headers? */ case IPPROTO_AH: case IPPROTO_ESP: case IPPROTO_COMP: default: fl6->fl6_ipsec_spi = 0; fl6->flowi6_proto = nexthdr; return; } } }

Contributors

PersonTokensPropCommitsCommitProp
hideaki yoshifujihideaki yoshifuji18030.41%39.38%
masahide nakamuramasahide nakamura10117.06%39.38%
steffen klassertsteffen klassert6310.64%412.50%
david s. millerdavid s. miller488.11%39.38%
li rongqingli rongqing447.43%13.12%
herbert xuherbert xu315.24%26.25%
mathias krausemathias krause244.05%13.12%
wei yongjunwei yongjun223.72%13.12%
arnaldo carvalho de meloarnaldo carvalho de melo213.55%26.25%
nicolas dichtelnicolas dichtel213.55%13.12%
david aherndavid ahern91.52%26.25%
hajime tazakihajime tazaki71.18%13.12%
peter kosyhpeter kosyh61.01%13.12%
james morrisjames morris30.51%13.12%
gerrit renkergerrit renker30.51%13.12%
patrick mchardypatrick mchardy30.51%13.12%
alexey dobriyanalexey dobriyan20.34%13.12%
al viroal viro20.34%13.12%
eric dumazeteric dumazet10.17%13.12%
americo wangamerico wang10.17%13.12%
Total592100.00%32100.00%


static inline int xfrm6_garbage_collect(struct dst_ops *ops) { struct net *net = container_of(ops, struct net, xfrm.xfrm6_dst_ops); xfrm6_policy_afinfo.garbage_collect(net); return dst_entries_get_fast(ops) > ops->gc_thresh * 2; }

Contributors

PersonTokensPropCommitsCommitProp
alexey dobriyanalexey dobriyan2347.92%240.00%
hideaki yoshifujihideaki yoshifuji2041.67%120.00%
daniel lezcanodaniel lezcano48.33%120.00%
eric dumazeteric dumazet12.08%120.00%
Total48100.00%5100.00%


static void xfrm6_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 yoshifujihideaki yoshifuji3253.33%133.33%
david s. millerdavid s. miller1423.33%133.33%
herbert xuherbert xu1423.33%133.33%
Total60100.00%3100.00%


static void xfrm6_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. millerdavid s. miller55100.00%2100.00%
Total55100.00%2100.00%


static void xfrm6_dst_destroy(struct dst_entry *dst) { struct xfrm_dst *xdst = (struct xfrm_dst *)dst; if (likely(xdst->u.rt6.rt6i_idev)) in6_dev_put(xdst->u.rt6.rt6i_idev); dst_destroy_metrics_generic(dst); xfrm_dst_destroy(xdst); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu5291.23%150.00%
david s. millerdavid s. miller58.77%150.00%
Total57100.00%2100.00%


static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, int unregister) { struct xfrm_dst *xdst; if (!unregister) return; xdst = (struct xfrm_dst *)dst; if (xdst->u.rt6.rt6i_idev->dev == dev) { struct inet6_dev *loopback_idev = in6_dev_get(dev_net(dev)->loopback_dev); BUG_ON(!loopback_idev); do { in6_dev_put(xdst->u.rt6.rt6i_idev); xdst->u.rt6.rt6i_idev = loopback_idev; in6_dev_hold(loopback_idev); xdst = (struct xfrm_dst *)xdst->u.dst.child; } while (xdst->u.dst.xfrm); __in6_dev_put(loopback_idev); } xfrm_dst_ifdown(dst, dev); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu13896.50%133.33%
hideaki yoshifujihideaki yoshifuji32.10%133.33%
denis v. lunevdenis v. lunev21.40%133.33%
Total143100.00%3100.00%

static struct dst_ops xfrm6_dst_ops_template = { .family = AF_INET6, .gc = xfrm6_garbage_collect, .update_pmtu = xfrm6_update_pmtu, .redirect = xfrm6_redirect, .cow_metrics = dst_cow_metrics_generic, .destroy = xfrm6_dst_destroy, .ifdown = xfrm6_dst_ifdown, .local_out = __ip6_local_out, .gc_thresh = INT_MAX, }; static struct xfrm_policy_afinfo xfrm6_policy_afinfo = { .family = AF_INET6, .dst_ops = &xfrm6_dst_ops_template, .dst_lookup = xfrm6_dst_lookup, .get_saddr = xfrm6_get_saddr, .decode_session = _decode_session6, .get_tos = xfrm6_get_tos, .init_path = xfrm6_init_path, .fill_dst = xfrm6_fill_dst, .blackhole_route = ip6_blackhole_route, };
static int __init xfrm6_policy_init(void) { return xfrm_policy_register_afinfo(&xfrm6_policy_afinfo); }

Contributors

PersonTokensPropCommitsCommitProp
hideaki yoshifujihideaki yoshifuji1275.00%133.33%
daniel lezcanodaniel lezcano318.75%133.33%
patrick mchardypatrick mchardy16.25%133.33%
Total16100.00%3100.00%


static void xfrm6_policy_fini(void) { xfrm_policy_unregister_afinfo(&xfrm6_policy_afinfo); }

Contributors

PersonTokensPropCommitsCommitProp
hideaki yoshifujihideaki yoshifuji1392.86%150.00%
patrick mchardypatrick mchardy17.14%150.00%
Total14100.00%2100.00%

#ifdef CONFIG_SYSCTL static struct ctl_table xfrm6_policy_table[] = { { .procname = "xfrm6_gc_thresh", .data = &init_net.xfrm.xfrm6_dst_ops.gc_thresh, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec, }, { } };
static int __net_init xfrm6_net_sysctl_init(struct net *net) { struct ctl_table *table; struct ctl_table_header *hdr; table = xfrm6_policy_table; if (!net_eq(net, &init_net)) { table = kmemdup(table, sizeof(xfrm6_policy_table), GFP_KERNEL); if (!table) goto err_alloc; table[0].data = &net->xfrm.xfrm6_dst_ops.gc_thresh; } hdr = register_net_sysctl(net, "net/ipv6", table); if (!hdr) goto err_reg; net->ipv6.sysctl.xfrm6_hdr = hdr; return 0; err_reg: if (!net_eq(net, &init_net)) kfree(table); err_alloc: return -ENOMEM; }

Contributors

PersonTokensPropCommitsCommitProp
michal kubecekmichal kubecek12896.24%133.33%
neil hormanneil horman43.01%133.33%
dan streetmandan streetman10.75%133.33%
Total133100.00%3100.00%


static void __net_exit xfrm6_net_sysctl_exit(struct net *net) { struct ctl_table *table; if (!net->ipv6.sysctl.xfrm6_hdr) return; table = net->ipv6.sysctl.xfrm6_hdr->ctl_table_arg; unregister_net_sysctl_table(net->ipv6.sysctl.xfrm6_hdr); if (!net_eq(net, &init_net)) kfree(table); }

Contributors

PersonTokensPropCommitsCommitProp
michal kubecekmichal kubecek6697.06%133.33%
dan streetmandan streetman11.47%133.33%
ian morrisian morris11.47%133.33%
Total68100.00%3100.00%

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

Contributors

PersonTokensPropCommitsCommitProp
dan streetmandan streetman1493.33%150.00%
arnd bergmannarnd bergmann16.67%150.00%
Total15100.00%2100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
dan streetmandan streetman1090.91%150.00%
arnd bergmannarnd bergmann19.09%150.00%
Total11100.00%2100.00%

#endif
static int __net_init xfrm6_net_init(struct net *net) { int ret; memcpy(&net->xfrm.xfrm6_dst_ops, &xfrm6_dst_ops_template, sizeof(xfrm6_dst_ops_template)); ret = dst_entries_init(&net->xfrm.xfrm6_dst_ops); if (ret) return ret; ret = xfrm6_net_sysctl_init(net); if (ret) dst_entries_destroy(&net->xfrm.xfrm6_dst_ops); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
dan streetmandan streetman76100.00%1100.00%
Total76100.00%1100.00%


static void __net_exit xfrm6_net_exit(struct net *net) { xfrm6_net_sysctl_exit(net); dst_entries_destroy(&net->xfrm.xfrm6_dst_ops); }

Contributors

PersonTokensPropCommitsCommitProp
dan streetmandan streetman27100.00%1100.00%
Total27100.00%1100.00%

static struct pernet_operations xfrm6_net_ops = { .init = xfrm6_net_init, .exit = xfrm6_net_exit, };
int __init xfrm6_init(void) { int ret; ret = xfrm6_policy_init(); if (ret) goto out; ret = xfrm6_state_init(); if (ret) goto out_policy; ret = xfrm6_protocol_init(); if (ret) goto out_state; register_pernet_subsys(&xfrm6_net_ops); out: return ret; out_state: xfrm6_state_fini(); out_policy: xfrm6_policy_fini(); goto out; }

Contributors

PersonTokensPropCommitsCommitProp
daniel lezcanodaniel lezcano3549.30%120.00%
steffen klassertsteffen klassert1723.94%120.00%
hideaki yoshifujihideaki yoshifuji1318.31%120.00%
neil hormanneil horman45.63%120.00%
michal kubecekmichal kubecek22.82%120.00%
Total71100.00%5100.00%


void xfrm6_fini(void) { unregister_pernet_subsys(&xfrm6_net_ops); xfrm6_protocol_fini(); xfrm6_policy_fini(); xfrm6_state_fini(); }

Contributors

PersonTokensPropCommitsCommitProp
hideaki yoshifujihideaki yoshifuji1359.09%125.00%
michal kubecekmichal kubecek313.64%125.00%
steffen klassertsteffen klassert313.64%125.00%
neil hormanneil horman313.64%125.00%
Total22100.00%4100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
hideaki yoshifujihideaki yoshifuji44520.83%78.54%
herbert xuherbert xu43720.46%1113.41%
michal kubecekmichal kubecek21510.07%11.22%
masahide nakamuramasahide nakamura1848.61%44.88%
david s. millerdavid s. miller1697.91%1113.41%
dan streetmandan streetman1366.37%11.22%
steffen klassertsteffen klassert843.93%67.32%
patrick mchardypatrick mchardy582.72%33.66%
neil hormanneil horman552.57%11.22%
li rongqingli rongqing442.06%11.22%
daniel lezcanodaniel lezcano432.01%33.66%
alexey dobriyanalexey dobriyan421.97%56.10%
david aherndavid ahern371.73%56.10%
mathias krausemathias krause241.12%11.22%
wei yongjunwei yongjun221.03%11.22%
nicolas dichtelnicolas dichtel210.98%11.22%
arnaldo carvalho de meloarnaldo carvalho de melo210.98%22.44%
tom lendackytom lendacky200.94%11.22%
ville nuorvalaville nuorvala170.80%11.22%
brian haleybrian haley160.75%11.22%
americo wangamerico wang90.42%22.44%
hajime tazakihajime tazaki70.33%11.22%
peter kosyhpeter kosyh60.28%11.22%
martin kafai laumartin kafai lau60.28%11.22%
james morrisjames morris30.14%11.22%
gerrit renkergerrit renker30.14%11.22%
arnd bergmannarnd bergmann20.09%11.22%
al viroal viro20.09%11.22%
denis v. lunevdenis v. lunev20.09%11.22%
eric dumazeteric dumazet20.09%22.44%
ian morrisian morris20.09%22.44%
jiri bencjiri benc20.09%11.22%
Total2136100.00%82100.00%
Directory: net/ipv6
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.