Commit 479840ff authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

ipv6 addrconf: extend ifa_flags to u32

There is no more space in u8 ifa_flags. So do what davem suffested and
add another netlink attr called IFA_FLAGS for carry more flags.
Signed-off-by: default avatarJiri Pirko <jiri@resnulli.us>
Signed-off-by: default avatarThomas Haller <thaller@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e6247027
...@@ -81,9 +81,9 @@ int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev, ...@@ -81,9 +81,9 @@ int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
const struct in6_addr *daddr, unsigned int srcprefs, const struct in6_addr *daddr, unsigned int srcprefs,
struct in6_addr *saddr); struct in6_addr *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);
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);
int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2);
void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr); void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr);
void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr); void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr);
......
...@@ -50,8 +50,8 @@ struct inet6_ifaddr { ...@@ -50,8 +50,8 @@ struct inet6_ifaddr {
int state; int state;
__u32 flags;
__u8 dad_probes; __u8 dad_probes;
__u8 flags;
__u16 scope; __u16 scope;
......
...@@ -18,6 +18,9 @@ struct ifaddrmsg { ...@@ -18,6 +18,9 @@ struct ifaddrmsg {
* It makes no difference for normally configured broadcast interfaces, * It makes no difference for normally configured broadcast interfaces,
* but for point-to-point IFA_ADDRESS is DESTINATION address, * but for point-to-point IFA_ADDRESS is DESTINATION address,
* local address is supplied in IFA_LOCAL attribute. * local address is supplied in IFA_LOCAL attribute.
*
* IFA_FLAGS is a u32 attribute that extends the u8 field ifa_flags.
* If present, the value from struct ifaddrmsg will be ignored.
*/ */
enum { enum {
IFA_UNSPEC, IFA_UNSPEC,
...@@ -28,6 +31,7 @@ enum { ...@@ -28,6 +31,7 @@ enum {
IFA_ANYCAST, IFA_ANYCAST,
IFA_CACHEINFO, IFA_CACHEINFO,
IFA_MULTICAST, IFA_MULTICAST,
IFA_FLAGS,
__IFA_MAX, __IFA_MAX,
}; };
......
...@@ -1407,7 +1407,7 @@ int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev, ...@@ -1407,7 +1407,7 @@ int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
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, ...@@ -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 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) ...@@ -2178,7 +2178,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
} }
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 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg) ...@@ -2363,10 +2363,11 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg)
/* /*
* 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, unsigned int plen, __u32 ifa_flags,
__u32 valid_lft) __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) ...@@ -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] = { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment