cregit-Linux how code gets into the kernel

Release 4.11 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 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 Xu6543.33%19.09%
David S. Miller2718.00%218.18%
David Ahern2013.33%327.27%
Ville Nuorvala1711.33%19.09%
Hideaki Yoshifuji / 吉藤英明138.67%19.09%
Alexey Dobriyan64.00%19.09%
Patrick McHardy10.67%19.09%
Daniel Lezcano10.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 McHardy4445.36%111.11%
Herbert Xu1717.53%111.11%
Brian Haley1616.49%111.11%
Alexey Dobriyan77.22%222.22%
Hideaki Yoshifuji / 吉藤英明66.19%222.22%
David Ahern55.15%111.11%
Jiri Benc22.06%111.11%
Total97100.00%9100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Herbert Xu1386.67%133.33%
Hideaki Yoshifuji / 吉藤英明16.67%133.33%
David 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 Nakamura6295.38%150.00%
Martin 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 Yoshifuji / 吉藤英明7140.11%218.18%
Herbert Xu6938.98%436.36%
Tom Lendacky2011.30%19.09%
Américo Wang73.95%19.09%
Masahide Nakamura63.39%19.09%
Martin KaFai Lau31.69%19.09%
David 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 = skb_dst(skb)->dev->ifindex; 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 Yoshifuji / 吉藤英明18030.46%39.38%
Masahide Nakamura10117.09%39.38%
Steffen Klassert6310.66%412.50%
David S. Miller488.12%39.38%
Li RongQing447.45%13.12%
Herbert Xu315.25%26.25%
Mathias Krause244.06%13.12%
Wei Yongjun223.72%13.12%
Arnaldo Carvalho de Melo213.55%26.25%
Nicolas Dichtel213.55%13.12%
David Ahern81.35%26.25%
Hajime Tazaki71.18%13.12%
Peter Kosyh61.02%13.12%
James Morris30.51%13.12%
Gerrit Renker30.51%13.12%
Patrick McHardy30.51%13.12%
Al Viro20.34%13.12%
Alexey Dobriyan20.34%13.12%
Américo Wang10.17%13.12%
Eric Dumazet10.17%13.12%
Total591100.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); xfrm_garbage_collect_deferred(net); return dst_entries_get_fast(ops) > ops->gc_thresh * 2; }

Contributors

PersonTokensPropCommitsCommitProp
Alexey Dobriyan2350.00%233.33%
Hideaki Yoshifuji / 吉藤英明1736.96%116.67%
Daniel Lezcano48.70%116.67%
Florian Westphal12.17%116.67%
Eric Dumazet12.17%116.67%
Total46100.00%6100.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 Yoshifuji / 吉藤英明3253.33%133.33%
David S. Miller1423.33%133.33%
Herbert 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. 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 Xu5291.23%150.00%
David 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 Xu13896.50%133.33%
Hideaki Yoshifuji / 吉藤英明32.10%133.33%
Denis 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 const struct xfrm_policy_afinfo xfrm6_policy_afinfo = { .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, AF_INET6); }

Contributors

PersonTokensPropCommitsCommitProp
Hideaki Yoshifuji / 吉藤英明1266.67%125.00%
Daniel Lezcano316.67%125.00%
Florian Westphal211.11%125.00%
Patrick McHardy15.56%125.00%
Total18100.00%4100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Hideaki Yoshifuji / 吉藤英明1392.86%150.00%
Patrick 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 Kubeček12896.24%133.33%
Neil Horman43.01%133.33%
Dan 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 Kubeček6697.06%133.33%
Dan Streetman11.47%133.33%
Ian 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 Streetman1493.33%150.00%
Arnd Bergmann16.67%150.00%
Total15100.00%2100.00%


static inline void xfrm6_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 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 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 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 Lezcano3549.30%120.00%
Steffen Klassert1723.94%120.00%
Hideaki Yoshifuji / 吉藤英明1318.31%120.00%
Neil Horman45.63%120.00%
Michal Kubeček22.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 Yoshifuji / 吉藤英明1359.09%125.00%
Michal Kubeček313.64%125.00%
Steffen Klassert313.64%125.00%
Neil Horman313.64%125.00%
Total22100.00%4100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Herbert Xu43720.56%1112.79%
Hideaki Yoshifuji / 吉藤英明43320.37%78.14%
Michal Kubeček21510.11%11.16%
Masahide Nakamura1848.65%44.65%
David S. Miller1697.95%1112.79%
Dan Streetman1366.40%11.16%
Steffen Klassert843.95%66.98%
Patrick McHardy572.68%33.49%
Neil Horman552.59%11.16%
Li RongQing442.07%11.16%
Daniel Lezcano432.02%33.49%
Alexey Dobriyan421.98%55.81%
David Ahern361.69%66.98%
Mathias Krause241.13%11.16%
Wei Yongjun221.03%11.16%
Arnaldo Carvalho de Melo210.99%22.33%
Nicolas Dichtel210.99%11.16%
Tom Lendacky200.94%11.16%
Ville Nuorvala170.80%11.16%
Brian Haley160.75%11.16%
Américo Wang90.42%22.33%
Hajime Tazaki70.33%11.16%
Peter Kosyh60.28%11.16%
Martin KaFai Lau60.28%11.16%
Florian Westphal40.19%33.49%
James Morris30.14%11.16%
Gerrit Renker30.14%11.16%
Ian Morris20.09%22.33%
Al Viro20.09%11.16%
Eric Dumazet20.09%22.33%
Arnd Bergmann20.09%11.16%
Denis V. Lunev20.09%11.16%
Jiri Benc20.09%11.16%
Total2126100.00%86100.00%
Directory: net/ipv6
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.