|
@@ -1407,7 +1407,7 @@ try_nextdev:
|
|
EXPORT_SYMBOL(ipv6_dev_get_saddr);
|
|
EXPORT_SYMBOL(ipv6_dev_get_saddr);
|
|
|
|
|
|
int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
|
|
int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
|
|
- unsigned char banned_flags)
|
|
|
|
|
|
+ u32 banned_flags)
|
|
{
|
|
{
|
|
struct inet6_ifaddr *ifp;
|
|
struct inet6_ifaddr *ifp;
|
|
int err = -EADDRNOTAVAIL;
|
|
int err = -EADDRNOTAVAIL;
|
|
@@ -1424,7 +1424,7 @@ int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
|
|
}
|
|
}
|
|
|
|
|
|
int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
|
|
int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
|
|
- unsigned char banned_flags)
|
|
|
|
|
|
+ u32 banned_flags)
|
|
{
|
|
{
|
|
struct inet6_dev *idev;
|
|
struct inet6_dev *idev;
|
|
int err = -EADDRNOTAVAIL;
|
|
int err = -EADDRNOTAVAIL;
|
|
@@ -2178,7 +2178,7 @@ ok:
|
|
}
|
|
}
|
|
|
|
|
|
if (ifp) {
|
|
if (ifp) {
|
|
- int flags;
|
|
|
|
|
|
+ u32 flags;
|
|
unsigned long now;
|
|
unsigned long now;
|
|
struct inet6_ifaddr *ift;
|
|
struct inet6_ifaddr *ift;
|
|
u32 stored_lft;
|
|
u32 stored_lft;
|
|
@@ -2363,10 +2363,11 @@ err_exit:
|
|
/*
|
|
/*
|
|
* Manual configuration of address on an interface
|
|
* Manual configuration of address on an interface
|
|
*/
|
|
*/
|
|
-static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *pfx,
|
|
|
|
|
|
+static int inet6_addr_add(struct net *net, int ifindex,
|
|
|
|
+ const struct in6_addr *pfx,
|
|
const struct in6_addr *peer_pfx,
|
|
const struct in6_addr *peer_pfx,
|
|
- unsigned int plen, __u8 ifa_flags, __u32 prefered_lft,
|
|
|
|
- __u32 valid_lft)
|
|
|
|
|
|
+ unsigned int plen, __u32 ifa_flags,
|
|
|
|
+ __u32 prefered_lft, __u32 valid_lft)
|
|
{
|
|
{
|
|
struct inet6_ifaddr *ifp;
|
|
struct inet6_ifaddr *ifp;
|
|
struct inet6_dev *idev;
|
|
struct inet6_dev *idev;
|
|
@@ -3351,7 +3352,7 @@ static void if6_seq_stop(struct seq_file *seq, void *v)
|
|
static int if6_seq_show(struct seq_file *seq, void *v)
|
|
static int if6_seq_show(struct seq_file *seq, void *v)
|
|
{
|
|
{
|
|
struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
|
|
struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
|
|
- seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
|
|
|
|
|
|
+ seq_printf(seq, "%pi6 %02x %02x %02x %03x %8s\n",
|
|
&ifp->addr,
|
|
&ifp->addr,
|
|
ifp->idev->dev->ifindex,
|
|
ifp->idev->dev->ifindex,
|
|
ifp->prefix_len,
|
|
ifp->prefix_len,
|
|
@@ -3572,6 +3573,7 @@ static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
|
|
[IFA_ADDRESS] = { .len = sizeof(struct in6_addr) },
|
|
[IFA_ADDRESS] = { .len = sizeof(struct in6_addr) },
|
|
[IFA_LOCAL] = { .len = sizeof(struct in6_addr) },
|
|
[IFA_LOCAL] = { .len = sizeof(struct in6_addr) },
|
|
[IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
|
|
[IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
|
|
|
|
+ [IFA_FLAGS] = { .len = sizeof(u32) },
|
|
};
|
|
};
|
|
|
|
|
|
static int
|
|
static int
|
|
@@ -3595,7 +3597,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|
return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen);
|
|
return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen);
|
|
}
|
|
}
|
|
|
|
|
|
-static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags,
|
|
|
|
|
|
+static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,
|
|
u32 prefered_lft, u32 valid_lft)
|
|
u32 prefered_lft, u32 valid_lft)
|
|
{
|
|
{
|
|
u32 flags;
|
|
u32 flags;
|
|
@@ -3650,7 +3652,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|
struct inet6_ifaddr *ifa;
|
|
struct inet6_ifaddr *ifa;
|
|
struct net_device *dev;
|
|
struct net_device *dev;
|
|
u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME;
|
|
u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME;
|
|
- u8 ifa_flags;
|
|
|
|
|
|
+ u32 ifa_flags;
|
|
int err;
|
|
int err;
|
|
|
|
|
|
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
|
|
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
|
|
@@ -3677,8 +3679,10 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|
if (dev == NULL)
|
|
if (dev == NULL)
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
+ ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifm->ifa_flags;
|
|
|
|
+
|
|
/* We ignore other flags so far. */
|
|
/* We ignore other flags so far. */
|
|
- ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS);
|
|
|
|
|
|
+ ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS;
|
|
|
|
|
|
ifa = ipv6_get_ifaddr(net, pfx, dev, 1);
|
|
ifa = ipv6_get_ifaddr(net, pfx, dev, 1);
|
|
if (ifa == NULL) {
|
|
if (ifa == NULL) {
|
|
@@ -3702,7 +3706,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
-static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u8 flags,
|
|
|
|
|
|
+static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u32 flags,
|
|
u8 scope, int ifindex)
|
|
u8 scope, int ifindex)
|
|
{
|
|
{
|
|
struct ifaddrmsg *ifm;
|
|
struct ifaddrmsg *ifm;
|
|
@@ -3745,7 +3749,8 @@ static inline int inet6_ifaddr_msgsize(void)
|
|
return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
|
|
return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
|
|
+ nla_total_size(16) /* IFA_LOCAL */
|
|
+ nla_total_size(16) /* IFA_LOCAL */
|
|
+ nla_total_size(16) /* IFA_ADDRESS */
|
|
+ nla_total_size(16) /* IFA_ADDRESS */
|
|
- + nla_total_size(sizeof(struct ifa_cacheinfo));
|
|
|
|
|
|
+ + nla_total_size(sizeof(struct ifa_cacheinfo))
|
|
|
|
+ + nla_total_size(4) /* IFA_FLAGS */;
|
|
}
|
|
}
|
|
|
|
|
|
static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
|
|
static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
|
|
@@ -3793,6 +3798,9 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
|
|
if (put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0)
|
|
if (put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0)
|
|
goto error;
|
|
goto error;
|
|
|
|
|
|
|
|
+ if (nla_put_u32(skb, IFA_FLAGS, ifa->flags) < 0)
|
|
|
|
+ goto error;
|
|
|
|
+
|
|
return nlmsg_end(skb, nlh);
|
|
return nlmsg_end(skb, nlh);
|
|
|
|
|
|
error:
|
|
error:
|