Merge branch 'net-next-2.6-v6ready-20080703' of git://git.linux-ipv6.org/gitroot/yoshfuji/linux-2.6-next
This commit is contained in:
Коммит
44d28ab19c
|
@ -1025,6 +1025,17 @@ max_addresses - INTEGER
|
|||
autoconfigured addresses.
|
||||
Default: 16
|
||||
|
||||
disable_ipv6 - BOOLEAN
|
||||
Disable IPv6 operation.
|
||||
Default: FALSE (enable IPv6 operation)
|
||||
|
||||
accept_dad - INTEGER
|
||||
Whether to accept DAD (Duplicate Address Detection).
|
||||
0: Disable DAD
|
||||
1: Enable DAD (default)
|
||||
2: Enable DAD, and disable IPv6 operation if MAC-based duplicate
|
||||
link-local address has been found.
|
||||
|
||||
icmp/*:
|
||||
ratelimit - INTEGER
|
||||
Limit the maximal rates for sending ICMPv6 packets.
|
||||
|
|
|
@ -228,7 +228,6 @@ extern int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
|
|||
extern int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
|
||||
struct group_filter __user *optval, int __user *optlen);
|
||||
extern int ip_mc_sf_allow(struct sock *sk, __be32 local, __be32 rmt, int dif);
|
||||
extern void ip_mr_init(void);
|
||||
extern void ip_mc_init_dev(struct in_device *);
|
||||
extern void ip_mc_destroy_dev(struct in_device *);
|
||||
extern void ip_mc_up(struct in_device *);
|
||||
|
|
|
@ -163,6 +163,8 @@ struct ipv6_devconf {
|
|||
#ifdef CONFIG_IPV6_MROUTE
|
||||
__s32 mc_forwarding;
|
||||
#endif
|
||||
__s32 disable_ipv6;
|
||||
__s32 accept_dad;
|
||||
void *sysctl;
|
||||
};
|
||||
|
||||
|
@ -194,6 +196,8 @@ enum {
|
|||
DEVCONF_OPTIMISTIC_DAD,
|
||||
DEVCONF_ACCEPT_SOURCE_ROUTE,
|
||||
DEVCONF_MC_FORWARDING,
|
||||
DEVCONF_DISABLE_IPV6,
|
||||
DEVCONF_ACCEPT_DAD,
|
||||
DEVCONF_MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -144,11 +144,37 @@ static inline int ip_mroute_opt(int opt)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IP_MROUTE
|
||||
extern int ip_mroute_setsockopt(struct sock *, int, char __user *, int);
|
||||
extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
|
||||
extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
|
||||
extern void ip_mr_init(void);
|
||||
extern int ip_mr_init(void);
|
||||
#else
|
||||
static inline
|
||||
int ip_mroute_setsockopt(struct sock *sock,
|
||||
int optname, char __user *optval, int optlen)
|
||||
{
|
||||
return -ENOPROTOOPT;
|
||||
}
|
||||
|
||||
static inline
|
||||
int ip_mroute_getsockopt(struct sock *sock,
|
||||
int optname, char __user *optval, int __user *optlen)
|
||||
{
|
||||
return -ENOPROTOOPT;
|
||||
}
|
||||
|
||||
static inline
|
||||
int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
|
||||
{
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
static inline int ip_mr_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct vif_device
|
||||
{
|
||||
|
|
|
@ -131,11 +131,44 @@ static inline int ip6_mroute_opt(int opt)
|
|||
|
||||
struct sock;
|
||||
|
||||
#ifdef CONFIG_IPV6_MROUTE
|
||||
extern int ip6_mroute_setsockopt(struct sock *, int, char __user *, int);
|
||||
extern int ip6_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
|
||||
extern int ip6_mr_input(struct sk_buff *skb);
|
||||
extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg);
|
||||
extern void ip6_mr_init(void);
|
||||
extern int ip6_mr_init(void);
|
||||
extern void ip6_mr_cleanup(void);
|
||||
#else
|
||||
static inline
|
||||
int ip6_mroute_setsockopt(struct sock *sock,
|
||||
int optname, char __user *optval, int optlen)
|
||||
{
|
||||
return -ENOPROTOOPT;
|
||||
}
|
||||
|
||||
static inline
|
||||
int ip6_mroute_getsockopt(struct sock *sock,
|
||||
int optname, char __user *optval, int __user *optlen)
|
||||
{
|
||||
return -ENOPROTOOPT;
|
||||
}
|
||||
|
||||
static inline
|
||||
int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
|
||||
{
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
static inline int ip6_mr_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ip6_mr_cleanup(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct mif_device
|
||||
{
|
||||
|
|
|
@ -1479,14 +1479,15 @@ static int __init inet_init(void)
|
|||
* Initialise the multicast router
|
||||
*/
|
||||
#if defined(CONFIG_IP_MROUTE)
|
||||
ip_mr_init();
|
||||
if (ip_mr_init())
|
||||
printk(KERN_CRIT "inet_init: Cannot init ipv4 mroute\n");
|
||||
#endif
|
||||
/*
|
||||
* Initialise per-cpu ipv4 mibs
|
||||
*/
|
||||
|
||||
if (init_ipv4_mibs())
|
||||
printk(KERN_CRIT "inet_init: Cannot init ipv4 mibs\n"); ;
|
||||
printk(KERN_CRIT "inet_init: Cannot init ipv4 mibs\n");
|
||||
|
||||
ipv4_proc_init();
|
||||
|
||||
|
|
|
@ -1878,16 +1878,36 @@ static struct net_protocol pim_protocol = {
|
|||
* Setup for IP multicast routing
|
||||
*/
|
||||
|
||||
void __init ip_mr_init(void)
|
||||
int __init ip_mr_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
mrt_cachep = kmem_cache_create("ip_mrt_cache",
|
||||
sizeof(struct mfc_cache),
|
||||
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
|
||||
NULL);
|
||||
if (!mrt_cachep)
|
||||
return -ENOMEM;
|
||||
|
||||
setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0);
|
||||
register_netdevice_notifier(&ip_mr_notifier);
|
||||
err = register_netdevice_notifier(&ip_mr_notifier);
|
||||
if (err)
|
||||
goto reg_notif_fail;
|
||||
#ifdef CONFIG_PROC_FS
|
||||
proc_net_fops_create(&init_net, "ip_mr_vif", 0, &ipmr_vif_fops);
|
||||
proc_net_fops_create(&init_net, "ip_mr_cache", 0, &ipmr_mfc_fops);
|
||||
err = -ENOMEM;
|
||||
if (!proc_net_fops_create(&init_net, "ip_mr_vif", 0, &ipmr_vif_fops))
|
||||
goto proc_vif_fail;
|
||||
if (!proc_net_fops_create(&init_net, "ip_mr_cache", 0, &ipmr_mfc_fops))
|
||||
goto proc_cache_fail;
|
||||
#endif
|
||||
return 0;
|
||||
reg_notif_fail:
|
||||
kmem_cache_destroy(mrt_cachep);
|
||||
#ifdef CONFIG_PROC_FS
|
||||
proc_vif_fail:
|
||||
unregister_netdevice_notifier(&ip_mr_notifier);
|
||||
proc_cache_fail:
|
||||
proc_net_remove(&init_net, "ip_mr_vif");
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -119,6 +119,7 @@ static void ipv6_regen_rndid(unsigned long data);
|
|||
static int desync_factor = MAX_DESYNC_FACTOR * HZ;
|
||||
#endif
|
||||
|
||||
static int ipv6_generate_eui64(u8 *eui, struct net_device *dev);
|
||||
static int ipv6_count_addresses(struct inet6_dev *idev);
|
||||
|
||||
/*
|
||||
|
@ -183,6 +184,8 @@ struct ipv6_devconf ipv6_devconf __read_mostly = {
|
|||
#endif
|
||||
.proxy_ndp = 0,
|
||||
.accept_source_route = 0, /* we do not accept RH0 by default. */
|
||||
.disable_ipv6 = 0,
|
||||
.accept_dad = 1,
|
||||
};
|
||||
|
||||
static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
|
||||
|
@ -215,6 +218,8 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
|
|||
#endif
|
||||
.proxy_ndp = 0,
|
||||
.accept_source_route = 0, /* we do not accept RH0 by default. */
|
||||
.disable_ipv6 = 0,
|
||||
.accept_dad = 1,
|
||||
};
|
||||
|
||||
/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
|
||||
|
@ -378,6 +383,9 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
|
|||
*/
|
||||
in6_dev_hold(ndev);
|
||||
|
||||
if (dev->flags & (IFF_NOARP | IFF_LOOPBACK))
|
||||
ndev->cnf.accept_dad = -1;
|
||||
|
||||
#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
|
||||
if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
|
||||
printk(KERN_INFO
|
||||
|
@ -578,6 +586,13 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
|
|||
struct rt6_info *rt;
|
||||
int hash;
|
||||
int err = 0;
|
||||
int addr_type = ipv6_addr_type(addr);
|
||||
|
||||
if (addr_type == IPV6_ADDR_ANY ||
|
||||
addr_type & IPV6_ADDR_MULTICAST ||
|
||||
(!(idev->dev->flags & IFF_LOOPBACK) &&
|
||||
addr_type & IPV6_ADDR_LOOPBACK))
|
||||
return ERR_PTR(-EADDRNOTAVAIL);
|
||||
|
||||
rcu_read_lock_bh();
|
||||
if (idev->dead) {
|
||||
|
@ -1412,6 +1427,20 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp)
|
|||
|
||||
void addrconf_dad_failure(struct inet6_ifaddr *ifp)
|
||||
{
|
||||
struct inet6_dev *idev = ifp->idev;
|
||||
if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) {
|
||||
struct in6_addr addr;
|
||||
|
||||
addr.s6_addr32[0] = htonl(0xfe800000);
|
||||
addr.s6_addr32[1] = 0;
|
||||
|
||||
if (!ipv6_generate_eui64(addr.s6_addr + 8, idev->dev) &&
|
||||
ipv6_addr_equal(&ifp->addr, &addr)) {
|
||||
/* DAD failed for link-local based on MAC address */
|
||||
idev->cnf.disable_ipv6 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (net_ratelimit())
|
||||
printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name);
|
||||
addrconf_dad_stop(ifp);
|
||||
|
@ -2744,6 +2773,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
|
|||
spin_lock_bh(&ifp->lock);
|
||||
|
||||
if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
|
||||
idev->cnf.accept_dad < 1 ||
|
||||
!(ifp->flags&IFA_F_TENTATIVE) ||
|
||||
ifp->flags & IFA_F_NODAD) {
|
||||
ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
|
||||
|
@ -2791,6 +2821,11 @@ static void addrconf_dad_timer(unsigned long data)
|
|||
read_unlock_bh(&idev->lock);
|
||||
goto out;
|
||||
}
|
||||
if (idev->cnf.accept_dad > 1 && idev->cnf.disable_ipv6) {
|
||||
read_unlock_bh(&idev->lock);
|
||||
addrconf_dad_failure(ifp);
|
||||
return;
|
||||
}
|
||||
spin_lock_bh(&ifp->lock);
|
||||
if (ifp->probes == 0) {
|
||||
/*
|
||||
|
@ -3650,6 +3685,8 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
|
|||
#ifdef CONFIG_IPV6_MROUTE
|
||||
array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding;
|
||||
#endif
|
||||
array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
|
||||
array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
|
||||
}
|
||||
|
||||
static inline size_t inet6_if_nlmsg_size(void)
|
||||
|
@ -4208,6 +4245,22 @@ static struct addrconf_sysctl_table
|
|||
.proc_handler = &proc_dointvec,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.ctl_name = CTL_UNNUMBERED,
|
||||
.procname = "disable_ipv6",
|
||||
.data = &ipv6_devconf.disable_ipv6,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = &proc_dointvec,
|
||||
},
|
||||
{
|
||||
.ctl_name = CTL_UNNUMBERED,
|
||||
.procname = "accept_dad",
|
||||
.data = &ipv6_devconf.accept_dad,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = &proc_dointvec,
|
||||
},
|
||||
{
|
||||
.ctl_name = 0, /* sentinel */
|
||||
}
|
||||
|
|
|
@ -59,9 +59,7 @@
|
|||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/system.h>
|
||||
#ifdef CONFIG_IPV6_MROUTE
|
||||
#include <linux/mroute6.h>
|
||||
#endif
|
||||
|
||||
MODULE_AUTHOR("Cast of dozens");
|
||||
MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
|
||||
|
@ -952,9 +950,9 @@ static int __init inet6_init(void)
|
|||
err = icmpv6_init();
|
||||
if (err)
|
||||
goto icmp_fail;
|
||||
#ifdef CONFIG_IPV6_MROUTE
|
||||
ip6_mr_init();
|
||||
#endif
|
||||
err = ip6_mr_init();
|
||||
if (err)
|
||||
goto ipmr_fail;
|
||||
err = ndisc_init();
|
||||
if (err)
|
||||
goto ndisc_fail;
|
||||
|
@ -1057,6 +1055,8 @@ netfilter_fail:
|
|||
igmp_fail:
|
||||
ndisc_cleanup();
|
||||
ndisc_fail:
|
||||
ip6_mr_cleanup();
|
||||
ipmr_fail:
|
||||
icmpv6_cleanup();
|
||||
icmp_fail:
|
||||
unregister_pernet_subsys(&inet6_net_ops);
|
||||
|
@ -1111,6 +1111,7 @@ static void __exit inet6_exit(void)
|
|||
ipv6_netfilter_fini();
|
||||
igmp6_cleanup();
|
||||
ndisc_cleanup();
|
||||
ip6_mr_cleanup();
|
||||
icmpv6_cleanup();
|
||||
rawv6_exit();
|
||||
|
||||
|
|
|
@ -71,7 +71,8 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
|
|||
|
||||
IP6_INC_STATS_BH(idev, IPSTATS_MIB_INRECEIVES);
|
||||
|
||||
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
|
||||
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
|
||||
!idev || unlikely(idev->cnf.disable_ipv6)) {
|
||||
IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
|
|
|
@ -173,6 +173,13 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
|
|||
|
||||
int ip6_output(struct sk_buff *skb)
|
||||
{
|
||||
struct inet6_dev *idev = ip6_dst_idev(skb->dst);
|
||||
if (unlikely(idev->cnf.disable_ipv6)) {
|
||||
IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS);
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
|
||||
dst_allfrag(skb->dst))
|
||||
return ip6_fragment(skb, ip6_output2);
|
||||
|
@ -498,7 +505,8 @@ int ip6_forward(struct sk_buff *skb)
|
|||
int addrtype = ipv6_addr_type(&hdr->saddr);
|
||||
|
||||
/* This check is security critical. */
|
||||
if (addrtype & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK))
|
||||
if (addrtype == IPV6_ADDR_ANY ||
|
||||
addrtype & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LOOPBACK))
|
||||
goto error;
|
||||
if (addrtype & IPV6_ADDR_LINKLOCAL) {
|
||||
icmpv6_send(skb, ICMPV6_DEST_UNREACH,
|
||||
|
|
|
@ -948,23 +948,51 @@ static struct notifier_block ip6_mr_notifier = {
|
|||
* Setup for IP multicast routing
|
||||
*/
|
||||
|
||||
void __init ip6_mr_init(void)
|
||||
int __init ip6_mr_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
mrt_cachep = kmem_cache_create("ip6_mrt_cache",
|
||||
sizeof(struct mfc6_cache),
|
||||
0, SLAB_HWCACHE_ALIGN,
|
||||
NULL);
|
||||
if (!mrt_cachep)
|
||||
panic("cannot allocate ip6_mrt_cache");
|
||||
return -ENOMEM;
|
||||
|
||||
setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0);
|
||||
register_netdevice_notifier(&ip6_mr_notifier);
|
||||
err = register_netdevice_notifier(&ip6_mr_notifier);
|
||||
if (err)
|
||||
goto reg_notif_fail;
|
||||
#ifdef CONFIG_PROC_FS
|
||||
proc_net_fops_create(&init_net, "ip6_mr_vif", 0, &ip6mr_vif_fops);
|
||||
proc_net_fops_create(&init_net, "ip6_mr_cache", 0, &ip6mr_mfc_fops);
|
||||
err = -ENOMEM;
|
||||
if (!proc_net_fops_create(&init_net, "ip6_mr_vif", 0, &ip6mr_vif_fops))
|
||||
goto proc_vif_fail;
|
||||
if (!proc_net_fops_create(&init_net, "ip6_mr_cache",
|
||||
0, &ip6mr_mfc_fops))
|
||||
goto proc_cache_fail;
|
||||
#endif
|
||||
return 0;
|
||||
reg_notif_fail:
|
||||
kmem_cache_destroy(mrt_cachep);
|
||||
#ifdef CONFIG_PROC_FS
|
||||
proc_vif_fail:
|
||||
unregister_netdevice_notifier(&ip6_mr_notifier);
|
||||
proc_cache_fail:
|
||||
proc_net_remove(&init_net, "ip6_mr_vif");
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
void ip6_mr_cleanup(void)
|
||||
{
|
||||
#ifdef CONFIG_PROC_FS
|
||||
proc_net_remove(&init_net, "ip6_mr_cache");
|
||||
proc_net_remove(&init_net, "ip6_mr_vif");
|
||||
#endif
|
||||
unregister_netdevice_notifier(&ip6_mr_notifier);
|
||||
del_timer(&ipmr_expire_timer);
|
||||
kmem_cache_destroy(mrt_cachep);
|
||||
}
|
||||
|
||||
static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock)
|
||||
{
|
||||
|
|
|
@ -228,7 +228,7 @@ static __inline__ int rt6_check_expired(const struct rt6_info *rt)
|
|||
static inline int rt6_need_strict(struct in6_addr *daddr)
|
||||
{
|
||||
return (ipv6_addr_type(daddr) &
|
||||
(IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
|
||||
(IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -237,15 +237,20 @@ static inline int rt6_need_strict(struct in6_addr *daddr)
|
|||
|
||||
static inline struct rt6_info *rt6_device_match(struct net *net,
|
||||
struct rt6_info *rt,
|
||||
struct in6_addr *saddr,
|
||||
int oif,
|
||||
int flags)
|
||||
{
|
||||
struct rt6_info *local = NULL;
|
||||
struct rt6_info *sprt;
|
||||
|
||||
if (oif) {
|
||||
for (sprt = rt; sprt; sprt = sprt->u.dst.rt6_next) {
|
||||
struct net_device *dev = sprt->rt6i_dev;
|
||||
if (!oif && ipv6_addr_any(saddr))
|
||||
goto out;
|
||||
|
||||
for (sprt = rt; sprt; sprt = sprt->u.dst.rt6_next) {
|
||||
struct net_device *dev = sprt->rt6i_dev;
|
||||
|
||||
if (oif) {
|
||||
if (dev->ifindex == oif)
|
||||
return sprt;
|
||||
if (dev->flags & IFF_LOOPBACK) {
|
||||
|
@ -259,14 +264,21 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
|
|||
}
|
||||
local = sprt;
|
||||
}
|
||||
} else {
|
||||
if (ipv6_chk_addr(net, saddr, dev,
|
||||
flags & RT6_LOOKUP_F_IFACE))
|
||||
return sprt;
|
||||
}
|
||||
}
|
||||
|
||||
if (oif) {
|
||||
if (local)
|
||||
return local;
|
||||
|
||||
if (flags & RT6_LOOKUP_F_IFACE)
|
||||
return net->ipv6.ip6_null_entry;
|
||||
}
|
||||
out:
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
@ -539,7 +551,7 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net,
|
|||
fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
|
||||
restart:
|
||||
rt = fn->leaf;
|
||||
rt = rt6_device_match(net, rt, fl->oif, flags);
|
||||
rt = rt6_device_match(net, rt, &fl->fl6_src, fl->oif, flags);
|
||||
BACKTRACK(net, &fl->fl6_src);
|
||||
out:
|
||||
dst_use(&rt->u.dst, jiffies);
|
||||
|
|
Загрузка…
Ссылка в новой задаче