cregit-Linux how code gets into the kernel

Release 4.14 net/xfrm/xfrm_device.c

Directory: net/xfrm
/*
 * xfrm_device.c - IPsec device offloading code.
 *
 * Copyright (c) 2015 secunet Security Networks AG
 *
 * Author:
 * Steffen Klassert <steffen.klassert@secunet.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <linux/errno.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <net/dst.h>
#include <net/xfrm.h>
#include <linux/notifier.h>

#ifdef CONFIG_XFRM_OFFLOAD

int validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features) { int err; struct xfrm_state *x; struct xfrm_offload *xo = xfrm_offload(skb); if (skb_is_gso(skb)) return 0; if (xo) { x = skb->sp->xvec[skb->sp->len - 1]; if (xo->flags & XFRM_GRO || x->xso.flags & XFRM_OFFLOAD_INBOUND) return 0; x->outer_mode->xmit(x, skb); err = x->type_offload->xmit(x, skb, features); if (err) { XFRM_INC_STATS(xs_net(x), LINUX_MIB_XFRMOUTSTATEPROTOERROR); return err; } skb_push(skb, skb->data - skb_mac_header(skb)); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Steffen Klassert145100.00%1100.00%
Total145100.00%1100.00%

EXPORT_SYMBOL_GPL(validate_xmit_xfrm);
int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo) { int err; struct dst_entry *dst; struct net_device *dev; struct xfrm_state_offload *xso = &x->xso; xfrm_address_t *saddr; xfrm_address_t *daddr; if (!x->type_offload) return -EINVAL; /* We don't yet support UDP encapsulation, TFC padding and ESN. */ if (x->encap || x->tfcpad || (x->props.flags & XFRM_STATE_ESN)) return 0; dev = dev_get_by_index(net, xuo->ifindex); if (!dev) { if (!(xuo->flags & XFRM_OFFLOAD_INBOUND)) { saddr = &x->props.saddr; daddr = &x->id.daddr; } else { saddr = &x->id.daddr; daddr = &x->props.saddr; } dst = __xfrm_dst_lookup(net, 0, 0, saddr, daddr, x->props.family, x->props.output_mark); if (IS_ERR(dst)) return 0; dev = dst->dev; dev_hold(dev); dst_release(dst); } if (!dev->xfrmdev_ops || !dev->xfrmdev_ops->xdo_dev_state_add) { xso->dev = NULL; dev_put(dev); return 0; } xso->dev = dev; xso->num_exthdrs = 1; xso->flags = xuo->flags; err = dev->xfrmdev_ops->xdo_dev_state_add(x); if (err) { dev_put(dev); return err; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Steffen Klassert27997.21%250.00%
Lorenzo Colitti62.09%125.00%
Ilan Tayari20.70%125.00%
Total287100.00%4100.00%

EXPORT_SYMBOL_GPL(xfrm_dev_state_add);
bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x) { int mtu; struct dst_entry *dst = skb_dst(skb); struct xfrm_dst *xdst = (struct xfrm_dst *)dst; struct net_device *dev = x->xso.dev; if (!x->type_offload || x->encap) return false; if ((x->xso.offload_handle && (dev == dst->path->dev)) && !dst->child->xfrm && x->type->get_mtu) { mtu = x->type->get_mtu(x, xdst->child_mtu_cached); if (skb->len <= mtu) goto ok; if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu)) goto ok; } return false; ok: if (dev && dev->xfrmdev_ops && dev->xfrmdev_ops->xdo_dev_offload_ok) return x->xso.dev->xfrmdev_ops->xdo_dev_offload_ok(skb, x); return true; }

Contributors

PersonTokensPropCommitsCommitProp
Steffen Klassert181100.00%1100.00%
Total181100.00%1100.00%

EXPORT_SYMBOL_GPL(xfrm_dev_offload_ok); #endif
static int xfrm_dev_register(struct net_device *dev) { if ((dev->features & NETIF_F_HW_ESP) && !dev->xfrmdev_ops) return NOTIFY_BAD; if ((dev->features & NETIF_F_HW_ESP_TX_CSUM) && !(dev->features & NETIF_F_HW_ESP)) return NOTIFY_BAD; return NOTIFY_DONE; }

Contributors

PersonTokensPropCommitsCommitProp
Steffen Klassert5398.15%150.00%
Wei Yongjun11.85%150.00%
Total54100.00%2100.00%


static int xfrm_dev_unregister(struct net_device *dev) { xfrm_policy_cache_flush(); return NOTIFY_DONE; }

Contributors

PersonTokensPropCommitsCommitProp
Steffen Klassert1482.35%150.00%
Florian Westphal317.65%150.00%
Total17100.00%2100.00%


static int xfrm_dev_feat_change(struct net_device *dev) { if ((dev->features & NETIF_F_HW_ESP) && !dev->xfrmdev_ops) return NOTIFY_BAD; else if (!(dev->features & NETIF_F_HW_ESP)) dev->xfrmdev_ops = NULL; if ((dev->features & NETIF_F_HW_ESP_TX_CSUM) && !(dev->features & NETIF_F_HW_ESP)) return NOTIFY_BAD; return NOTIFY_DONE; }

Contributors

PersonTokensPropCommitsCommitProp
Steffen Klassert72100.00%1100.00%
Total72100.00%1100.00%


static int xfrm_dev_down(struct net_device *dev) { if (dev->features & NETIF_F_HW_ESP) xfrm_dev_state_flush(dev_net(dev), dev, true); xfrm_policy_cache_flush(); return NOTIFY_DONE; }

Contributors

PersonTokensPropCommitsCommitProp
Steffen Klassert3389.19%133.33%
Florian Westphal38.11%133.33%
Ilan Tayari12.70%133.33%
Total37100.00%3100.00%


static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *dev = netdev_notifier_info_to_dev(ptr); switch (event) { case NETDEV_REGISTER: return xfrm_dev_register(dev); case NETDEV_UNREGISTER: return xfrm_dev_unregister(dev); case NETDEV_FEAT_CHANGE: return xfrm_dev_feat_change(dev); case NETDEV_DOWN: return xfrm_dev_down(dev); } return NOTIFY_DONE; }

Contributors

PersonTokensPropCommitsCommitProp
Steffen Klassert74100.00%2100.00%
Total74100.00%2100.00%

static struct notifier_block xfrm_dev_notifier = { .notifier_call = xfrm_dev_event, };
void __net_init xfrm_dev_init(void) { register_netdevice_notifier(&xfrm_dev_notifier); }

Contributors

PersonTokensPropCommitsCommitProp
Steffen Klassert14100.00%1100.00%
Total14100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Steffen Klassert92097.77%440.00%
Lorenzo Colitti60.64%110.00%
Florian Westphal60.64%110.00%
Hangbin Liu50.53%110.00%
Ilan Tayari30.32%220.00%
Wei Yongjun10.11%110.00%
Total941100.00%10100.00%
Directory: net/xfrm
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.