mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 19:51:31 -04:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Conflicts: net/netfilter/core.c net/netfilter/nf_tables_netdev.c Resolve two conflicts before pull request for David's net-next tree: 1) Betweenc73c248490("netfilter: nf_tables_netdev: remove redundant ip_hdr assignment") from the net tree and commitddc8b6027a("netfilter: introduce nft_set_pktinfo_{ipv4, ipv6}_validate()"). 2) Betweene8bffe0cf9("net: Add _nf_(un)register_hooks symbols") and Aaron Conole's patches to replace list_head with single linked list. Signed-off-by: Pablo Neira Ayuso <[email protected]>
This commit is contained in:
commit
f20fbc0717
1352 changed files with 49627 additions and 17803 deletions
|
|
@ -778,7 +778,14 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
|
|||
}
|
||||
|
||||
if (p == &net->ipv6.devconf_all->forwarding) {
|
||||
int old_dflt = net->ipv6.devconf_dflt->forwarding;
|
||||
|
||||
net->ipv6.devconf_dflt->forwarding = newf;
|
||||
if ((!newf) ^ (!old_dflt))
|
||||
inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
|
||||
NETCONFA_IFINDEX_DEFAULT,
|
||||
net->ipv6.devconf_dflt);
|
||||
|
||||
addrconf_forward_change(net, newf);
|
||||
if ((!newf) ^ (!old))
|
||||
inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
|
||||
|
|
@ -1941,6 +1948,7 @@ errdad:
|
|||
spin_unlock_bh(&ifp->lock);
|
||||
|
||||
addrconf_mod_dad_work(ifp, 0);
|
||||
in6_ifa_put(ifp);
|
||||
}
|
||||
|
||||
/* Join to solicited addr multicast group.
|
||||
|
|
@ -3850,6 +3858,7 @@ static void addrconf_dad_work(struct work_struct *w)
|
|||
addrconf_dad_begin(ifp);
|
||||
goto out;
|
||||
} else if (action == DAD_ABORT) {
|
||||
in6_ifa_hold(ifp);
|
||||
addrconf_dad_stop(ifp, 1);
|
||||
if (disable_ipv6)
|
||||
addrconf_ifdown(idev->dev, 0);
|
||||
|
|
@ -6025,7 +6034,7 @@ static const struct ctl_table addrconf_sysctl[] = {
|
|||
static int __addrconf_sysctl_register(struct net *net, char *dev_name,
|
||||
struct inet6_dev *idev, struct ipv6_devconf *p)
|
||||
{
|
||||
int i;
|
||||
int i, ifindex;
|
||||
struct ctl_table *table;
|
||||
char path[sizeof("net/ipv6/conf/") + IFNAMSIZ];
|
||||
|
||||
|
|
@ -6045,6 +6054,13 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
|
|||
if (!p->sysctl_header)
|
||||
goto free;
|
||||
|
||||
if (!strcmp(dev_name, "all"))
|
||||
ifindex = NETCONFA_IFINDEX_ALL;
|
||||
else if (!strcmp(dev_name, "default"))
|
||||
ifindex = NETCONFA_IFINDEX_DEFAULT;
|
||||
else
|
||||
ifindex = idev->dev->ifindex;
|
||||
inet6_netconf_notify_devconf(net, NETCONFA_ALL, ifindex, p);
|
||||
return 0;
|
||||
|
||||
free:
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
|
|||
.flags = FIB_LOOKUP_NOREF,
|
||||
};
|
||||
|
||||
/* update flow if oif or iif point to device enslaved to l3mdev */
|
||||
l3mdev_update_flow(net, flowi6_to_flowi(fl6));
|
||||
|
||||
fib_rules_lookup(net->ipv6.fib6_rules_ops,
|
||||
flowi6_to_flowi(fl6), flags, &arg);
|
||||
|
||||
|
|
|
|||
|
|
@ -743,6 +743,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
|
|||
(info->nlh->nlmsg_flags & NLM_F_CREATE));
|
||||
int found = 0;
|
||||
bool rt_can_ecmp = rt6_qualify_for_ecmp(rt);
|
||||
u16 nlflags = NLM_F_EXCL;
|
||||
int err;
|
||||
|
||||
ins = &fn->leaf;
|
||||
|
|
@ -759,6 +760,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
|
|||
if (info->nlh &&
|
||||
(info->nlh->nlmsg_flags & NLM_F_EXCL))
|
||||
return -EEXIST;
|
||||
|
||||
nlflags &= ~NLM_F_EXCL;
|
||||
if (replace) {
|
||||
if (rt_can_ecmp == rt6_qualify_for_ecmp(iter)) {
|
||||
found++;
|
||||
|
|
@ -856,6 +859,7 @@ next_iter:
|
|||
pr_warn("NLM_F_CREATE should be set when creating new route\n");
|
||||
|
||||
add:
|
||||
nlflags |= NLM_F_CREATE;
|
||||
err = fib6_commit_metrics(&rt->dst, mxc);
|
||||
if (err)
|
||||
return err;
|
||||
|
|
@ -864,7 +868,7 @@ add:
|
|||
*ins = rt;
|
||||
rt->rt6i_node = fn;
|
||||
atomic_inc(&rt->rt6i_ref);
|
||||
inet6_rt_notify(RTM_NEWROUTE, rt, info, 0);
|
||||
inet6_rt_notify(RTM_NEWROUTE, rt, info, nlflags);
|
||||
info->nl_net->ipv6.rt6_stats->fib_rt_entries++;
|
||||
|
||||
if (!(fn->fn_flags & RTN_RTINFO)) {
|
||||
|
|
|
|||
|
|
@ -1239,7 +1239,7 @@ static void ip6gre_netlink_parms(struct nlattr *data[],
|
|||
parms->encap_limit = nla_get_u8(data[IFLA_GRE_ENCAP_LIMIT]);
|
||||
|
||||
if (data[IFLA_GRE_FLOWINFO])
|
||||
parms->flowinfo = nla_get_u32(data[IFLA_GRE_FLOWINFO]);
|
||||
parms->flowinfo = nla_get_be32(data[IFLA_GRE_FLOWINFO]);
|
||||
|
||||
if (data[IFLA_GRE_FLAGS])
|
||||
parms->flags = nla_get_u32(data[IFLA_GRE_FLAGS]);
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
|
|||
int offset = 0;
|
||||
bool encap, udpfrag;
|
||||
int nhoff;
|
||||
bool gso_partial;
|
||||
|
||||
skb_reset_network_header(skb);
|
||||
nhoff = skb_network_header(skb) - skb_mac_header(skb);
|
||||
|
|
@ -101,9 +102,11 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
|
|||
if (IS_ERR(segs))
|
||||
goto out;
|
||||
|
||||
gso_partial = !!(skb_shinfo(segs)->gso_type & SKB_GSO_PARTIAL);
|
||||
|
||||
for (skb = segs; skb; skb = skb->next) {
|
||||
ipv6h = (struct ipv6hdr *)(skb_mac_header(skb) + nhoff);
|
||||
if (skb_is_gso(skb))
|
||||
if (gso_partial)
|
||||
payload_len = skb_shinfo(skb)->gso_size +
|
||||
SKB_GSO_CB(skb)->data_offset +
|
||||
skb->head - (unsigned char *)(ipv6h + 1);
|
||||
|
|
|
|||
|
|
@ -236,6 +236,14 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
|
|||
if ((skb->len <= mtu) || skb->ignore_df || skb_is_gso(skb)) {
|
||||
IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)),
|
||||
IPSTATS_MIB_OUT, skb->len);
|
||||
|
||||
/* if egress device is enslaved to an L3 master device pass the
|
||||
* skb to its handler for processing
|
||||
*/
|
||||
skb = l3mdev_ip6_out((struct sock *)sk, skb);
|
||||
if (unlikely(!skb))
|
||||
return 0;
|
||||
|
||||
/* hooks should never assume socket lock is held.
|
||||
* we promote our socket to non const
|
||||
*/
|
||||
|
|
@ -918,13 +926,6 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk,
|
|||
int err;
|
||||
int flags = 0;
|
||||
|
||||
if (ipv6_addr_any(&fl6->saddr) && fl6->flowi6_oif &&
|
||||
(!*dst || !(*dst)->error)) {
|
||||
err = l3mdev_get_saddr6(net, sk, fl6);
|
||||
if (err)
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
/* The correct way to handle this would be to do
|
||||
* ip6_route_get_saddr, and then ip6_route_output; however,
|
||||
* the route-specific preferred source forces the
|
||||
|
|
@ -1016,7 +1017,7 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk,
|
|||
out_err_release:
|
||||
dst_release(*dst);
|
||||
*dst = NULL;
|
||||
out_err:
|
||||
|
||||
if (err == -ENETUNREACH)
|
||||
IP6_INC_STATS(net, NULL, IPSTATS_MIB_OUTNOROUTES);
|
||||
return err;
|
||||
|
|
@ -1062,8 +1063,6 @@ struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6,
|
|||
return ERR_PTR(err);
|
||||
if (final_dst)
|
||||
fl6->daddr = *final_dst;
|
||||
if (!fl6->flowi6_oif)
|
||||
fl6->flowi6_oif = l3mdev_fib_oif(dst->dev);
|
||||
|
||||
return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include <net/inet_ecn.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/netns/generic.h>
|
||||
#include <net/dst_metadata.h>
|
||||
|
||||
MODULE_AUTHOR("Ville Nuorvala");
|
||||
MODULE_DESCRIPTION("IPv6 tunneling device");
|
||||
|
|
@ -90,6 +91,7 @@ struct ip6_tnl_net {
|
|||
struct ip6_tnl __rcu *tnls_r_l[IP6_TUNNEL_HASH_SIZE];
|
||||
struct ip6_tnl __rcu *tnls_wc[1];
|
||||
struct ip6_tnl __rcu **tnls[2];
|
||||
struct ip6_tnl __rcu *collect_md_tun;
|
||||
};
|
||||
|
||||
static struct net_device_stats *ip6_get_stats(struct net_device *dev)
|
||||
|
|
@ -166,6 +168,10 @@ ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_
|
|||
return t;
|
||||
}
|
||||
|
||||
t = rcu_dereference(ip6n->collect_md_tun);
|
||||
if (t)
|
||||
return t;
|
||||
|
||||
t = rcu_dereference(ip6n->tnls_wc[0]);
|
||||
if (t && (t->dev->flags & IFF_UP))
|
||||
return t;
|
||||
|
|
@ -209,6 +215,8 @@ ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
|
|||
{
|
||||
struct ip6_tnl __rcu **tp = ip6_tnl_bucket(ip6n, &t->parms);
|
||||
|
||||
if (t->parms.collect_md)
|
||||
rcu_assign_pointer(ip6n->collect_md_tun, t);
|
||||
rcu_assign_pointer(t->next , rtnl_dereference(*tp));
|
||||
rcu_assign_pointer(*tp, t);
|
||||
}
|
||||
|
|
@ -224,6 +232,9 @@ ip6_tnl_unlink(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
|
|||
struct ip6_tnl __rcu **tp;
|
||||
struct ip6_tnl *iter;
|
||||
|
||||
if (t->parms.collect_md)
|
||||
rcu_assign_pointer(ip6n->collect_md_tun, NULL);
|
||||
|
||||
for (tp = ip6_tnl_bucket(ip6n, &t->parms);
|
||||
(iter = rtnl_dereference(*tp)) != NULL;
|
||||
tp = &iter->next) {
|
||||
|
|
@ -829,6 +840,9 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
|
|||
|
||||
skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
|
||||
|
||||
if (tun_dst)
|
||||
skb_dst_set(skb, (struct dst_entry *)tun_dst);
|
||||
|
||||
gro_cells_receive(&tunnel->gro_cells, skb);
|
||||
return 0;
|
||||
|
||||
|
|
@ -865,6 +879,7 @@ static int ipxip6_rcv(struct sk_buff *skb, u8 ipproto,
|
|||
{
|
||||
struct ip6_tnl *t;
|
||||
const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
|
||||
struct metadata_dst *tun_dst = NULL;
|
||||
int ret = -1;
|
||||
|
||||
rcu_read_lock();
|
||||
|
|
@ -881,7 +896,12 @@ static int ipxip6_rcv(struct sk_buff *skb, u8 ipproto,
|
|||
goto drop;
|
||||
if (iptunnel_pull_header(skb, 0, tpi->proto, false))
|
||||
goto drop;
|
||||
ret = __ip6_tnl_rcv(t, skb, tpi, NULL, dscp_ecn_decapsulate,
|
||||
if (t->parms.collect_md) {
|
||||
tun_dst = ipv6_tun_rx_dst(skb, 0, 0, 0);
|
||||
if (!tun_dst)
|
||||
return 0;
|
||||
}
|
||||
ret = __ip6_tnl_rcv(t, skb, tpi, tun_dst, dscp_ecn_decapsulate,
|
||||
log_ecn_error);
|
||||
}
|
||||
|
||||
|
|
@ -1012,8 +1032,16 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
|
|||
int mtu;
|
||||
unsigned int psh_hlen = sizeof(struct ipv6hdr) + t->encap_hlen;
|
||||
unsigned int max_headroom = psh_hlen;
|
||||
u8 hop_limit;
|
||||
int err = -1;
|
||||
|
||||
if (t->parms.collect_md) {
|
||||
hop_limit = skb_tunnel_info(skb)->key.ttl;
|
||||
goto route_lookup;
|
||||
} else {
|
||||
hop_limit = t->parms.hop_limit;
|
||||
}
|
||||
|
||||
/* NBMA tunnel */
|
||||
if (ipv6_addr_any(&t->parms.raddr)) {
|
||||
struct in6_addr *addr6;
|
||||
|
|
@ -1043,6 +1071,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
|
|||
goto tx_err_link_failure;
|
||||
|
||||
if (!dst) {
|
||||
route_lookup:
|
||||
dst = ip6_route_output(net, NULL, fl6);
|
||||
|
||||
if (dst->error)
|
||||
|
|
@ -1053,6 +1082,10 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
|
|||
dst = NULL;
|
||||
goto tx_err_link_failure;
|
||||
}
|
||||
if (t->parms.collect_md &&
|
||||
ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
|
||||
&fl6->daddr, 0, &fl6->saddr))
|
||||
goto tx_err_link_failure;
|
||||
ndst = dst;
|
||||
}
|
||||
|
||||
|
|
@ -1071,7 +1104,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
|
|||
}
|
||||
if (mtu < IPV6_MIN_MTU)
|
||||
mtu = IPV6_MIN_MTU;
|
||||
if (skb_dst(skb))
|
||||
if (skb_dst(skb) && !t->parms.collect_md)
|
||||
skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
|
||||
if (skb->len > mtu && !skb_is_gso(skb)) {
|
||||
*pmtu = mtu;
|
||||
|
|
@ -1111,8 +1144,13 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
|
|||
skb = new_skb;
|
||||
}
|
||||
|
||||
if (!fl6->flowi6_mark && ndst)
|
||||
dst_cache_set_ip6(&t->dst_cache, ndst, &fl6->saddr);
|
||||
if (t->parms.collect_md) {
|
||||
if (t->encap.type != TUNNEL_ENCAP_NONE)
|
||||
goto tx_err_dst_release;
|
||||
} else {
|
||||
if (!fl6->flowi6_mark && ndst)
|
||||
dst_cache_set_ip6(&t->dst_cache, ndst, &fl6->saddr);
|
||||
}
|
||||
skb_dst_set(skb, dst);
|
||||
|
||||
if (encap_limit >= 0) {
|
||||
|
|
@ -1137,7 +1175,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
|
|||
ipv6h = ipv6_hdr(skb);
|
||||
ip6_flow_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield),
|
||||
ip6_make_flowlabel(net, skb, fl6->flowlabel, true, fl6));
|
||||
ipv6h->hop_limit = t->parms.hop_limit;
|
||||
ipv6h->hop_limit = hop_limit;
|
||||
ipv6h->nexthdr = proto;
|
||||
ipv6h->saddr = fl6->saddr;
|
||||
ipv6h->daddr = fl6->daddr;
|
||||
|
|
@ -1170,18 +1208,34 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
if (tproto != IPPROTO_IPIP && tproto != 0)
|
||||
return -1;
|
||||
|
||||
if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
|
||||
encap_limit = t->parms.encap_limit;
|
||||
|
||||
memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
|
||||
|
||||
dsfield = ipv4_get_dsfield(iph);
|
||||
|
||||
if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
|
||||
fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT)
|
||||
& IPV6_TCLASS_MASK;
|
||||
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
|
||||
fl6.flowi6_mark = skb->mark;
|
||||
if (t->parms.collect_md) {
|
||||
struct ip_tunnel_info *tun_info;
|
||||
const struct ip_tunnel_key *key;
|
||||
|
||||
tun_info = skb_tunnel_info(skb);
|
||||
if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
|
||||
ip_tunnel_info_af(tun_info) != AF_INET6))
|
||||
return -1;
|
||||
key = &tun_info->key;
|
||||
memset(&fl6, 0, sizeof(fl6));
|
||||
fl6.flowi6_proto = IPPROTO_IPIP;
|
||||
fl6.daddr = key->u.ipv6.dst;
|
||||
fl6.flowlabel = key->label;
|
||||
} else {
|
||||
if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
|
||||
encap_limit = t->parms.encap_limit;
|
||||
|
||||
memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
|
||||
fl6.flowi6_proto = IPPROTO_IPIP;
|
||||
|
||||
if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
|
||||
fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT)
|
||||
& IPV6_TCLASS_MASK;
|
||||
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
|
||||
fl6.flowi6_mark = skb->mark;
|
||||
}
|
||||
|
||||
if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
|
||||
return -1;
|
||||
|
|
@ -1219,28 +1273,47 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
ip6_tnl_addr_conflict(t, ipv6h))
|
||||
return -1;
|
||||
|
||||
offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb));
|
||||
if (offset > 0) {
|
||||
struct ipv6_tlv_tnl_enc_lim *tel;
|
||||
tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset];
|
||||
if (tel->encap_limit == 0) {
|
||||
icmpv6_send(skb, ICMPV6_PARAMPROB,
|
||||
ICMPV6_HDR_FIELD, offset + 2);
|
||||
return -1;
|
||||
}
|
||||
encap_limit = tel->encap_limit - 1;
|
||||
} else if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
|
||||
encap_limit = t->parms.encap_limit;
|
||||
|
||||
memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
|
||||
|
||||
dsfield = ipv6_get_dsfield(ipv6h);
|
||||
if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
|
||||
fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK);
|
||||
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)
|
||||
fl6.flowlabel |= ip6_flowlabel(ipv6h);
|
||||
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
|
||||
fl6.flowi6_mark = skb->mark;
|
||||
|
||||
if (t->parms.collect_md) {
|
||||
struct ip_tunnel_info *tun_info;
|
||||
const struct ip_tunnel_key *key;
|
||||
|
||||
tun_info = skb_tunnel_info(skb);
|
||||
if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
|
||||
ip_tunnel_info_af(tun_info) != AF_INET6))
|
||||
return -1;
|
||||
key = &tun_info->key;
|
||||
memset(&fl6, 0, sizeof(fl6));
|
||||
fl6.flowi6_proto = IPPROTO_IPV6;
|
||||
fl6.daddr = key->u.ipv6.dst;
|
||||
fl6.flowlabel = key->label;
|
||||
} else {
|
||||
offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb));
|
||||
if (offset > 0) {
|
||||
struct ipv6_tlv_tnl_enc_lim *tel;
|
||||
|
||||
tel = (void *)&skb_network_header(skb)[offset];
|
||||
if (tel->encap_limit == 0) {
|
||||
icmpv6_send(skb, ICMPV6_PARAMPROB,
|
||||
ICMPV6_HDR_FIELD, offset + 2);
|
||||
return -1;
|
||||
}
|
||||
encap_limit = tel->encap_limit - 1;
|
||||
} else if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) {
|
||||
encap_limit = t->parms.encap_limit;
|
||||
}
|
||||
|
||||
memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
|
||||
fl6.flowi6_proto = IPPROTO_IPV6;
|
||||
|
||||
if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
|
||||
fl6.flowlabel |= (*(__be32 *)ipv6h & IPV6_TCLASS_MASK);
|
||||
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)
|
||||
fl6.flowlabel |= ip6_flowlabel(ipv6h);
|
||||
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
|
||||
fl6.flowi6_mark = skb->mark;
|
||||
}
|
||||
|
||||
if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
|
||||
return -1;
|
||||
|
|
@ -1739,6 +1812,10 @@ static int ip6_tnl_dev_init(struct net_device *dev)
|
|||
if (err)
|
||||
return err;
|
||||
ip6_tnl_link_config(t);
|
||||
if (t->parms.collect_md) {
|
||||
dev->features |= NETIF_F_NETNS_LOCAL;
|
||||
netif_keep_dst(dev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1809,6 +1886,9 @@ static void ip6_tnl_netlink_parms(struct nlattr *data[],
|
|||
|
||||
if (data[IFLA_IPTUN_PROTO])
|
||||
parms->proto = nla_get_u8(data[IFLA_IPTUN_PROTO]);
|
||||
|
||||
if (data[IFLA_IPTUN_COLLECT_METADATA])
|
||||
parms->collect_md = true;
|
||||
}
|
||||
|
||||
static bool ip6_tnl_netlink_encap_parms(struct nlattr *data[],
|
||||
|
|
@ -1848,6 +1928,7 @@ static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
|
|||
struct nlattr *tb[], struct nlattr *data[])
|
||||
{
|
||||
struct net *net = dev_net(dev);
|
||||
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
|
||||
struct ip6_tnl *nt, *t;
|
||||
struct ip_tunnel_encap ipencap;
|
||||
|
||||
|
|
@ -1862,9 +1943,14 @@ static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
|
|||
|
||||
ip6_tnl_netlink_parms(data, &nt->parms);
|
||||
|
||||
t = ip6_tnl_locate(net, &nt->parms, 0);
|
||||
if (!IS_ERR(t))
|
||||
return -EEXIST;
|
||||
if (nt->parms.collect_md) {
|
||||
if (rtnl_dereference(ip6n->collect_md_tun))
|
||||
return -EEXIST;
|
||||
} else {
|
||||
t = ip6_tnl_locate(net, &nt->parms, 0);
|
||||
if (!IS_ERR(t))
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
return ip6_tnl_create2(dev);
|
||||
}
|
||||
|
|
@ -1888,6 +1974,8 @@ static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
|
|||
return err;
|
||||
}
|
||||
ip6_tnl_netlink_parms(data, &p);
|
||||
if (p.collect_md)
|
||||
return -EINVAL;
|
||||
|
||||
t = ip6_tnl_locate(net, &p, 0);
|
||||
if (!IS_ERR(t)) {
|
||||
|
|
@ -1935,6 +2023,8 @@ static size_t ip6_tnl_get_size(const struct net_device *dev)
|
|||
nla_total_size(2) +
|
||||
/* IFLA_IPTUN_ENCAP_DPORT */
|
||||
nla_total_size(2) +
|
||||
/* IFLA_IPTUN_COLLECT_METADATA */
|
||||
nla_total_size(0) +
|
||||
0;
|
||||
}
|
||||
|
||||
|
|
@ -1953,16 +2043,15 @@ static int ip6_tnl_fill_info(struct sk_buff *skb, const struct net_device *dev)
|
|||
nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE,
|
||||
tunnel->encap.type) ||
|
||||
nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT,
|
||||
tunnel->encap.sport) ||
|
||||
nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT,
|
||||
tunnel->encap.dport) ||
|
||||
nla_put_u16(skb, IFLA_IPTUN_ENCAP_FLAGS,
|
||||
tunnel->encap.flags))
|
||||
if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) ||
|
||||
nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) ||
|
||||
nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) ||
|
||||
nla_put_u16(skb, IFLA_IPTUN_ENCAP_FLAGS, tunnel->encap.flags))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (parm->collect_md)
|
||||
if (nla_put_flag(skb, IFLA_IPTUN_COLLECT_METADATA))
|
||||
goto nla_put_failure;
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
|
|
@ -1990,6 +2079,7 @@ static const struct nla_policy ip6_tnl_policy[IFLA_IPTUN_MAX + 1] = {
|
|||
[IFLA_IPTUN_ENCAP_FLAGS] = { .type = NLA_U16 },
|
||||
[IFLA_IPTUN_ENCAP_SPORT] = { .type = NLA_U16 },
|
||||
[IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 },
|
||||
[IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
static struct rtnl_link_ops ip6_link_ops __read_mostly = {
|
||||
|
|
|
|||
|
|
@ -321,11 +321,9 @@ static int vti6_rcv(struct sk_buff *skb)
|
|||
goto discard;
|
||||
}
|
||||
|
||||
XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t;
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
return xfrm6_rcv(skb);
|
||||
return xfrm6_rcv_tnl(skb, t);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return -EINVAL;
|
||||
|
|
@ -340,6 +338,7 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err)
|
|||
struct net_device *dev;
|
||||
struct pcpu_sw_netstats *tstats;
|
||||
struct xfrm_state *x;
|
||||
struct xfrm_mode *inner_mode;
|
||||
struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6;
|
||||
u32 orig_mark = skb->mark;
|
||||
int ret;
|
||||
|
|
@ -357,7 +356,19 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err)
|
|||
}
|
||||
|
||||
x = xfrm_input_state(skb);
|
||||
family = x->inner_mode->afinfo->family;
|
||||
|
||||
inner_mode = x->inner_mode;
|
||||
|
||||
if (x->sel.family == AF_UNSPEC) {
|
||||
inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
|
||||
if (inner_mode == NULL) {
|
||||
XFRM_INC_STATS(dev_net(skb->dev),
|
||||
LINUX_MIB_XFRMINSTATEMODEERROR);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
family = inner_mode->afinfo->family;
|
||||
|
||||
skb->mark = be32_to_cpu(t->parms.i_key);
|
||||
ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family);
|
||||
|
|
|
|||
|
|
@ -2239,6 +2239,7 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
|
|||
struct rta_mfc_stats mfcs;
|
||||
struct nlattr *mp_attr;
|
||||
struct rtnexthop *nhp;
|
||||
unsigned long lastuse;
|
||||
int ct;
|
||||
|
||||
/* If cache is unresolved, don't try to parse IIF and OIF */
|
||||
|
|
@ -2269,12 +2270,14 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
|
|||
|
||||
nla_nest_end(skb, mp_attr);
|
||||
|
||||
lastuse = READ_ONCE(c->mfc_un.res.lastuse);
|
||||
lastuse = time_after_eq(jiffies, lastuse) ? jiffies - lastuse : 0;
|
||||
|
||||
mfcs.mfcs_packets = c->mfc_un.res.pkt;
|
||||
mfcs.mfcs_bytes = c->mfc_un.res.bytes;
|
||||
mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if;
|
||||
if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) ||
|
||||
nla_put_u64_64bit(skb, RTA_EXPIRES,
|
||||
jiffies_to_clock_t(c->mfc_un.res.lastuse),
|
||||
nla_put_u64_64bit(skb, RTA_EXPIRES, jiffies_to_clock_t(lastuse),
|
||||
RTA_PAD))
|
||||
return -EMSGSIZE;
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@
|
|||
#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>
|
||||
|
|
@ -457,11 +456,9 @@ static void ndisc_send_skb(struct sk_buff *skb,
|
|||
|
||||
if (!dst) {
|
||||
struct flowi6 fl6;
|
||||
int oif = l3mdev_fib_oif(skb->dev);
|
||||
int oif = 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);
|
||||
|
|
@ -1538,7 +1535,6 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
|
|||
int rd_len;
|
||||
u8 ha_buf[MAX_ADDR_LEN], *ha = NULL,
|
||||
ops_data_buf[NDISC_OPS_REDIRECT_DATA_SPACE], *ops_data = NULL;
|
||||
int oif = l3mdev_fib_oif(dev);
|
||||
bool ret;
|
||||
|
||||
if (ipv6_get_lladdr(dev, &saddr_buf, IFA_F_TENTATIVE)) {
|
||||
|
|
@ -1555,10 +1551,7 @@ 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, oif);
|
||||
|
||||
if (oif != skb->dev->ifindex)
|
||||
fl6.flowi6_flags |= FLOWI_FLAG_L3MDEV_SRC;
|
||||
&saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex);
|
||||
|
||||
dst = ip6_route_output(net, NULL, &fl6);
|
||||
if (dst->error) {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ static unsigned int nf_route_table_hook(void *priv,
|
|||
struct in6_addr saddr, daddr;
|
||||
u_int8_t hop_limit;
|
||||
u32 mark, flowlabel;
|
||||
int err;
|
||||
|
||||
nft_set_pktinfo_ipv6(&pkt, skb, state);
|
||||
|
||||
|
|
@ -44,13 +45,16 @@ static unsigned int nf_route_table_hook(void *priv,
|
|||
flowlabel = *((u32 *)ipv6_hdr(skb));
|
||||
|
||||
ret = nft_do_chain(&pkt, priv);
|
||||
if (ret != NF_DROP && ret != NF_QUEUE &&
|
||||
if (ret != NF_DROP && ret != NF_STOLEN &&
|
||||
(memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) ||
|
||||
memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) ||
|
||||
skb->mark != mark ||
|
||||
ipv6_hdr(skb)->hop_limit != hop_limit ||
|
||||
flowlabel != *((u_int32_t *)ipv6_hdr(skb))))
|
||||
return ip6_route_me_harder(state->net, skb) == 0 ? ret : NF_DROP;
|
||||
flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
|
||||
err = ip6_route_me_harder(state->net, skb);
|
||||
if (err < 0)
|
||||
ret = NF_DROP_ERR(err);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ static const struct nft_expr_ops nft_reject_ipv6_ops = {
|
|||
.eval = nft_reject_ipv6_eval,
|
||||
.init = nft_reject_init,
|
||||
.dump = nft_reject_dump,
|
||||
.validate = nft_reject_validate,
|
||||
};
|
||||
|
||||
static struct nft_expr_type nft_reject_ipv6_type __read_mostly = {
|
||||
|
|
|
|||
|
|
@ -148,6 +148,13 @@ int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|||
ipv6_hdr(skb)->payload_len = htons(len);
|
||||
IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
|
||||
|
||||
/* if egress device is enslaved to an L3 master device pass the
|
||||
* skb to its handler for processing
|
||||
*/
|
||||
skb = l3mdev_ip6_out(sk, skb);
|
||||
if (unlikely(!skb))
|
||||
return 0;
|
||||
|
||||
return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
|
||||
net, sk, skb, NULL, skb_dst(skb)->dev,
|
||||
dst_output);
|
||||
|
|
|
|||
|
|
@ -126,8 +126,10 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
rt = (struct rt6_info *) dst;
|
||||
|
||||
np = inet6_sk(sk);
|
||||
if (!np)
|
||||
return -EBADF;
|
||||
if (!np) {
|
||||
err = -EBADF;
|
||||
goto dst_err_out;
|
||||
}
|
||||
|
||||
if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
|
||||
fl6.flowi6_oif = np->mcast_oif;
|
||||
|
|
@ -163,6 +165,9 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
}
|
||||
release_sock(sk);
|
||||
|
||||
dst_err_out:
|
||||
dst_release(dst);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
|||
|
|
@ -653,6 +653,13 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
|
|||
if (err)
|
||||
goto error_fault;
|
||||
|
||||
/* if egress device is enslaved to an L3 master device pass the
|
||||
* skb to its handler for processing
|
||||
*/
|
||||
skb = l3mdev_ip6_out(sk, skb);
|
||||
if (unlikely(!skb))
|
||||
return 0;
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -1147,15 +1147,16 @@ static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *
|
|||
return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags);
|
||||
}
|
||||
|
||||
static struct dst_entry *ip6_route_input_lookup(struct net *net,
|
||||
struct net_device *dev,
|
||||
struct flowi6 *fl6, int flags)
|
||||
struct dst_entry *ip6_route_input_lookup(struct net *net,
|
||||
struct net_device *dev,
|
||||
struct flowi6 *fl6, int flags)
|
||||
{
|
||||
if (rt6_need_strict(&fl6->daddr) && dev->type != ARPHRD_PIMREG)
|
||||
flags |= RT6_LOOKUP_F_IFACE;
|
||||
|
||||
return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_input);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ip6_route_input_lookup);
|
||||
|
||||
void ip6_route_input(struct sk_buff *skb)
|
||||
{
|
||||
|
|
@ -1164,7 +1165,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 = l3mdev_fib_oif(skb->dev),
|
||||
.flowi6_iif = skb->dev->ifindex,
|
||||
.daddr = iph->daddr,
|
||||
.saddr = iph->saddr,
|
||||
.flowlabel = ip6_flowinfo(iph),
|
||||
|
|
@ -1188,12 +1189,15 @@ static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table
|
|||
struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
|
||||
struct flowi6 *fl6, int flags)
|
||||
{
|
||||
struct dst_entry *dst;
|
||||
bool any_src;
|
||||
|
||||
dst = l3mdev_get_rt6_dst(net, fl6);
|
||||
if (dst)
|
||||
return dst;
|
||||
if (rt6_need_strict(&fl6->daddr)) {
|
||||
struct dst_entry *dst;
|
||||
|
||||
dst = l3mdev_link_scope_lookup(net, fl6);
|
||||
if (dst)
|
||||
return dst;
|
||||
}
|
||||
|
||||
fl6->flowi6_iif = LOOPBACK_IFINDEX;
|
||||
|
||||
|
|
@ -1988,9 +1992,18 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg)
|
|||
if (!(gwa_type & IPV6_ADDR_UNICAST))
|
||||
goto out;
|
||||
|
||||
if (cfg->fc_table)
|
||||
if (cfg->fc_table) {
|
||||
grt = ip6_nh_lookup_table(net, cfg, gw_addr);
|
||||
|
||||
if (grt) {
|
||||
if (grt->rt6i_flags & RTF_GATEWAY ||
|
||||
(dev && dev != grt->dst.dev)) {
|
||||
ip6_rt_put(grt);
|
||||
grt = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!grt)
|
||||
grt = rt6_lookup(net, gw_addr, NULL,
|
||||
cfg->fc_ifindex, 1);
|
||||
|
|
@ -2558,8 +2571,16 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
|
|||
{
|
||||
u32 tb_id;
|
||||
struct net *net = dev_net(idev->dev);
|
||||
struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev,
|
||||
DST_NOCOUNT);
|
||||
struct net_device *dev = net->loopback_dev;
|
||||
struct rt6_info *rt;
|
||||
|
||||
/* use L3 Master device as loopback for host routes if device
|
||||
* is enslaved and address is not link local or multicast
|
||||
*/
|
||||
if (!rt6_need_strict(addr))
|
||||
dev = l3mdev_master_dev_rcu(idev->dev) ? : dev;
|
||||
|
||||
rt = ip6_dst_alloc(net, dev, DST_NOCOUNT);
|
||||
if (!rt)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
|
@ -3338,11 +3359,6 @@ 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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -818,12 +818,8 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
|
|||
fl6.flowi6_proto = IPPROTO_TCP;
|
||||
if (rt6_need_strict(&fl6.daddr) && !oif)
|
||||
fl6.flowi6_oif = tcp_v6_iif(skb);
|
||||
else {
|
||||
if (!oif && netif_index_is_l3_master(net, skb->skb_iif))
|
||||
oif = skb->skb_iif;
|
||||
|
||||
fl6.flowi6_oif = oif;
|
||||
}
|
||||
else
|
||||
fl6.flowi6_oif = oif ? : skb->skb_iif;
|
||||
|
||||
fl6.flowi6_mark = IP6_REPLY_MARK(net, skb->mark);
|
||||
fl6.fl6_dport = t1->dest;
|
||||
|
|
|
|||
|
|
@ -21,8 +21,10 @@ int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb)
|
|||
return xfrm6_extract_header(skb);
|
||||
}
|
||||
|
||||
int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
|
||||
int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
|
||||
struct ip6_tnl *t)
|
||||
{
|
||||
XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t;
|
||||
XFRM_SPI_SKB_CB(skb)->family = AF_INET6;
|
||||
XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
|
||||
return xfrm_input(skb, nexthdr, spi, 0);
|
||||
|
|
@ -48,13 +50,18 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int xfrm6_rcv(struct sk_buff *skb)
|
||||
int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t)
|
||||
{
|
||||
return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
|
||||
0);
|
||||
0, t);
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm6_rcv_tnl);
|
||||
|
||||
int xfrm6_rcv(struct sk_buff *skb)
|
||||
{
|
||||
return xfrm6_rcv_tnl(skb, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm6_rcv);
|
||||
|
||||
int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
|
||||
xfrm_address_t *saddr, u8 proto)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,
|
|||
int err;
|
||||
|
||||
memset(&fl6, 0, sizeof(fl6));
|
||||
fl6.flowi6_oif = oif;
|
||||
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)
|
||||
|
|
@ -134,7 +134,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
|
|||
nexthdr = nh[nhoff];
|
||||
|
||||
if (skb_dst(skb))
|
||||
oif = l3mdev_fib_oif(skb_dst(skb)->dev);
|
||||
oif = skb_dst(skb)->dev->ifindex;
|
||||
|
||||
memset(fl6, 0, sizeof(struct flowi6));
|
||||
fl6->flowi6_mark = skb->mark;
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb)
|
|||
__be32 spi;
|
||||
|
||||
spi = xfrm6_tunnel_spi_lookup(net, (const xfrm_address_t *)&iph->saddr);
|
||||
return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi);
|
||||
return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi, NULL);
|
||||
}
|
||||
|
||||
static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
||||
|
|
|
|||
Loading…
Reference in a new issue