mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
This merge resolves conflicts with 75aec9df3a ("bridge: Remove
br_nf_push_frag_xmit_sk") as part of Eric Biederman's effort to improve
netns support in the network stack that reached upstream via David's
net-next tree.
Signed-off-by: Pablo Neira Ayuso <[email protected]>
Conflicts:
net/bridge/br_netfilter_hooks.c
This commit is contained in:
commit
f0a0a978b6
620 changed files with 23881 additions and 7357 deletions
|
|
@ -81,6 +81,7 @@
|
|||
#include <net/ip.h>
|
||||
#include <net/netlink.h>
|
||||
#include <net/pkt_sched.h>
|
||||
#include <net/l3mdev.h>
|
||||
#include <linux/if_tunnel.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/netconf.h>
|
||||
|
|
@ -2146,7 +2147,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
|
|||
unsigned long expires, u32 flags)
|
||||
{
|
||||
struct fib6_config cfg = {
|
||||
.fc_table = RT6_TABLE_PREFIX,
|
||||
.fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_PREFIX,
|
||||
.fc_metric = IP6_RT_PRIO_ADDRCONF,
|
||||
.fc_ifindex = dev->ifindex,
|
||||
.fc_expires = expires,
|
||||
|
|
@ -2179,8 +2180,9 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
|
|||
struct fib6_node *fn;
|
||||
struct rt6_info *rt = NULL;
|
||||
struct fib6_table *table;
|
||||
u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_PREFIX;
|
||||
|
||||
table = fib6_get_table(dev_net(dev), RT6_TABLE_PREFIX);
|
||||
table = fib6_get_table(dev_net(dev), tb_id);
|
||||
if (!table)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -2211,7 +2213,7 @@ out:
|
|||
static void addrconf_add_mroute(struct net_device *dev)
|
||||
{
|
||||
struct fib6_config cfg = {
|
||||
.fc_table = RT6_TABLE_LOCAL,
|
||||
.fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_LOCAL,
|
||||
.fc_metric = IP6_RT_PRIO_ADDRCONF,
|
||||
.fc_ifindex = dev->ifindex,
|
||||
.fc_dst_len = 8,
|
||||
|
|
@ -3029,6 +3031,10 @@ static void addrconf_addr_gen(struct inet6_dev *idev, bool prefix_route)
|
|||
{
|
||||
struct in6_addr addr;
|
||||
|
||||
/* no link local addresses on L3 master devices */
|
||||
if (netif_is_l3_master(idev->dev))
|
||||
return;
|
||||
|
||||
ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0);
|
||||
|
||||
if (idev->addr_gen_mode == IN6_ADDR_GEN_MODE_STABLE_PRIVACY) {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@
|
|||
#include <net/xfrm.h>
|
||||
#include <net/inet_common.h>
|
||||
#include <net/dsfield.h>
|
||||
#include <net/l3mdev.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
|
|
@ -496,6 +497,9 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
|
|||
else if (!fl6.flowi6_oif)
|
||||
fl6.flowi6_oif = np->ucast_oif;
|
||||
|
||||
if (!fl6.flowi6_oif)
|
||||
fl6.flowi6_oif = l3mdev_master_ifindex(skb->dev);
|
||||
|
||||
dst = icmpv6_route_lookup(net, skb, sk, &fl6);
|
||||
if (IS_ERR(dst))
|
||||
goto out;
|
||||
|
|
@ -575,7 +579,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
|
|||
fl6.daddr = ipv6_hdr(skb)->saddr;
|
||||
if (saddr)
|
||||
fl6.saddr = *saddr;
|
||||
fl6.flowi6_oif = skb->dev->ifindex;
|
||||
fl6.flowi6_oif = l3mdev_fib_oif(skb->dev);
|
||||
fl6.fl6_icmp_type = ICMPV6_ECHO_REPLY;
|
||||
fl6.flowi6_mark = mark;
|
||||
security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ static void update_ipv6_locator(struct sk_buff *skb, struct ila_params *p)
|
|||
*(__be64 *)&ip6h->daddr = p->locator;
|
||||
}
|
||||
|
||||
static int ila_output(struct sock *sk, struct sk_buff *skb)
|
||||
static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct dst_entry *dst = skb_dst(skb);
|
||||
|
||||
|
|
@ -100,7 +100,7 @@ static int ila_output(struct sock *sk, struct sk_buff *skb)
|
|||
|
||||
update_ipv6_locator(skb, ila_params_lwtunnel(dst->lwtstate));
|
||||
|
||||
return dst->lwtstate->orig_output(sk, skb);
|
||||
return dst->lwtstate->orig_output(net, sk, skb);
|
||||
|
||||
drop:
|
||||
kfree_skb(skb);
|
||||
|
|
|
|||
|
|
@ -114,6 +114,8 @@ static inline int compute_score(struct sock *sk, struct net *net,
|
|||
return -1;
|
||||
score++;
|
||||
}
|
||||
if (sk->sk_incoming_cpu == raw_smp_processor_id())
|
||||
score++;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,6 +264,7 @@ struct fib6_table *fib6_get_table(struct net *net, u32 id)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fib6_get_table);
|
||||
|
||||
static void __net_init fib6_tables_init(struct net *net)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,12 +55,12 @@
|
|||
#include <net/xfrm.h>
|
||||
#include <net/checksum.h>
|
||||
#include <linux/mroute6.h>
|
||||
#include <net/l3mdev.h>
|
||||
|
||||
static int ip6_finish_output2(struct sock *sk, struct sk_buff *skb)
|
||||
static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct dst_entry *dst = skb_dst(skb);
|
||||
struct net_device *dev = dst->dev;
|
||||
struct net *net = dev_net(dev);
|
||||
struct neighbour *neigh;
|
||||
struct in6_addr *nexthop;
|
||||
int ret;
|
||||
|
|
@ -126,16 +126,15 @@ static int ip6_finish_output(struct net *net, struct sock *sk, struct sk_buff *s
|
|||
if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
|
||||
dst_allfrag(skb_dst(skb)) ||
|
||||
(IP6CB(skb)->frag_max_size && skb->len > IP6CB(skb)->frag_max_size))
|
||||
return ip6_fragment(sk, skb, ip6_finish_output2);
|
||||
return ip6_fragment(net, sk, skb, ip6_finish_output2);
|
||||
else
|
||||
return ip6_finish_output2(sk, skb);
|
||||
return ip6_finish_output2(net, sk, skb);
|
||||
}
|
||||
|
||||
int ip6_output(struct sock *sk, struct sk_buff *skb)
|
||||
int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct net_device *dev = skb_dst(skb)->dev;
|
||||
struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
|
||||
struct net *net = dev_net(dev);
|
||||
|
||||
if (unlikely(idev->cnf.disable_ipv6)) {
|
||||
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
|
||||
|
|
@ -234,7 +233,7 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
|
|||
*/
|
||||
return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
|
||||
net, (struct sock *)sk, skb, NULL, dst->dev,
|
||||
dst_output_okfn);
|
||||
dst_output);
|
||||
}
|
||||
|
||||
skb->dev = dst->dev;
|
||||
|
|
@ -334,7 +333,7 @@ static inline int ip6_forward_finish(struct net *net, struct sock *sk,
|
|||
struct sk_buff *skb)
|
||||
{
|
||||
skb_sender_cpu_clear(skb);
|
||||
return dst_output(sk, skb);
|
||||
return dst_output(net, sk, skb);
|
||||
}
|
||||
|
||||
static unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst)
|
||||
|
|
@ -554,8 +553,8 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
|
|||
skb_copy_secmark(to, from);
|
||||
}
|
||||
|
||||
int ip6_fragment(struct sock *sk, struct sk_buff *skb,
|
||||
int (*output)(struct sock *, struct sk_buff *))
|
||||
int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
||||
int (*output)(struct net *, struct sock *, struct sk_buff *))
|
||||
{
|
||||
struct sk_buff *frag;
|
||||
struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
|
||||
|
|
@ -568,7 +567,6 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
|
|||
__be32 frag_id;
|
||||
int ptr, offset = 0, err = 0;
|
||||
u8 *prevhdr, nexthdr = 0;
|
||||
struct net *net = dev_net(skb_dst(skb)->dev);
|
||||
|
||||
hlen = ip6_find_1stfragopt(skb, &prevhdr);
|
||||
nexthdr = *prevhdr;
|
||||
|
|
@ -688,7 +686,7 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
|
|||
ip6_copy_metadata(frag, skb);
|
||||
}
|
||||
|
||||
err = output(sk, skb);
|
||||
err = output(net, sk, skb);
|
||||
if (!err)
|
||||
IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
|
||||
IPSTATS_MIB_FRAGCREATES);
|
||||
|
|
@ -816,7 +814,7 @@ slow_path:
|
|||
/*
|
||||
* Put this fragment into the sending queue.
|
||||
*/
|
||||
err = output(sk, frag);
|
||||
err = output(net, sk, frag);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
|
|
@ -888,7 +886,8 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
|
|||
#ifdef CONFIG_IPV6_SUBTREES
|
||||
ip6_rt_check(&rt->rt6i_src, &fl6->saddr, np->saddr_cache) ||
|
||||
#endif
|
||||
(fl6->flowi6_oif && fl6->flowi6_oif != dst->dev->ifindex)) {
|
||||
(!(fl6->flowi6_flags & FLOWI_FLAG_SKIP_NH_OIF) &&
|
||||
(fl6->flowi6_oif && fl6->flowi6_oif != dst->dev->ifindex))) {
|
||||
dst_release(dst);
|
||||
dst = NULL;
|
||||
}
|
||||
|
|
@ -1040,7 +1039,7 @@ struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6,
|
|||
if (final_dst)
|
||||
fl6->daddr = *final_dst;
|
||||
if (!fl6->flowi6_oif)
|
||||
fl6->flowi6_oif = dst->dev->ifindex;
|
||||
fl6->flowi6_oif = l3mdev_fib_oif(dst->dev);
|
||||
|
||||
return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
|
||||
}
|
||||
|
|
@ -1694,7 +1693,7 @@ int ip6_send_skb(struct sk_buff *skb)
|
|||
struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
|
||||
int err;
|
||||
|
||||
err = ip6_local_out(skb);
|
||||
err = ip6_local_out(net, skb->sk, skb);
|
||||
if (err) {
|
||||
if (err > 0)
|
||||
err = net_xmit_errno(err);
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
|
|||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
err = dst_output(skb->sk, skb);
|
||||
err = dst_output(t->net, skb->sk, skb);
|
||||
if (net_xmit_eval(err) == 0) {
|
||||
struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
|
||||
|
||||
|
|
|
|||
|
|
@ -1991,7 +1991,7 @@ static inline int ip6mr_forward2_finish(struct net *net, struct sock *sk, struct
|
|||
IPSTATS_MIB_OUTFORWDATAGRAMS);
|
||||
IP6_ADD_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
|
||||
IPSTATS_MIB_OUTOCTETS, skb->len);
|
||||
return dst_output(sk, skb);
|
||||
return dst_output(net, sk, skb);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1646,7 +1646,7 @@ static void mld_sendpack(struct sk_buff *skb)
|
|||
|
||||
err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
|
||||
net, net->ipv6.igmp_sk, skb, NULL, skb->dev,
|
||||
dst_output_okfn);
|
||||
dst_output);
|
||||
out:
|
||||
if (!err) {
|
||||
ICMP6MSGOUT_INC_STATS(net, idev, ICMPV6_MLD2_REPORT);
|
||||
|
|
@ -2010,7 +2010,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
|
|||
skb_dst_set(skb, dst);
|
||||
err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
|
||||
net, sk, skb, NULL, skb->dev,
|
||||
dst_output_okfn);
|
||||
dst_output);
|
||||
out:
|
||||
if (!err) {
|
||||
ICMP6MSGOUT_INC_STATS(net, idev, type);
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ static int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
|
|||
|
||||
struct mip6_report_rate_limiter {
|
||||
spinlock_t lock;
|
||||
struct timeval stamp;
|
||||
ktime_t stamp;
|
||||
int iif;
|
||||
struct in6_addr src;
|
||||
struct in6_addr dst;
|
||||
|
|
@ -184,20 +184,18 @@ static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int mip6_report_rl_allow(struct timeval *stamp,
|
||||
static inline int mip6_report_rl_allow(ktime_t stamp,
|
||||
const struct in6_addr *dst,
|
||||
const struct in6_addr *src, int iif)
|
||||
{
|
||||
int allow = 0;
|
||||
|
||||
spin_lock_bh(&mip6_report_rl.lock);
|
||||
if (mip6_report_rl.stamp.tv_sec != stamp->tv_sec ||
|
||||
mip6_report_rl.stamp.tv_usec != stamp->tv_usec ||
|
||||
if (!ktime_equal(mip6_report_rl.stamp, stamp) ||
|
||||
mip6_report_rl.iif != iif ||
|
||||
!ipv6_addr_equal(&mip6_report_rl.src, src) ||
|
||||
!ipv6_addr_equal(&mip6_report_rl.dst, dst)) {
|
||||
mip6_report_rl.stamp.tv_sec = stamp->tv_sec;
|
||||
mip6_report_rl.stamp.tv_usec = stamp->tv_usec;
|
||||
mip6_report_rl.stamp = stamp;
|
||||
mip6_report_rl.iif = iif;
|
||||
mip6_report_rl.src = *src;
|
||||
mip6_report_rl.dst = *dst;
|
||||
|
|
@ -216,7 +214,7 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb,
|
|||
struct ipv6_destopt_hao *hao = NULL;
|
||||
struct xfrm_selector sel;
|
||||
int offset;
|
||||
struct timeval stamp;
|
||||
ktime_t stamp;
|
||||
int err = 0;
|
||||
|
||||
if (unlikely(fl6->flowi6_proto == IPPROTO_MH &&
|
||||
|
|
@ -230,9 +228,9 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb,
|
|||
(skb_network_header(skb) + offset);
|
||||
}
|
||||
|
||||
skb_get_timestamp(skb, &stamp);
|
||||
stamp = skb_get_ktime(skb);
|
||||
|
||||
if (!mip6_report_rl_allow(&stamp, &ipv6_hdr(skb)->daddr,
|
||||
if (!mip6_report_rl_allow(stamp, &ipv6_hdr(skb)->daddr,
|
||||
hao ? &hao->addr : &ipv6_hdr(skb)->saddr,
|
||||
opt->iif))
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@
|
|||
#include <net/flow.h>
|
||||
#include <net/ip6_checksum.h>
|
||||
#include <net/inet_common.h>
|
||||
#include <net/l3mdev.h>
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
|
|
@ -147,6 +148,7 @@ struct neigh_table nd_tbl = {
|
|||
.gc_thresh2 = 512,
|
||||
.gc_thresh3 = 1024,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(nd_tbl);
|
||||
|
||||
static void ndisc_fill_addr_option(struct sk_buff *skb, int type, void *data)
|
||||
{
|
||||
|
|
@ -441,8 +443,11 @@ static void ndisc_send_skb(struct sk_buff *skb,
|
|||
|
||||
if (!dst) {
|
||||
struct flowi6 fl6;
|
||||
int oif = l3mdev_fib_oif(skb->dev);
|
||||
|
||||
icmpv6_flow_init(sk, &fl6, type, saddr, daddr, skb->dev->ifindex);
|
||||
icmpv6_flow_init(sk, &fl6, type, saddr, daddr, oif);
|
||||
if (oif != skb->dev->ifindex)
|
||||
fl6.flowi6_flags |= FLOWI_FLAG_L3MDEV_SRC;
|
||||
dst = icmp6_dst_alloc(skb->dev, &fl6);
|
||||
if (IS_ERR(dst)) {
|
||||
kfree_skb(skb);
|
||||
|
|
@ -465,7 +470,7 @@ static void ndisc_send_skb(struct sk_buff *skb,
|
|||
|
||||
err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
|
||||
net, sk, skb, NULL, dst->dev,
|
||||
dst_output_okfn);
|
||||
dst_output);
|
||||
if (!err) {
|
||||
ICMP6MSGOUT_INC_STATS(net, idev, type);
|
||||
ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
|
||||
|
|
@ -766,7 +771,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
|
|||
|
||||
ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
|
||||
if (ifp) {
|
||||
|
||||
have_ifp:
|
||||
if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) {
|
||||
if (dad) {
|
||||
/*
|
||||
|
|
@ -792,6 +797,18 @@ static void ndisc_recv_ns(struct sk_buff *skb)
|
|||
} else {
|
||||
struct net *net = dev_net(dev);
|
||||
|
||||
/* perhaps an address on the master device */
|
||||
if (netif_is_l3_slave(dev)) {
|
||||
struct net_device *mdev;
|
||||
|
||||
mdev = netdev_master_upper_dev_get_rcu(dev);
|
||||
if (mdev) {
|
||||
ifp = ipv6_get_ifaddr(net, &msg->target, mdev, 1);
|
||||
if (ifp)
|
||||
goto have_ifp;
|
||||
}
|
||||
}
|
||||
|
||||
idev = in6_dev_get(dev);
|
||||
if (!idev) {
|
||||
/* XXX: count this drop? */
|
||||
|
|
@ -1483,6 +1500,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
|
|||
struct flowi6 fl6;
|
||||
int rd_len;
|
||||
u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
|
||||
int oif = l3mdev_fib_oif(dev);
|
||||
bool ret;
|
||||
|
||||
if (ipv6_get_lladdr(dev, &saddr_buf, IFA_F_TENTATIVE)) {
|
||||
|
|
@ -1499,7 +1517,10 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
|
|||
}
|
||||
|
||||
icmpv6_flow_init(sk, &fl6, NDISC_REDIRECT,
|
||||
&saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex);
|
||||
&saddr_buf, &ipv6_hdr(skb)->saddr, oif);
|
||||
|
||||
if (oif != skb->dev->ifindex)
|
||||
fl6.flowi6_flags |= FLOWI_FLAG_L3MDEV_SRC;
|
||||
|
||||
dst = ip6_route_output(net, NULL, &fl6);
|
||||
if (dst->error) {
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ synproxy_send_tcp(const struct synproxy_net *snet,
|
|||
nf_conntrack_get(nfct);
|
||||
}
|
||||
|
||||
ip6_local_out(nskb);
|
||||
ip6_local_out(net, nskb->sk, nskb);
|
||||
return;
|
||||
|
||||
free_nskb:
|
||||
|
|
|
|||
|
|
@ -563,12 +563,10 @@ find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
|
||||
struct sk_buff *nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
|
||||
{
|
||||
struct sk_buff *clone;
|
||||
struct net_device *dev = skb->dev;
|
||||
struct net *net = skb_dst(skb) ? dev_net(skb_dst(skb)->dev)
|
||||
: dev_net(skb->dev);
|
||||
struct frag_hdr *fhdr;
|
||||
struct frag_queue *fq;
|
||||
struct ipv6hdr *hdr;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@ static unsigned int ipv6_defrag(void *priv,
|
|||
return NF_ACCEPT;
|
||||
#endif
|
||||
|
||||
reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(state->hook, skb));
|
||||
reasm = nf_ct_frag6_gather(state->net, skb,
|
||||
nf_ct6_defrag_user(state->hook, skb));
|
||||
/* queued */
|
||||
if (reasm == NULL)
|
||||
return NF_STOLEN;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ void nf_dup_ipv6(struct net *net, struct sk_buff *skb, unsigned int hooknum,
|
|||
}
|
||||
if (nf_dup_ipv6_route(net, skb, gw, oif)) {
|
||||
__this_cpu_write(nf_skb_duplicated, true);
|
||||
ip6_local_out(skb);
|
||||
ip6_local_out(net, skb->sk, skb);
|
||||
__this_cpu_write(nf_skb_duplicated, false);
|
||||
} else {
|
||||
kfree_skb(skb);
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
|
|||
dev_queue_xmit(nskb);
|
||||
} else
|
||||
#endif
|
||||
ip6_local_out(nskb);
|
||||
ip6_local_out(net, nskb->sk, nskb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_send_reset6);
|
||||
|
||||
|
|
|
|||
|
|
@ -138,9 +138,8 @@ int ip6_dst_hoplimit(struct dst_entry *dst)
|
|||
EXPORT_SYMBOL(ip6_dst_hoplimit);
|
||||
#endif
|
||||
|
||||
static int __ip6_local_out_sk(struct sock *sk, struct sk_buff *skb)
|
||||
int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct net *net = dev_net(skb_dst(skb)->dev);
|
||||
int len;
|
||||
|
||||
len = skb->len - sizeof(struct ipv6hdr);
|
||||
|
|
@ -151,29 +150,18 @@ static int __ip6_local_out_sk(struct sock *sk, struct sk_buff *skb)
|
|||
|
||||
return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
|
||||
net, sk, skb, NULL, skb_dst(skb)->dev,
|
||||
dst_output_okfn);
|
||||
}
|
||||
|
||||
int __ip6_local_out(struct sk_buff *skb)
|
||||
{
|
||||
return __ip6_local_out_sk(skb->sk, skb);
|
||||
dst_output);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__ip6_local_out);
|
||||
|
||||
int ip6_local_out_sk(struct sock *sk, struct sk_buff *skb)
|
||||
int ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = __ip6_local_out_sk(sk, skb);
|
||||
err = __ip6_local_out(net, sk, skb);
|
||||
if (likely(err == 1))
|
||||
err = dst_output(sk, skb);
|
||||
err = dst_output(net, sk, skb);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ip6_local_out_sk);
|
||||
|
||||
int ip6_local_out(struct sk_buff *skb)
|
||||
{
|
||||
return ip6_local_out_sk(skb->sk, skb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ip6_local_out);
|
||||
|
|
|
|||
|
|
@ -655,7 +655,7 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
|
|||
|
||||
IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
|
||||
err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, skb,
|
||||
NULL, rt->dst.dev, dst_output_okfn);
|
||||
NULL, rt->dst.dev, dst_output);
|
||||
if (err > 0)
|
||||
err = net_xmit_errno(err);
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
#include <net/nexthop.h>
|
||||
#include <net/lwtunnel.h>
|
||||
#include <net/ip_tunnels.h>
|
||||
#include <net/l3mdev.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
|
|
@ -86,9 +87,9 @@ static void ip6_dst_ifdown(struct dst_entry *,
|
|||
static int ip6_dst_gc(struct dst_ops *ops);
|
||||
|
||||
static int ip6_pkt_discard(struct sk_buff *skb);
|
||||
static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb);
|
||||
static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb);
|
||||
static int ip6_pkt_prohibit(struct sk_buff *skb);
|
||||
static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb);
|
||||
static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb);
|
||||
static void ip6_link_failure(struct sk_buff *skb);
|
||||
static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
|
||||
struct sk_buff *skb, u32 mtu);
|
||||
|
|
@ -308,7 +309,7 @@ static const struct rt6_info ip6_blk_hole_entry_template = {
|
|||
.obsolete = DST_OBSOLETE_FORCE_CHK,
|
||||
.error = -EINVAL,
|
||||
.input = dst_discard,
|
||||
.output = dst_discard_sk,
|
||||
.output = dst_discard_out,
|
||||
},
|
||||
.rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
|
||||
.rt6i_protocol = RTPROT_KERNEL,
|
||||
|
|
@ -1044,6 +1045,9 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
|
|||
fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
|
||||
saved_fn = fn;
|
||||
|
||||
if (fl6->flowi6_flags & FLOWI_FLAG_SKIP_NH_OIF)
|
||||
oif = 0;
|
||||
|
||||
redo_rt6_select:
|
||||
rt = rt6_select(fn, oif, strict);
|
||||
if (rt->rt6i_nsiblings)
|
||||
|
|
@ -1141,7 +1145,7 @@ void ip6_route_input(struct sk_buff *skb)
|
|||
int flags = RT6_LOOKUP_F_HAS_SADDR;
|
||||
struct ip_tunnel_info *tun_info;
|
||||
struct flowi6 fl6 = {
|
||||
.flowi6_iif = skb->dev->ifindex,
|
||||
.flowi6_iif = l3mdev_fib_oif(skb->dev),
|
||||
.daddr = iph->daddr,
|
||||
.saddr = iph->saddr,
|
||||
.flowlabel = ip6_flowinfo(iph),
|
||||
|
|
@ -1165,8 +1169,13 @@ static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table
|
|||
struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk,
|
||||
struct flowi6 *fl6)
|
||||
{
|
||||
struct dst_entry *dst;
|
||||
int flags = 0;
|
||||
|
||||
dst = l3mdev_rt6_dst_by_oif(net, fl6);
|
||||
if (dst)
|
||||
return dst;
|
||||
|
||||
fl6->flowi6_iif = LOOPBACK_IFINDEX;
|
||||
|
||||
if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr) ||
|
||||
|
|
@ -1195,7 +1204,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
|
|||
|
||||
new->__use = 1;
|
||||
new->input = dst_discard;
|
||||
new->output = dst_discard_sk;
|
||||
new->output = dst_discard_out;
|
||||
|
||||
if (dst_metrics_read_only(&ort->dst))
|
||||
new->_metrics = ort->dst._metrics;
|
||||
|
|
@ -1724,21 +1733,21 @@ static int ip6_convert_metrics(struct mx6_config *mxc,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
int ip6_route_info_create(struct fib6_config *cfg, struct rt6_info **rt_ret)
|
||||
static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg)
|
||||
{
|
||||
int err;
|
||||
struct net *net = cfg->fc_nlinfo.nl_net;
|
||||
struct rt6_info *rt = NULL;
|
||||
struct net_device *dev = NULL;
|
||||
struct inet6_dev *idev = NULL;
|
||||
struct fib6_table *table;
|
||||
int addr_type;
|
||||
int err = -EINVAL;
|
||||
|
||||
if (cfg->fc_dst_len > 128 || cfg->fc_src_len > 128)
|
||||
return -EINVAL;
|
||||
goto out;
|
||||
#ifndef CONFIG_IPV6_SUBTREES
|
||||
if (cfg->fc_src_len)
|
||||
return -EINVAL;
|
||||
goto out;
|
||||
#endif
|
||||
if (cfg->fc_ifindex) {
|
||||
err = -ENODEV;
|
||||
|
|
@ -1853,7 +1862,7 @@ int ip6_route_info_create(struct fib6_config *cfg, struct rt6_info **rt_ret)
|
|||
switch (cfg->fc_type) {
|
||||
case RTN_BLACKHOLE:
|
||||
rt->dst.error = -EINVAL;
|
||||
rt->dst.output = dst_discard_sk;
|
||||
rt->dst.output = dst_discard_out;
|
||||
rt->dst.input = dst_discard;
|
||||
break;
|
||||
case RTN_PROHIBIT:
|
||||
|
|
@ -1958,9 +1967,7 @@ install_route:
|
|||
|
||||
cfg->fc_nlinfo.nl_net = dev_net(dev);
|
||||
|
||||
*rt_ret = rt;
|
||||
|
||||
return 0;
|
||||
return rt;
|
||||
out:
|
||||
if (dev)
|
||||
dev_put(dev);
|
||||
|
|
@ -1969,20 +1976,21 @@ out:
|
|||
if (rt)
|
||||
dst_free(&rt->dst);
|
||||
|
||||
*rt_ret = NULL;
|
||||
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
int ip6_route_add(struct fib6_config *cfg)
|
||||
{
|
||||
struct mx6_config mxc = { .mx = NULL, };
|
||||
struct rt6_info *rt = NULL;
|
||||
struct rt6_info *rt;
|
||||
int err;
|
||||
|
||||
err = ip6_route_info_create(cfg, &rt);
|
||||
if (err)
|
||||
rt = ip6_route_info_create(cfg);
|
||||
if (IS_ERR(rt)) {
|
||||
err = PTR_ERR(rt);
|
||||
rt = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = ip6_convert_metrics(&mxc, cfg);
|
||||
if (err)
|
||||
|
|
@ -2264,7 +2272,6 @@ static struct rt6_info *rt6_add_route_info(struct net *net,
|
|||
unsigned int pref)
|
||||
{
|
||||
struct fib6_config cfg = {
|
||||
.fc_table = RT6_TABLE_INFO,
|
||||
.fc_metric = IP6_RT_PRIO_USER,
|
||||
.fc_ifindex = ifindex,
|
||||
.fc_dst_len = prefixlen,
|
||||
|
|
@ -2275,6 +2282,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net,
|
|||
.fc_nlinfo.nl_net = net,
|
||||
};
|
||||
|
||||
cfg.fc_table = l3mdev_fib_table_by_index(net, ifindex) ? : RT6_TABLE_INFO;
|
||||
cfg.fc_dst = *prefix;
|
||||
cfg.fc_gateway = *gwaddr;
|
||||
|
||||
|
|
@ -2315,7 +2323,7 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr,
|
|||
unsigned int pref)
|
||||
{
|
||||
struct fib6_config cfg = {
|
||||
.fc_table = RT6_TABLE_DFLT,
|
||||
.fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT,
|
||||
.fc_metric = IP6_RT_PRIO_USER,
|
||||
.fc_ifindex = dev->ifindex,
|
||||
.fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
|
||||
|
|
@ -2362,7 +2370,8 @@ static void rtmsg_to_fib6_config(struct net *net,
|
|||
{
|
||||
memset(cfg, 0, sizeof(*cfg));
|
||||
|
||||
cfg->fc_table = RT6_TABLE_MAIN;
|
||||
cfg->fc_table = l3mdev_fib_table_by_index(net, rtmsg->rtmsg_ifindex) ?
|
||||
: RT6_TABLE_MAIN;
|
||||
cfg->fc_ifindex = rtmsg->rtmsg_ifindex;
|
||||
cfg->fc_metric = rtmsg->rtmsg_metric;
|
||||
cfg->fc_expires = rtmsg->rtmsg_info;
|
||||
|
|
@ -2446,7 +2455,7 @@ static int ip6_pkt_discard(struct sk_buff *skb)
|
|||
return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES);
|
||||
}
|
||||
|
||||
static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb)
|
||||
static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
skb->dev = skb_dst(skb)->dev;
|
||||
return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES);
|
||||
|
|
@ -2457,7 +2466,7 @@ static int ip6_pkt_prohibit(struct sk_buff *skb)
|
|||
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES);
|
||||
}
|
||||
|
||||
static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb)
|
||||
static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
skb->dev = skb_dst(skb)->dev;
|
||||
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
|
||||
|
|
@ -2471,6 +2480,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
|
|||
const struct in6_addr *addr,
|
||||
bool anycast)
|
||||
{
|
||||
u32 tb_id;
|
||||
struct net *net = dev_net(idev->dev);
|
||||
struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev,
|
||||
DST_NOCOUNT);
|
||||
|
|
@ -2493,7 +2503,8 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
|
|||
rt->rt6i_gateway = *addr;
|
||||
rt->rt6i_dst.addr = *addr;
|
||||
rt->rt6i_dst.plen = 128;
|
||||
rt->rt6i_table = fib6_get_table(net, RT6_TABLE_LOCAL);
|
||||
tb_id = l3mdev_fib_table(idev->dev) ? : RT6_TABLE_LOCAL;
|
||||
rt->rt6i_table = fib6_get_table(net, tb_id);
|
||||
rt->dst.flags |= DST_NOCACHE;
|
||||
|
||||
atomic_set(&rt->dst.__refcnt, 1);
|
||||
|
|
@ -2871,9 +2882,12 @@ static int ip6_route_multipath_add(struct fib6_config *cfg)
|
|||
r_cfg.fc_encap_type = nla_get_u16(nla);
|
||||
}
|
||||
|
||||
err = ip6_route_info_create(&r_cfg, &rt);
|
||||
if (err)
|
||||
rt = ip6_route_info_create(&r_cfg);
|
||||
if (IS_ERR(rt)) {
|
||||
err = PTR_ERR(rt);
|
||||
rt = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
err = ip6_route_info_append(&rt6_nh_list, rt, &r_cfg);
|
||||
if (err) {
|
||||
|
|
@ -3252,6 +3266,11 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
|
|||
} else {
|
||||
fl6.flowi6_oif = oif;
|
||||
|
||||
if (netif_index_is_l3_master(net, oif)) {
|
||||
fl6.flowi6_flags = FLOWI_FLAG_L3MDEV_SRC |
|
||||
FLOWI_FLAG_SKIP_NH_OIF;
|
||||
}
|
||||
|
||||
rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
|
|||
goto out;
|
||||
|
||||
ret = NULL;
|
||||
req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk);
|
||||
req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false);
|
||||
if (!req)
|
||||
goto out;
|
||||
|
||||
|
|
@ -235,9 +235,9 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
|
||||
req->rsk_window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
|
||||
tcp_select_initial_window(tcp_full_space(sk), req->mss,
|
||||
&req->rcv_wnd, &req->window_clamp,
|
||||
&req->rsk_rcv_wnd, &req->rsk_window_clamp,
|
||||
ireq->wscale_ok, &rcv_wscale,
|
||||
dst_metric(dst, RTAX_INITRWND));
|
||||
|
||||
|
|
|
|||
|
|
@ -931,7 +931,7 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
|
|||
*/
|
||||
tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ?
|
||||
tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt,
|
||||
tcp_rsk(req)->rcv_nxt, req->rcv_wnd,
|
||||
tcp_rsk(req)->rcv_nxt, req->rsk_rcv_wnd,
|
||||
tcp_time_stamp, req->ts_recent, sk->sk_bound_dev_if,
|
||||
tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr),
|
||||
0, 0);
|
||||
|
|
@ -1363,6 +1363,7 @@ static int tcp_v6_rcv(struct sk_buff *skb)
|
|||
th = tcp_hdr(skb);
|
||||
hdr = ipv6_hdr(skb);
|
||||
|
||||
lookup:
|
||||
sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest,
|
||||
inet6_iif(skb));
|
||||
if (!sk)
|
||||
|
|
@ -1382,8 +1383,12 @@ process:
|
|||
reqsk_put(req);
|
||||
goto discard_it;
|
||||
}
|
||||
if (sk->sk_state == TCP_LISTEN)
|
||||
if (likely(sk->sk_state == TCP_LISTEN)) {
|
||||
nsk = tcp_check_req(sk, skb, req, false);
|
||||
} else {
|
||||
inet_csk_reqsk_queue_drop_and_put(sk, req);
|
||||
goto lookup;
|
||||
}
|
||||
if (!nsk) {
|
||||
reqsk_put(req);
|
||||
goto discard_it;
|
||||
|
|
|
|||
|
|
@ -182,10 +182,12 @@ static inline int compute_score(struct sock *sk, struct net *net,
|
|||
score++;
|
||||
}
|
||||
|
||||
if (sk->sk_incoming_cpu == raw_smp_processor_id())
|
||||
score++;
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
#define SCORE2_MAX (1 + 1 + 1)
|
||||
static inline int compute_score2(struct sock *sk, struct net *net,
|
||||
const struct in6_addr *saddr, __be16 sport,
|
||||
const struct in6_addr *daddr,
|
||||
|
|
@ -223,6 +225,9 @@ static inline int compute_score2(struct sock *sk, struct net *net,
|
|||
score++;
|
||||
}
|
||||
|
||||
if (sk->sk_incoming_cpu == raw_smp_processor_id())
|
||||
score++;
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
|
|
@ -251,8 +256,7 @@ begin:
|
|||
hash = udp6_ehashfn(net, daddr, hnum,
|
||||
saddr, sport);
|
||||
matches = 1;
|
||||
} else if (score == SCORE2_MAX)
|
||||
goto exact_match;
|
||||
}
|
||||
} else if (score == badness && reuseport) {
|
||||
matches++;
|
||||
if (reciprocal_scale(hash, matches) == 0)
|
||||
|
|
@ -269,7 +273,6 @@ begin:
|
|||
goto begin;
|
||||
|
||||
if (result) {
|
||||
exact_match:
|
||||
if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
|
||||
result = NULL;
|
||||
else if (unlikely(compute_score2(result, net, saddr, sport,
|
||||
|
|
|
|||
|
|
@ -131,6 +131,13 @@ int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb)
|
|||
return xfrm_output(sk, skb);
|
||||
}
|
||||
|
||||
static int __xfrm6_output_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct xfrm_state *x = skb_dst(skb)->xfrm;
|
||||
|
||||
return x->outer_mode->afinfo->output_finish(sk, skb);
|
||||
}
|
||||
|
||||
static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct dst_entry *dst = skb_dst(skb);
|
||||
|
|
@ -140,7 +147,7 @@ static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|||
#ifdef CONFIG_NETFILTER
|
||||
if (!x) {
|
||||
IP6CB(skb)->flags |= IP6SKB_REROUTED;
|
||||
return dst_output(sk, skb);
|
||||
return dst_output(net, sk, skb);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -160,16 +167,14 @@ static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|||
if (x->props.mode == XFRM_MODE_TUNNEL &&
|
||||
((skb->len > mtu && !skb_is_gso(skb)) ||
|
||||
dst_allfrag(skb_dst(skb)))) {
|
||||
return ip6_fragment(sk, skb,
|
||||
x->outer_mode->afinfo->output_finish);
|
||||
return ip6_fragment(net, sk, skb,
|
||||
__xfrm6_output_finish);
|
||||
}
|
||||
return x->outer_mode->afinfo->output_finish(sk, skb);
|
||||
}
|
||||
|
||||
int xfrm6_output(struct sock *sk, struct sk_buff *skb)
|
||||
int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct net *net = dev_net(skb_dst(skb)->dev);
|
||||
|
||||
return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
|
||||
net, sk, skb, NULL, skb_dst(skb)->dev,
|
||||
__xfrm6_output,
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,
|
|||
|
||||
memset(&fl6, 0, sizeof(fl6));
|
||||
fl6.flowi6_oif = 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));
|
||||
|
|
|
|||
Loading…
Reference in a new issue