Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
effef85f
Commit
effef85f
authored
Aug 18, 2004
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge nuts.davemloft.net:/disk1/BK/ip6route-2.6
into nuts.davemloft.net:/disk1/BK/net-2.6
parents
44716493
6dad59bb
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
145 additions
and
73 deletions
+145
-73
include/net/if_inet6.h
include/net/if_inet6.h
+2
-0
include/net/ip6_route.h
include/net/ip6_route.h
+7
-0
net/ipv4/route.c
net/ipv4/route.c
+6
-3
net/ipv6/addrconf.c
net/ipv6/addrconf.c
+35
-14
net/ipv6/anycast.c
net/ipv6/anycast.c
+29
-11
net/ipv6/ip6_fib.c
net/ipv6/ip6_fib.c
+4
-3
net/ipv6/route.c
net/ipv6/route.c
+62
-42
No files found.
include/net/if_inet6.h
View file @
effef85f
...
...
@@ -51,6 +51,7 @@ struct inet6_ifaddr
struct
timer_list
timer
;
struct
inet6_dev
*
idev
;
struct
rt6_info
*
rt
;
struct
inet6_ifaddr
*
lst_next
;
/* next addr in addr_lst */
struct
inet6_ifaddr
*
if_next
;
/* next addr in inet6_dev */
...
...
@@ -133,6 +134,7 @@ struct ifacaddr6
{
struct
in6_addr
aca_addr
;
struct
inet6_dev
*
aca_idev
;
struct
rt6_info
*
aca_rt
;
struct
ifacaddr6
*
aca_next
;
int
aca_users
;
atomic_t
aca_refcnt
;
...
...
include/net/ip6_route.h
View file @
effef85f
...
...
@@ -42,6 +42,9 @@ extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg);
extern
int
ip6_route_add
(
struct
in6_rtmsg
*
rtmsg
,
struct
nlmsghdr
*
,
void
*
rtattr
);
extern
int
ip6_ins_rt
(
struct
rt6_info
*
,
struct
nlmsghdr
*
,
void
*
rtattr
);
extern
int
ip6_del_rt
(
struct
rt6_info
*
,
struct
nlmsghdr
*
,
void
*
rtattr
);
...
...
@@ -71,6 +74,10 @@ extern struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
extern
int
ndisc_dst_gc
(
int
*
more
);
extern
void
fib6_force_start_gc
(
void
);
extern
struct
rt6_info
*
addrconf_dst_alloc
(
struct
inet6_dev
*
idev
,
const
struct
in6_addr
*
addr
,
int
anycast
);
/*
* support functions for ND
*
...
...
net/ipv4/route.c
View file @
effef85f
...
...
@@ -1342,9 +1342,12 @@ static void ipv4_dst_ifdown(struct dst_entry *dst, int how)
{
struct
rtable
*
rt
=
(
struct
rtable
*
)
dst
;
struct
in_device
*
idev
=
rt
->
idev
;
if
(
idev
)
{
rt
->
idev
=
NULL
;
in_dev_put
(
idev
);
if
(
idev
&&
idev
->
dev
!=
&
loopback_dev
)
{
struct
in_device
*
loopback_idev
=
in_dev_get
(
&
loopback_dev
);
if
(
loopback_idev
)
{
rt
->
idev
=
loopback_idev
;
in_dev_put
(
idev
);
}
}
}
...
...
net/ipv6/addrconf.c
View file @
effef85f
...
...
@@ -472,6 +472,8 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
printk
(
"Freeing alive inet6 address %p
\n
"
,
ifp
);
return
;
}
dst_release
(
&
ifp
->
rt
->
u
.
dst
);
inet6_ifa_count
--
;
kfree
(
ifp
);
}
...
...
@@ -482,25 +484,33 @@ static struct inet6_ifaddr *
ipv6_add_addr
(
struct
inet6_dev
*
idev
,
const
struct
in6_addr
*
addr
,
int
pfxlen
,
int
scope
,
unsigned
flags
)
{
struct
inet6_ifaddr
*
ifa
;
struct
inet6_ifaddr
*
ifa
=
NULL
;
struct
rt6_info
*
rt
;
int
hash
;
static
spinlock_t
lock
=
SPIN_LOCK_UNLOCKED
;
int
err
=
0
;
spin_lock_bh
(
&
lock
);
/* Ignore adding duplicate addresses on an interface */
if
(
ipv6_chk_same_addr
(
addr
,
idev
->
dev
))
{
spin_unlock_bh
(
&
lock
);
ADBG
((
"ipv6_add_addr: already assigned
\n
"
));
return
ERR_PTR
(
-
EEXIST
);
err
=
-
EEXIST
;
goto
out
;
}
ifa
=
kmalloc
(
sizeof
(
struct
inet6_ifaddr
),
GFP_ATOMIC
);
if
(
ifa
==
NULL
)
{
spin_unlock_bh
(
&
lock
);
ADBG
((
"ipv6_add_addr: malloc failed
\n
"
));
return
ERR_PTR
(
-
ENOBUFS
);
err
=
-
ENOBUFS
;
goto
out
;
}
rt
=
addrconf_dst_alloc
(
idev
,
addr
,
0
);
if
(
IS_ERR
(
rt
))
{
err
=
PTR_ERR
(
rt
);
goto
out
;
}
memset
(
ifa
,
0
,
sizeof
(
struct
inet6_ifaddr
));
...
...
@@ -517,9 +527,8 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
read_lock
(
&
addrconf_lock
);
if
(
idev
->
dead
)
{
read_unlock
(
&
addrconf_lock
);
spin_unlock_bh
(
&
lock
);
kfree
(
ifa
);
return
ERR_PTR
(
-
ENODEV
);
/*XXX*/
err
=
-
ENODEV
;
/*XXX*/
goto
out
;
}
inet6_ifa_count
++
;
...
...
@@ -553,12 +562,20 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
}
#endif
ifa
->
rt
=
rt
;
in6_ifa_hold
(
ifa
);
write_unlock_bh
(
&
idev
->
lock
);
read_unlock
(
&
addrconf_lock
);
out:
spin_unlock_bh
(
&
lock
);
notifier_call_chain
(
&
inet6addr_chain
,
NETDEV_UP
,
ifa
);
if
(
unlikely
(
err
==
0
))
notifier_call_chain
(
&
inet6addr_chain
,
NETDEV_UP
,
ifa
);
else
{
kfree
(
ifa
);
ifa
=
ERR_PTR
(
err
);
}
return
ifa
;
}
...
...
@@ -1457,8 +1474,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
spin_unlock
(
&
ifp
->
lock
);
if
(
!
(
flags
&
IFA_F_TENTATIVE
))
ipv6_ifa_notify
((
flags
&
IFA_F_DEPRECATED
)
?
0
:
RTM_NEWADDR
,
ifp
);
ipv6_ifa_notify
(
0
,
ifp
);
}
else
spin_unlock
(
&
ifp
->
lock
);
...
...
@@ -2982,7 +2998,9 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
switch
(
event
)
{
case
RTM_NEWADDR
:
ip6_rt_addr_add
(
&
ifp
->
addr
,
ifp
->
idev
->
dev
,
0
);
dst_hold
(
&
ifp
->
rt
->
u
.
dst
);
if
(
ip6_ins_rt
(
ifp
->
rt
,
NULL
,
NULL
))
dst_release
(
&
ifp
->
rt
->
u
.
dst
);
break
;
case
RTM_DELADDR
:
addrconf_leave_solict
(
ifp
->
idev
->
dev
,
&
ifp
->
addr
);
...
...
@@ -2993,8 +3011,11 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
if
(
!
ipv6_addr_any
(
&
addr
))
ipv6_dev_ac_dec
(
ifp
->
idev
->
dev
,
&
addr
);
}
if
(
!
ipv6_chk_addr
(
&
ifp
->
addr
,
ifp
->
idev
->
dev
,
1
))
ip6_rt_addr_del
(
&
ifp
->
addr
,
ifp
->
idev
->
dev
);
dst_hold
(
&
ifp
->
rt
->
u
.
dst
);
if
(
ip6_del_rt
(
ifp
->
rt
,
NULL
,
NULL
))
dst_free
(
&
ifp
->
rt
->
u
.
dst
);
else
dst_release
(
&
ifp
->
rt
->
u
.
dst
);
break
;
}
}
...
...
net/ipv6/anycast.c
View file @
effef85f
...
...
@@ -293,6 +293,7 @@ static void aca_put(struct ifacaddr6 *ac)
{
if
(
atomic_dec_and_test
(
&
ac
->
aca_refcnt
))
{
in6_dev_put
(
ac
->
aca_idev
);
dst_release
(
&
ac
->
aca_rt
->
u
.
dst
);
kfree
(
ac
);
}
}
...
...
@@ -304,6 +305,8 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr)
{
struct
ifacaddr6
*
aca
;
struct
inet6_dev
*
idev
;
struct
rt6_info
*
rt
;
int
err
;
idev
=
in6_dev_get
(
dev
);
...
...
@@ -312,17 +315,15 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr)
write_lock_bh
(
&
idev
->
lock
);
if
(
idev
->
dead
)
{
write_unlock_bh
(
&
idev
->
lock
);
in6_dev_put
(
idev
);
return
-
ENODEV
;
err
=
-
ENODEV
;
goto
out
;
}
for
(
aca
=
idev
->
ac_list
;
aca
;
aca
=
aca
->
aca_next
)
{
if
(
ipv6_addr_cmp
(
&
aca
->
aca_addr
,
addr
)
==
0
)
{
aca
->
aca_users
++
;
write_unlock_bh
(
&
idev
->
lock
);
in6_dev_put
(
idev
);
return
0
;
err
=
0
;
goto
out
;
}
}
...
...
@@ -333,15 +334,22 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr)
aca
=
kmalloc
(
sizeof
(
struct
ifacaddr6
),
GFP_ATOMIC
);
if
(
aca
==
NULL
)
{
write_unlock_bh
(
&
idev
->
lock
);
in6_dev_put
(
idev
);
return
-
ENOMEM
;
err
=
-
ENOMEM
;
goto
out
;
}
rt
=
addrconf_dst_alloc
(
idev
,
addr
,
1
);
if
(
IS_ERR
(
rt
))
{
kfree
(
aca
);
err
=
PTR_ERR
(
rt
);
goto
out
;
}
memset
(
aca
,
0
,
sizeof
(
struct
ifacaddr6
));
ipv6_addr_copy
(
&
aca
->
aca_addr
,
addr
);
aca
->
aca_idev
=
idev
;
aca
->
aca_rt
=
rt
;
aca
->
aca_users
=
1
;
/* aca_tstamp should be updated upon changes */
aca
->
aca_cstamp
=
aca
->
aca_tstamp
=
jiffies
;
...
...
@@ -352,12 +360,18 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr)
idev
->
ac_list
=
aca
;
write_unlock_bh
(
&
idev
->
lock
);
ip6_rt_addr_add
(
&
aca
->
aca_addr
,
dev
,
1
);
dst_hold
(
&
rt
->
u
.
dst
);
if
(
ip6_ins_rt
(
rt
,
NULL
,
NULL
))
dst_release
(
&
rt
->
u
.
dst
);
addrconf_join_solict
(
dev
,
&
aca
->
aca_addr
);
aca_put
(
aca
);
return
0
;
out:
write_unlock_bh
(
&
idev
->
lock
);
in6_dev_put
(
idev
);
return
err
;
}
/*
...
...
@@ -396,7 +410,11 @@ int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
write_unlock_bh
(
&
idev
->
lock
);
addrconf_leave_solict
(
dev
,
&
aca
->
aca_addr
);
ip6_rt_addr_del
(
&
aca
->
aca_addr
,
dev
);
dst_hold
(
&
aca
->
aca_rt
->
u
.
dst
);
if
(
ip6_del_rt
(
aca
->
aca_rt
,
NULL
,
NULL
))
dst_free
(
&
aca
->
aca_rt
->
u
.
dst
);
else
dst_release
(
&
aca
->
aca_rt
->
u
.
dst
);
aca_put
(
aca
);
in6_dev_put
(
idev
);
...
...
net/ipv6/ip6_fib.c
View file @
effef85f
...
...
@@ -449,9 +449,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
* Same priority level
*/
if
((
iter
->
rt6i_dev
==
rt
->
rt6i_dev
)
&&
(
ipv6_addr_cmp
(
&
iter
->
rt6i_gateway
,
&
rt
->
rt6i_gateway
)
==
0
))
{
if
(
iter
->
rt6i_dev
==
rt
->
rt6i_dev
&&
iter
->
rt6i_idev
==
rt
->
rt6i_idev
&&
ipv6_addr_cmp
(
&
iter
->
rt6i_gateway
,
&
rt
->
rt6i_gateway
)
==
0
)
{
if
(
!
(
iter
->
rt6i_flags
&
RTF_EXPIRES
))
return
-
EEXIST
;
iter
->
rt6i_expires
=
rt
->
rt6i_expires
;
...
...
net/ipv6/route.c
View file @
effef85f
...
...
@@ -155,7 +155,16 @@ static void ip6_dst_destroy(struct dst_entry *dst)
static
void
ip6_dst_ifdown
(
struct
dst_entry
*
dst
,
int
how
)
{
ip6_dst_destroy
(
dst
);
struct
rt6_info
*
rt
=
(
struct
rt6_info
*
)
dst
;
struct
inet6_dev
*
idev
=
rt
->
rt6i_idev
;
if
(
idev
!=
NULL
&&
idev
->
dev
!=
&
loopback_dev
)
{
struct
inet6_dev
*
loopback_idev
=
in6_dev_get
(
&
loopback_dev
);
if
(
loopback_idev
!=
NULL
)
{
rt
->
rt6i_idev
=
loopback_idev
;
in6_dev_put
(
idev
);
}
}
}
/*
...
...
@@ -174,8 +183,16 @@ static __inline__ struct rt6_info *rt6_device_match(struct rt6_info *rt,
struct
net_device
*
dev
=
sprt
->
rt6i_dev
;
if
(
dev
->
ifindex
==
oif
)
return
sprt
;
if
(
dev
->
flags
&
IFF_LOOPBACK
)
if
(
dev
->
flags
&
IFF_LOOPBACK
)
{
if
(
sprt
->
rt6i_idev
->
dev
->
ifindex
!=
oif
)
{
if
(
strict
&&
oif
)
continue
;
if
(
local
&&
(
!
oif
||
local
->
rt6i_idev
->
dev
->
ifindex
==
oif
))
continue
;
}
local
=
sprt
;
}
}
if
(
local
)
...
...
@@ -336,13 +353,13 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr,
return
NULL
;
}
/*
rt6_ins
is called with FREE rt6_lock.
/*
ip6_ins_rt
is called with FREE rt6_lock.
It takes new route entry, the addition fails by any reason the
route is freed. In any case, if caller does not hold it, it may
be destroyed.
*/
static
int
rt6_ins
(
struct
rt6_info
*
rt
,
struct
nlmsghdr
*
nlh
,
void
*
_rtattr
)
int
ip6_ins_rt
(
struct
rt6_info
*
rt
,
struct
nlmsghdr
*
nlh
,
void
*
_rtattr
)
{
int
err
;
...
...
@@ -390,7 +407,7 @@ static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr,
dst_hold
(
&
rt
->
u
.
dst
);
err
=
rt6_ins
(
rt
,
NULL
,
NULL
);
err
=
ip6_ins_rt
(
rt
,
NULL
,
NULL
);
if
(
err
==
0
)
return
rt
;
...
...
@@ -608,8 +625,13 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
struct
in6_addr
*
addr
,
int
(
*
output
)(
struct
sk_buff
**
))
{
struct
rt6_info
*
rt
=
ip6_dst_alloc
();
struct
rt6_info
*
rt
;
struct
inet6_dev
*
idev
=
in6_dev_get
(
dev
);
if
(
unlikely
(
idev
==
NULL
))
return
NULL
;
rt
=
ip6_dst_alloc
();
if
(
unlikely
(
rt
==
NULL
))
goto
out
;
...
...
@@ -620,7 +642,7 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
neigh
=
ndisc_get_neigh
(
dev
,
addr
);
rt
->
rt6i_dev
=
dev
;
rt
->
rt6i_idev
=
i
n6_dev_get
(
dev
)
;
rt
->
rt6i_idev
=
i
dev
;
rt
->
rt6i_nexthop
=
neigh
;
atomic_set
(
&
rt
->
u
.
dst
.
__refcnt
,
1
);
rt
->
u
.
dst
.
metrics
[
RTAX_HOPLIMIT
-
1
]
=
255
;
...
...
@@ -731,8 +753,9 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
int
err
;
struct
rtmsg
*
r
;
struct
rtattr
**
rta
;
struct
rt6_info
*
rt
;
struct
rt6_info
*
rt
=
NULL
;
struct
net_device
*
dev
=
NULL
;
struct
inet6_dev
*
idev
=
NULL
;
int
addr_type
;
rta
=
(
struct
rtattr
**
)
_rtattr
;
...
...
@@ -744,9 +767,13 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
return
-
EINVAL
;
#endif
if
(
rtmsg
->
rtmsg_ifindex
)
{
err
=
-
ENODEV
;
dev
=
dev_get_by_index
(
rtmsg
->
rtmsg_ifindex
);
if
(
!
dev
)
return
-
ENODEV
;
goto
out
;
idev
=
in6_dev_get
(
dev
);
if
(
!
idev
)
goto
out
;
}
if
(
rtmsg
->
rtmsg_metric
==
0
)
...
...
@@ -793,10 +820,17 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
*/
if
((
rtmsg
->
rtmsg_flags
&
RTF_REJECT
)
||
(
dev
&&
(
dev
->
flags
&
IFF_LOOPBACK
)
&&
!
(
addr_type
&
IPV6_ADDR_LOOPBACK
)))
{
if
(
dev
)
if
(
dev
&&
dev
!=
&
loopback_dev
)
{
dev_put
(
dev
);
dev
=
&
loopback_dev
;
dev_hold
(
dev
);
in6_dev_put
(
idev
);
dev
=
&
loopback_dev
;
dev_hold
(
dev
);
idev
=
in6_dev_get
(
dev
);
if
(
!
idev
)
{
err
=
-
ENODEV
;
goto
out
;
}
}
rt
->
u
.
dst
.
output
=
ip6_pkt_discard_out
;
rt
->
u
.
dst
.
input
=
ip6_pkt_discard
;
rt
->
u
.
dst
.
error
=
-
ENETUNREACH
;
...
...
@@ -838,7 +872,9 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
}
}
else
{
dev
=
grt
->
rt6i_dev
;
idev
=
grt
->
rt6i_idev
;
dev_hold
(
dev
);
in6_dev_hold
(
grt
->
rt6i_idev
);
}
if
(
!
(
grt
->
rt6i_flags
&
RTF_GATEWAY
))
err
=
0
;
...
...
@@ -900,8 +936,8 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
if
(
!
rt
->
u
.
dst
.
metrics
[
RTAX_ADVMSS
-
1
])
rt
->
u
.
dst
.
metrics
[
RTAX_ADVMSS
-
1
]
=
ipv6_advmss
(
dst_pmtu
(
&
rt
->
u
.
dst
));
rt
->
u
.
dst
.
dev
=
dev
;
rt
->
rt6i_idev
=
i
n6_dev_get
(
dev
)
;
return
rt6_ins
(
rt
,
nlh
,
_rtattr
);
rt
->
rt6i_idev
=
i
dev
;
return
ip6_ins_rt
(
rt
,
nlh
,
_rtattr
);
out:
if
(
dev
)
...
...
@@ -1054,7 +1090,7 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *saddr,
nrt
->
u
.
dst
.
metrics
[
RTAX_MTU
-
1
]
=
ipv6_get_mtu
(
neigh
->
dev
);
nrt
->
u
.
dst
.
metrics
[
RTAX_ADVMSS
-
1
]
=
ipv6_advmss
(
dst_pmtu
(
&
nrt
->
u
.
dst
));
if
(
rt6_ins
(
nrt
,
NULL
,
NULL
))
if
(
ip6_ins_rt
(
nrt
,
NULL
,
NULL
))
goto
out
;
if
(
rt
->
rt6i_flags
&
RTF_CACHE
)
{
...
...
@@ -1144,7 +1180,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
dst_set_expires
(
&
nrt
->
u
.
dst
,
ip6_rt_mtu_expires
);
nrt
->
rt6i_flags
|=
RTF_DYNAMIC
|
RTF_CACHE
|
RTF_EXPIRES
;
nrt
->
u
.
dst
.
metrics
[
RTAX_MTU
-
1
]
=
pmtu
;
rt6_ins
(
nrt
,
NULL
,
NULL
);
ip6_ins_rt
(
nrt
,
NULL
,
NULL
);
}
out:
...
...
@@ -1303,23 +1339,26 @@ int ip6_pkt_discard_out(struct sk_buff **pskb)
}
/*
* A
dd address
* A
llocate a dst for local (unicast / anycast) address.
*/
int
ip6_rt_addr_add
(
struct
in6_addr
*
addr
,
struct
net_device
*
dev
,
int
anycast
)
struct
rt6_info
*
addrconf_dst_alloc
(
struct
inet6_dev
*
idev
,
const
struct
in6_addr
*
addr
,
int
anycast
)
{
struct
rt6_info
*
rt
=
ip6_dst_alloc
();
if
(
rt
==
NULL
)
return
-
ENOMEM
;
return
ERR_PTR
(
-
ENOMEM
)
;
dev_hold
(
&
loopback_dev
);
in6_dev_hold
(
idev
);
rt
->
u
.
dst
.
flags
=
DST_HOST
;
rt
->
u
.
dst
.
input
=
ip6_input
;
rt
->
u
.
dst
.
output
=
ip6_output
;
rt
->
rt6i_dev
=
&
loopback_dev
;
rt
->
rt6i_idev
=
i
n6_dev_get
(
&
loopback_dev
)
;
rt
->
rt6i_idev
=
i
dev
;
rt
->
u
.
dst
.
metrics
[
RTAX_MTU
-
1
]
=
ipv6_get_mtu
(
rt
->
rt6i_dev
);
rt
->
u
.
dst
.
metrics
[
RTAX_ADVMSS
-
1
]
=
ipv6_advmss
(
dst_pmtu
(
&
rt
->
u
.
dst
));
rt
->
u
.
dst
.
metrics
[
RTAX_HOPLIMIT
-
1
]
=
ipv6_get_hoplimit
(
rt
->
rt6i_dev
);
...
...
@@ -1331,34 +1370,15 @@ int ip6_rt_addr_add(struct in6_addr *addr, struct net_device *dev, int anycast)
rt
->
rt6i_nexthop
=
ndisc_get_neigh
(
rt
->
rt6i_dev
,
&
rt
->
rt6i_gateway
);
if
(
rt
->
rt6i_nexthop
==
NULL
)
{
dst_free
((
struct
dst_entry
*
)
rt
);
return
-
ENOMEM
;
return
ERR_PTR
(
-
ENOMEM
)
;
}
ipv6_addr_copy
(
&
rt
->
rt6i_dst
.
addr
,
addr
);
rt
->
rt6i_dst
.
plen
=
128
;
rt6_ins
(
rt
,
NULL
,
NULL
);
return
0
;
}
/* Delete address. Warning: you should check that this address
disappeared before calling this function.
*/
int
ip6_rt_addr_del
(
struct
in6_addr
*
addr
,
struct
net_device
*
dev
)
{
struct
rt6_info
*
rt
;
int
err
=
-
ENOENT
;
rt
=
rt6_lookup
(
addr
,
NULL
,
loopback_dev
.
ifindex
,
1
);
if
(
rt
)
{
if
(
rt
->
rt6i_dst
.
plen
==
128
)
err
=
ip6_del_rt
(
rt
,
NULL
,
NULL
);
else
dst_release
(
&
rt
->
u
.
dst
);
}
atomic_set
(
&
rt
->
u
.
dst
.
__refcnt
,
1
);
return
err
;
return
rt
;
}
static
int
fib6_ifdown
(
struct
rt6_info
*
rt
,
void
*
arg
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment