Commit 479840ffdbe4242e8a25349218c8e0859223aa35
Committed by
David S. Miller
1 parent
e6247027e5
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
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: Jiri Pirko <jiri@resnulli.us> Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 4 changed files with 27 additions and 15 deletions Side-by-side Diff
include/net/addrconf.h
... | ... | @@ -81,9 +81,9 @@ |
81 | 81 | const struct in6_addr *daddr, unsigned int srcprefs, |
82 | 82 | struct in6_addr *saddr); |
83 | 83 | int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr, |
84 | - unsigned char banned_flags); | |
84 | + u32 banned_flags); | |
85 | 85 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, |
86 | - unsigned char banned_flags); | |
86 | + u32 banned_flags); | |
87 | 87 | int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); |
88 | 88 | void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr); |
89 | 89 | void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr); |
include/net/if_inet6.h
include/uapi/linux/if_addr.h
... | ... | @@ -18,6 +18,9 @@ |
18 | 18 | * It makes no difference for normally configured broadcast interfaces, |
19 | 19 | * but for point-to-point IFA_ADDRESS is DESTINATION address, |
20 | 20 | * local address is supplied in IFA_LOCAL attribute. |
21 | + * | |
22 | + * IFA_FLAGS is a u32 attribute that extends the u8 field ifa_flags. | |
23 | + * If present, the value from struct ifaddrmsg will be ignored. | |
21 | 24 | */ |
22 | 25 | enum { |
23 | 26 | IFA_UNSPEC, |
... | ... | @@ -28,6 +31,7 @@ |
28 | 31 | IFA_ANYCAST, |
29 | 32 | IFA_CACHEINFO, |
30 | 33 | IFA_MULTICAST, |
34 | + IFA_FLAGS, | |
31 | 35 | __IFA_MAX, |
32 | 36 | }; |
33 | 37 |
net/ipv6/addrconf.c
... | ... | @@ -1407,7 +1407,7 @@ |
1407 | 1407 | EXPORT_SYMBOL(ipv6_dev_get_saddr); |
1408 | 1408 | |
1409 | 1409 | int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr, |
1410 | - unsigned char banned_flags) | |
1410 | + u32 banned_flags) | |
1411 | 1411 | { |
1412 | 1412 | struct inet6_ifaddr *ifp; |
1413 | 1413 | int err = -EADDRNOTAVAIL; |
... | ... | @@ -1424,7 +1424,7 @@ |
1424 | 1424 | } |
1425 | 1425 | |
1426 | 1426 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, |
1427 | - unsigned char banned_flags) | |
1427 | + u32 banned_flags) | |
1428 | 1428 | { |
1429 | 1429 | struct inet6_dev *idev; |
1430 | 1430 | int err = -EADDRNOTAVAIL; |
... | ... | @@ -2178,7 +2178,7 @@ |
2178 | 2178 | } |
2179 | 2179 | |
2180 | 2180 | if (ifp) { |
2181 | - int flags; | |
2181 | + u32 flags; | |
2182 | 2182 | unsigned long now; |
2183 | 2183 | struct inet6_ifaddr *ift; |
2184 | 2184 | u32 stored_lft; |
2185 | 2185 | |
... | ... | @@ -2363,10 +2363,11 @@ |
2363 | 2363 | /* |
2364 | 2364 | * Manual configuration of address on an interface |
2365 | 2365 | */ |
2366 | -static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *pfx, | |
2366 | +static int inet6_addr_add(struct net *net, int ifindex, | |
2367 | + const struct in6_addr *pfx, | |
2367 | 2368 | const struct in6_addr *peer_pfx, |
2368 | - unsigned int plen, __u8 ifa_flags, __u32 prefered_lft, | |
2369 | - __u32 valid_lft) | |
2369 | + unsigned int plen, __u32 ifa_flags, | |
2370 | + __u32 prefered_lft, __u32 valid_lft) | |
2370 | 2371 | { |
2371 | 2372 | struct inet6_ifaddr *ifp; |
2372 | 2373 | struct inet6_dev *idev; |
... | ... | @@ -3351,7 +3352,7 @@ |
3351 | 3352 | static int if6_seq_show(struct seq_file *seq, void *v) |
3352 | 3353 | { |
3353 | 3354 | struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v; |
3354 | - seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n", | |
3355 | + seq_printf(seq, "%pi6 %02x %02x %02x %03x %8s\n", | |
3355 | 3356 | &ifp->addr, |
3356 | 3357 | ifp->idev->dev->ifindex, |
3357 | 3358 | ifp->prefix_len, |
... | ... | @@ -3572,6 +3573,7 @@ |
3572 | 3573 | [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, |
3573 | 3574 | [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, |
3574 | 3575 | [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, |
3576 | + [IFA_FLAGS] = { .len = sizeof(u32) }, | |
3575 | 3577 | }; |
3576 | 3578 | |
3577 | 3579 | static int |
... | ... | @@ -3595,7 +3597,7 @@ |
3595 | 3597 | return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen); |
3596 | 3598 | } |
3597 | 3599 | |
3598 | -static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | |
3600 | +static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags, | |
3599 | 3601 | u32 prefered_lft, u32 valid_lft) |
3600 | 3602 | { |
3601 | 3603 | u32 flags; |
... | ... | @@ -3650,7 +3652,7 @@ |
3650 | 3652 | struct inet6_ifaddr *ifa; |
3651 | 3653 | struct net_device *dev; |
3652 | 3654 | u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME; |
3653 | - u8 ifa_flags; | |
3655 | + u32 ifa_flags; | |
3654 | 3656 | int err; |
3655 | 3657 | |
3656 | 3658 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3657 | 3659 | |
... | ... | @@ -3677,8 +3679,10 @@ |
3677 | 3679 | if (dev == NULL) |
3678 | 3680 | return -ENODEV; |
3679 | 3681 | |
3682 | + ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifm->ifa_flags; | |
3683 | + | |
3680 | 3684 | /* We ignore other flags so far. */ |
3681 | - ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS); | |
3685 | + ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS; | |
3682 | 3686 | |
3683 | 3687 | ifa = ipv6_get_ifaddr(net, pfx, dev, 1); |
3684 | 3688 | if (ifa == NULL) { |
... | ... | @@ -3702,7 +3706,7 @@ |
3702 | 3706 | return err; |
3703 | 3707 | } |
3704 | 3708 | |
3705 | -static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u8 flags, | |
3709 | +static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u32 flags, | |
3706 | 3710 | u8 scope, int ifindex) |
3707 | 3711 | { |
3708 | 3712 | struct ifaddrmsg *ifm; |
... | ... | @@ -3745,7 +3749,8 @@ |
3745 | 3749 | return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) |
3746 | 3750 | + nla_total_size(16) /* IFA_LOCAL */ |
3747 | 3751 | + nla_total_size(16) /* IFA_ADDRESS */ |
3748 | - + nla_total_size(sizeof(struct ifa_cacheinfo)); | |
3752 | + + nla_total_size(sizeof(struct ifa_cacheinfo)) | |
3753 | + + nla_total_size(4) /* IFA_FLAGS */; | |
3749 | 3754 | } |
3750 | 3755 | |
3751 | 3756 | static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, |
... | ... | @@ -3791,6 +3796,9 @@ |
3791 | 3796 | goto error; |
3792 | 3797 | |
3793 | 3798 | if (put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) |
3799 | + goto error; | |
3800 | + | |
3801 | + if (nla_put_u32(skb, IFA_FLAGS, ifa->flags) < 0) | |
3794 | 3802 | goto error; |
3795 | 3803 | |
3796 | 3804 | return nlmsg_end(skb, nlh); |