cregit-Linux how code gets into the kernel

Release 4.15 net/ipv4/xfrm4_policy.c

Directory: net/ipv4
// SPDX-License-Identifier: GPL-2.0
/*
 * 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, u32 mark) { 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); fl4->flowi4_mark = mark; 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. Miller5138.35%430.77%
Herbert Xu3324.81%17.69%
David Ahern2015.04%323.08%
Hideaki Yoshifuji / 吉藤英明118.27%17.69%
Lorenzo Colitti96.77%17.69%
Alexey Dobriyan64.51%17.69%
Changli Gao21.50%17.69%
Denis V. Lunev10.75%17.69%
Total133100.00%13100.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, u32 mark) { struct flowi4 fl4; return __xfrm4_dst_lookup(net, &fl4, tos, oif, saddr, daddr, mark); }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller4581.82%133.33%
David Ahern59.09%133.33%
Lorenzo Colitti59.09%133.33%
Total55100.00%3100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Patrick McHardy3441.98%114.29%
Herbert Xu2125.93%114.29%
David S. Miller911.11%114.29%
Alexey Dobriyan78.64%228.57%
David Ahern56.17%114.29%
Lorenzo Colitti56.17%114.29%
Total81100.00%7100.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%
James Morris396.18%13.85%
Masahide Nakamura396.18%13.85%
Herbert Xu375.86%311.54%
Al Viro81.27%27.69%
David Ahern81.27%27.69%
Wei Yongjun81.27%13.85%
Peter Kosyh60.95%13.85%
Arnaldo Carvalho de Melo60.95%27.69%
Patrick McHardy30.48%13.85%
Gerrit Renker30.48%13.85%
Paul Gortmaker20.32%13.85%
Alexey Dobriyan10.16%13.85%
Eric Dumazet10.16%13.85%
Total631100.00%26100.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, .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 = 32768, }; 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%
Arnd Bergmann10.76%125.00%
Dan Streetman10.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%
Dan Streetman11.61%125.00%
Arnd Bergmann11.61%125.00%
Ian Morris11.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%
Steffen Klassert417.39%233.33%
Neil Horman417.39%116.67%
Michal Kubeček28.70%116.67%
Total23100.00%6100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Hideaki Yoshifuji / 吉藤英明36419.50%22.50%
David S. Miller29916.01%1721.25%
Herbert Xu24713.23%1215.00%
Michal Kubeček20310.87%11.25%
Steffen Klassert1799.59%67.50%
Dan Streetman1367.28%11.25%
Timo Teräs683.64%11.25%
Masahide Nakamura663.54%22.50%
David Ahern532.84%78.75%
Neil Horman522.79%11.25%
Patrick McHardy452.41%33.75%
James Morris392.09%11.25%
Alexey Dobriyan241.29%45.00%
Lorenzo Colitti191.02%11.25%
Julian Anastasov120.64%11.25%
Wei Yongjun80.43%11.25%
Zheng Yan80.43%11.25%
Al Viro80.43%22.50%
Arnaldo Carvalho de Melo60.32%22.50%
Peter Kosyh60.32%11.25%
Arnd Bergmann40.21%11.25%
Florian Westphal40.21%33.75%
Randy Dunlap30.16%11.25%
Gerrit Renker30.16%11.25%
Ulrich Weber30.16%11.25%
Paul Gortmaker20.11%11.25%
Changli Gao20.11%11.25%
Eric Dumazet10.05%11.25%
Greg Kroah-Hartman10.05%11.25%
Ian Morris10.05%11.25%
Denis V. Lunev10.05%11.25%
Total1867100.00%80100.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.