aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2006-09-18 03:12:35 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 18:19:00 -0400
commit0ab6803bc90a8ee5c860ef09334b30007d1746be (patch)
tree934a0d108a9137337defadc2a396a199fda32610 /net/ipv6/addrconf.c
parent101bb229691c438bce4d7f13006494dd4de6910a (diff)
[IPV6] address: Convert address dumping to new netlink api
Replaces INET6_IFADDR_RTA_SPACE with a new function calculating the total required message size for all address messages. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c79
1 files changed, 33 insertions, 46 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index ca7ecf2f3e82..75a69bac82a8 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3040,23 +3040,27 @@ static inline int rt_scope(int ifa_scope)
3040 return RT_SCOPE_UNIVERSE; 3040 return RT_SCOPE_UNIVERSE;
3041} 3041}
3042 3042
3043/* Maximum length of ifa_cacheinfo attributes */ 3043static inline int inet6_ifaddr_msgsize(void)
3044#define INET6_IFADDR_RTA_SPACE \ 3044{
3045 RTA_SPACE(16) /* IFA_ADDRESS */ + \ 3045 return nlmsg_total_size(sizeof(struct ifaddrmsg) +
3046 RTA_SPACE(sizeof(struct ifa_cacheinfo)) /* CACHEINFO */ 3046 nla_total_size(16) +
3047 nla_total_size(sizeof(struct ifa_cacheinfo)) +
3048 128);
3049}
3047 3050
3048static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, 3051static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3049 u32 pid, u32 seq, int event, unsigned int flags) 3052 u32 pid, u32 seq, int event, unsigned int flags)
3050{ 3053{
3051 struct nlmsghdr *nlh; 3054 struct nlmsghdr *nlh;
3052 unsigned char *b = skb->tail;
3053 u32 preferred, valid; 3055 u32 preferred, valid;
3054 3056
3055 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3057 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3058 if (nlh == NULL)
3059 return -ENOBUFS;
3060
3056 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope), 3061 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
3057 ifa->idev->dev->ifindex); 3062 ifa->idev->dev->ifindex);
3058 3063
3059 RTA_PUT(skb, IFA_ADDRESS, 16, &ifa->addr);
3060 if (!(ifa->flags&IFA_F_PERMANENT)) { 3064 if (!(ifa->flags&IFA_F_PERMANENT)) {
3061 preferred = ifa->prefered_lft; 3065 preferred = ifa->prefered_lft;
3062 valid = ifa->valid_lft; 3066 valid = ifa->valid_lft;
@@ -3071,72 +3075,57 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3071 valid = INFINITY_LIFE_TIME; 3075 valid = INFINITY_LIFE_TIME;
3072 } 3076 }
3073 3077
3074 if (put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) 3078 if (nla_put(skb, IFA_ADDRESS, 16, &ifa->addr) < 0 ||
3075 goto rtattr_failure; 3079 put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0)
3080 return nlmsg_cancel(skb, nlh);
3076 3081
3077 nlh->nlmsg_len = skb->tail - b; 3082 return nlmsg_end(skb, nlh);
3078 return skb->len;
3079
3080nlmsg_failure:
3081rtattr_failure:
3082 skb_trim(skb, b - skb->data);
3083 return -1;
3084} 3083}
3085 3084
3086static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, 3085static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
3087 u32 pid, u32 seq, int event, u16 flags) 3086 u32 pid, u32 seq, int event, u16 flags)
3088{ 3087{
3089 struct nlmsghdr *nlh; 3088 struct nlmsghdr *nlh;
3090 unsigned char *b = skb->tail;
3091 u8 scope = RT_SCOPE_UNIVERSE; 3089 u8 scope = RT_SCOPE_UNIVERSE;
3092 int ifindex = ifmca->idev->dev->ifindex; 3090 int ifindex = ifmca->idev->dev->ifindex;
3093 3091
3094 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE) 3092 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
3095 scope = RT_SCOPE_SITE; 3093 scope = RT_SCOPE_SITE;
3096 3094
3097 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3095 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3098 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex); 3096 if (nlh == NULL)
3099 RTA_PUT(skb, IFA_MULTICAST, 16, &ifmca->mca_addr); 3097 return -ENOBUFS;
3100 3098
3101 if (put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp, 3099 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
3100 if (nla_put(skb, IFA_MULTICAST, 16, &ifmca->mca_addr) < 0 ||
3101 put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp,
3102 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) 3102 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0)
3103 goto rtattr_failure; 3103 return nlmsg_cancel(skb, nlh);
3104 3104
3105 nlh->nlmsg_len = skb->tail - b; 3105 return nlmsg_end(skb, nlh);
3106 return skb->len;
3107
3108nlmsg_failure:
3109rtattr_failure:
3110 skb_trim(skb, b - skb->data);
3111 return -1;
3112} 3106}
3113 3107
3114static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, 3108static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
3115 u32 pid, u32 seq, int event, unsigned int flags) 3109 u32 pid, u32 seq, int event, unsigned int flags)
3116{ 3110{
3117 struct nlmsghdr *nlh; 3111 struct nlmsghdr *nlh;
3118 unsigned char *b = skb->tail;
3119 u8 scope = RT_SCOPE_UNIVERSE; 3112 u8 scope = RT_SCOPE_UNIVERSE;
3120 int ifindex = ifaca->aca_idev->dev->ifindex; 3113 int ifindex = ifaca->aca_idev->dev->ifindex;
3121 3114
3122 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE) 3115 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
3123 scope = RT_SCOPE_SITE; 3116 scope = RT_SCOPE_SITE;
3124 3117
3125 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3118 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3126 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex); 3119 if (nlh == NULL)
3127 RTA_PUT(skb, IFA_ANYCAST, 16, &ifaca->aca_addr); 3120 return -ENOBUFS;
3128 3121
3129 if (put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp, 3122 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
3123 if (nla_put(skb, IFA_ANYCAST, 16, &ifaca->aca_addr) < 0 ||
3124 put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp,
3130 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) 3125 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0)
3131 goto rtattr_failure; 3126 return nlmsg_cancel(skb, nlh);
3132 3127
3133 nlh->nlmsg_len = skb->tail - b; 3128 return nlmsg_end(skb, nlh);
3134 return skb->len;
3135
3136nlmsg_failure:
3137rtattr_failure:
3138 skb_trim(skb, b - skb->data);
3139 return -1;
3140} 3129}
3141 3130
3142enum addr_type_t 3131enum addr_type_t
@@ -3256,7 +3245,6 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
3256 struct net_device *dev = NULL; 3245 struct net_device *dev = NULL;
3257 struct inet6_ifaddr *ifa; 3246 struct inet6_ifaddr *ifa;
3258 struct sk_buff *skb; 3247 struct sk_buff *skb;
3259 int payload = sizeof(struct ifaddrmsg) + INET6_IFADDR_RTA_SPACE;
3260 int err; 3248 int err;
3261 3249
3262 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 3250 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
@@ -3278,7 +3266,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
3278 goto errout; 3266 goto errout;
3279 } 3267 }
3280 3268
3281 if ((skb = nlmsg_new(nlmsg_total_size(payload), GFP_KERNEL)) == NULL) { 3269 if ((skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL)) == NULL) {
3282 err = -ENOBUFS; 3270 err = -ENOBUFS;
3283 goto errout_ifa; 3271 goto errout_ifa;
3284 } 3272 }
@@ -3300,10 +3288,9 @@ errout:
3300static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) 3288static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
3301{ 3289{
3302 struct sk_buff *skb; 3290 struct sk_buff *skb;
3303 int payload = sizeof(struct ifaddrmsg) + INET6_IFADDR_RTA_SPACE;
3304 int err = -ENOBUFS; 3291 int err = -ENOBUFS;
3305 3292
3306 skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC); 3293 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
3307 if (skb == NULL) 3294 if (skb == NULL)
3308 goto errout; 3295 goto errout;
3309 3296