diff options
author | Thomas Graf <tgraf@suug.ch> | 2006-09-18 03:12:35 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 18:19:00 -0400 |
commit | 0ab6803bc90a8ee5c860ef09334b30007d1746be (patch) | |
tree | 934a0d108a9137337defadc2a396a199fda32610 /net/ipv6/addrconf.c | |
parent | 101bb229691c438bce4d7f13006494dd4de6910a (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.c | 79 |
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 */ | 3043 | static 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 | ||
3048 | static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, | 3051 | static 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 | |||
3080 | nlmsg_failure: | ||
3081 | rtattr_failure: | ||
3082 | skb_trim(skb, b - skb->data); | ||
3083 | return -1; | ||
3084 | } | 3083 | } |
3085 | 3084 | ||
3086 | static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, | 3085 | static 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 | |||
3108 | nlmsg_failure: | ||
3109 | rtattr_failure: | ||
3110 | skb_trim(skb, b - skb->data); | ||
3111 | return -1; | ||
3112 | } | 3106 | } |
3113 | 3107 | ||
3114 | static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, | 3108 | static 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 | |||
3136 | nlmsg_failure: | ||
3137 | rtattr_failure: | ||
3138 | skb_trim(skb, b - skb->data); | ||
3139 | return -1; | ||
3140 | } | 3129 | } |
3141 | 3130 | ||
3142 | enum addr_type_t | 3131 | enum 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: | |||
3300 | static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) | 3288 | static 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 | ||