aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv6/addrconf.c77
1 files changed, 43 insertions, 34 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index d546f0e74530..ca7ecf2f3e82 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3000,6 +3000,19 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
3000 preferred_lft, valid_lft); 3000 preferred_lft, valid_lft);
3001} 3001}
3002 3002
3003static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u8 flags,
3004 u8 scope, int ifindex)
3005{
3006 struct ifaddrmsg *ifm;
3007
3008 ifm = nlmsg_data(nlh);
3009 ifm->ifa_family = AF_INET6;
3010 ifm->ifa_prefixlen = prefixlen;
3011 ifm->ifa_flags = flags;
3012 ifm->ifa_scope = scope;
3013 ifm->ifa_index = ifindex;
3014}
3015
3003static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp, 3016static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp,
3004 unsigned long tstamp, u32 preferred, u32 valid) 3017 unsigned long tstamp, u32 preferred, u32 valid)
3005{ 3018{
@@ -3015,6 +3028,18 @@ static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp,
3015 return nla_put(skb, IFA_CACHEINFO, sizeof(ci), &ci); 3028 return nla_put(skb, IFA_CACHEINFO, sizeof(ci), &ci);
3016} 3029}
3017 3030
3031static inline int rt_scope(int ifa_scope)
3032{
3033 if (ifa_scope & IFA_HOST)
3034 return RT_SCOPE_HOST;
3035 else if (ifa_scope & IFA_LINK)
3036 return RT_SCOPE_LINK;
3037 else if (ifa_scope & IFA_SITE)
3038 return RT_SCOPE_SITE;
3039 else
3040 return RT_SCOPE_UNIVERSE;
3041}
3042
3018/* Maximum length of ifa_cacheinfo attributes */ 3043/* Maximum length of ifa_cacheinfo attributes */
3019#define INET6_IFADDR_RTA_SPACE \ 3044#define INET6_IFADDR_RTA_SPACE \
3020 RTA_SPACE(16) /* IFA_ADDRESS */ + \ 3045 RTA_SPACE(16) /* IFA_ADDRESS */ + \
@@ -3023,24 +3048,14 @@ static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp,
3023static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, 3048static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3024 u32 pid, u32 seq, int event, unsigned int flags) 3049 u32 pid, u32 seq, int event, unsigned int flags)
3025{ 3050{
3026 struct ifaddrmsg *ifm;
3027 struct nlmsghdr *nlh; 3051 struct nlmsghdr *nlh;
3028 unsigned char *b = skb->tail; 3052 unsigned char *b = skb->tail;
3029 u32 preferred, valid; 3053 u32 preferred, valid;
3030 3054
3031 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags); 3055 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3032 ifm = NLMSG_DATA(nlh); 3056 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
3033 ifm->ifa_family = AF_INET6; 3057 ifa->idev->dev->ifindex);
3034 ifm->ifa_prefixlen = ifa->prefix_len; 3058
3035 ifm->ifa_flags = ifa->flags;
3036 ifm->ifa_scope = RT_SCOPE_UNIVERSE;
3037 if (ifa->scope&IFA_HOST)
3038 ifm->ifa_scope = RT_SCOPE_HOST;
3039 else if (ifa->scope&IFA_LINK)
3040 ifm->ifa_scope = RT_SCOPE_LINK;
3041 else if (ifa->scope&IFA_SITE)
3042 ifm->ifa_scope = RT_SCOPE_SITE;
3043 ifm->ifa_index = ifa->idev->dev->ifindex;
3044 RTA_PUT(skb, IFA_ADDRESS, 16, &ifa->addr); 3059 RTA_PUT(skb, IFA_ADDRESS, 16, &ifa->addr);
3045 if (!(ifa->flags&IFA_F_PERMANENT)) { 3060 if (!(ifa->flags&IFA_F_PERMANENT)) {
3046 preferred = ifa->prefered_lft; 3061 preferred = ifa->prefered_lft;
@@ -3071,19 +3086,16 @@ rtattr_failure:
3071static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, 3086static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
3072 u32 pid, u32 seq, int event, u16 flags) 3087 u32 pid, u32 seq, int event, u16 flags)
3073{ 3088{
3074 struct ifaddrmsg *ifm;
3075 struct nlmsghdr *nlh; 3089 struct nlmsghdr *nlh;
3076 unsigned char *b = skb->tail; 3090 unsigned char *b = skb->tail;
3091 u8 scope = RT_SCOPE_UNIVERSE;
3092 int ifindex = ifmca->idev->dev->ifindex;
3093
3094 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
3095 scope = RT_SCOPE_SITE;
3077 3096
3078 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags); 3097 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3079 ifm = NLMSG_DATA(nlh); 3098 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
3080 ifm->ifa_family = AF_INET6;
3081 ifm->ifa_prefixlen = 128;
3082 ifm->ifa_flags = IFA_F_PERMANENT;
3083 ifm->ifa_scope = RT_SCOPE_UNIVERSE;
3084 if (ipv6_addr_scope(&ifmca->mca_addr)&IFA_SITE)
3085 ifm->ifa_scope = RT_SCOPE_SITE;
3086 ifm->ifa_index = ifmca->idev->dev->ifindex;
3087 RTA_PUT(skb, IFA_MULTICAST, 16, &ifmca->mca_addr); 3099 RTA_PUT(skb, IFA_MULTICAST, 16, &ifmca->mca_addr);
3088 3100
3089 if (put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp, 3101 if (put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp,
@@ -3102,19 +3114,16 @@ rtattr_failure:
3102static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, 3114static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
3103 u32 pid, u32 seq, int event, unsigned int flags) 3115 u32 pid, u32 seq, int event, unsigned int flags)
3104{ 3116{
3105 struct ifaddrmsg *ifm;
3106 struct nlmsghdr *nlh; 3117 struct nlmsghdr *nlh;
3107 unsigned char *b = skb->tail; 3118 unsigned char *b = skb->tail;
3119 u8 scope = RT_SCOPE_UNIVERSE;
3120 int ifindex = ifaca->aca_idev->dev->ifindex;
3121
3122 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
3123 scope = RT_SCOPE_SITE;
3108 3124
3109 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags); 3125 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3110 ifm = NLMSG_DATA(nlh); 3126 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
3111 ifm->ifa_family = AF_INET6;
3112 ifm->ifa_prefixlen = 128;
3113 ifm->ifa_flags = IFA_F_PERMANENT;
3114 ifm->ifa_scope = RT_SCOPE_UNIVERSE;
3115 if (ipv6_addr_scope(&ifaca->aca_addr)&IFA_SITE)
3116 ifm->ifa_scope = RT_SCOPE_SITE;
3117 ifm->ifa_index = ifaca->aca_idev->dev->ifindex;
3118 RTA_PUT(skb, IFA_ANYCAST, 16, &ifaca->aca_addr); 3127 RTA_PUT(skb, IFA_ANYCAST, 16, &ifaca->aca_addr);
3119 3128
3120 if (put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp, 3129 if (put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp,