nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        hdr = nlmsg_data(nlh);
        hdr->ifi_family = AF_BRIDGE;
        return nlmsg_end(skb, nlh);
 
 nla_put_failure:
-       return nlmsg_cancel(skb, nlh);
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 /*
                goto errout;
 
        err = br_fill_ifinfo(skb, port, 0, 0, event, 0);
-       /* failure implies BUG in br_nlmsg_size() */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in br_nlmsg_size() */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout;
+       }
        err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
 errout:
        if (err < 0)
 
 
        nlh = nlmsg_put(skb, pid, seq, type, sizeof(*frh), flags);
        if (nlh == NULL)
-               return -1;
+               return -EMSGSIZE;
 
        frh = nlmsg_data(nlh);
        frh->table = rule->table;
        return nlmsg_end(skb, nlh);
 
 nla_put_failure:
-       return nlmsg_cancel(skb, nlh);
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 int fib_rules_dump(struct sk_buff *skb, struct netlink_callback *cb, int family)
                goto errout;
 
        err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops);
-       /* failure implies BUG in fib_rule_nlmsg_size() */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in fib_rule_nlmsg_size() */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout;
+       }
        err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL);
 errout:
        if (err < 0)
 
 
        nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        ndtmsg = nlmsg_data(nlh);
 
 
 nla_put_failure:
        read_unlock_bh(&tbl->lock);
-       return nlmsg_cancel(skb, nlh);
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 static int neightbl_fill_param_info(struct sk_buff *skb,
 
        nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        ndtmsg = nlmsg_data(nlh);
 
        return nlmsg_end(skb, nlh);
 errout:
        read_unlock_bh(&tbl->lock);
-       return nlmsg_cancel(skb, nlh);
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
  
 static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
 
        nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        ndm = nlmsg_data(nlh);
        ndm->ndm_family  = neigh->ops->family;
        return nlmsg_end(skb, nlh);
 
 nla_put_failure:
-       return nlmsg_cancel(skb, nlh);
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 
                goto errout;
 
        err = neigh_fill_info(skb, n, 0, 0, type, flags);
-       /* failure implies BUG in neigh_nlmsg_size() */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in neigh_nlmsg_size() */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout;
+       }
        err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
 errout:
        if (err < 0)
 
 
        nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        ifm = nlmsg_data(nlh);
        ifm->ifi_family = AF_UNSPEC;
        return nlmsg_end(skb, nlh);
 
 nla_put_failure:
-       return nlmsg_cancel(skb, nlh);
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
 
        err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK,
                               NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0);
-       /* failure impilies BUG in if_nlmsg_size or wireless_rtnetlink_get */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in if_nlmsg_size */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(nskb);
+               goto errout;
+       }
        err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
 errout:
        kfree(iw_buf);
                goto errout;
 
        err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0);
-       /* failure implies BUG in if_nlmsg_size() */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in if_nlmsg_size() */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout;
+       }
        err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
 errout:
        if (err < 0)
 
 
        nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        ifm = nlmsg_data(nlh);
        ifm->ifa_family = AF_DECnet;
        return nlmsg_end(skb, nlh);
 
 nla_put_failure:
-       return nlmsg_cancel(skb, nlh);
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa)
                goto errout;
 
        err = dn_nl_fill_ifaddr(skb, ifa, 0, 0, event, 0);
-       /* failure implies BUG in dn_ifaddr_nlmsg_size() */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in dn_ifaddr_nlmsg_size() */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout;
+       }
        err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
 errout:
        if (err < 0)
 
 nlmsg_failure:
 rtattr_failure:
         skb_trim(skb, b - skb->data);
-        return -1;
+        return -EMSGSIZE;
 }
 
 
         err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id,
                               f->fn_type, f->fn_scope, &f->fn_key, z,
                               DN_FIB_INFO(f), 0);
-       /* failure implies BUG in dn_fib_nlmsg_size() */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in dn_fib_nlmsg_size() */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout;
+       }
        err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
 errout:
        if (err < 0)
 
 
        nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        ifm = nlmsg_data(nlh);
        ifm->ifa_family = AF_INET;
        return nlmsg_end(skb, nlh);
 
 nla_put_failure:
-       return nlmsg_cancel(skb, nlh);
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
                goto errout;
 
        err = inet_fill_ifaddr(skb, ifa, pid, seq, event, 0);
-       /* failure implies BUG in inet_nlmsg_size() */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in inet_nlmsg_size() */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout;
+       }
        err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
 errout:
        if (err < 0)
 
        err = fib_dump_info(skb, info->pid, seq, event, tb_id,
                            fa->fa_type, fa->fa_scope, key, dst_len,
                            fa->fa_tos, fa->fa_info, 0);
-       /* failure implies BUG in fib_nlmsg_size() */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in fib_nlmsg_size() */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout;
+       }
        err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE,
                          info->nlh, GFP_KERNEL);
 errout:
 
        nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        rtm = nlmsg_data(nlh);
        rtm->rtm_family = AF_INET;
        return nlmsg_end(skb, nlh);
 
 nla_put_failure:
-       return nlmsg_cancel(skb, nlh);
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 /*
 
 rtattr_failure:
 nlmsg_failure:
        skb_trim(skb, b - skb->data);
-       return -1;
+       return -EMSGSIZE;
 }
 
 static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
        return skb->len;
 nlmsg_failure:
        skb_trim(skb, previous_tail - skb->data);
-       return -1;
+       return -EMSGSIZE;
 }
 
 static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
        if (!rep)
                goto out;
 
-       if (sk_diag_fill(sk, rep, req->idiag_ext,
-                        NETLINK_CB(in_skb).pid,
-                        nlh->nlmsg_seq, 0, nlh) <= 0)
-               BUG();
-
+       err = sk_diag_fill(sk, rep, req->idiag_ext,
+                          NETLINK_CB(in_skb).pid,
+                          nlh->nlmsg_seq, 0, nlh);
+       if (err < 0) {
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(rep);
+               goto out;
+       }
        err = netlink_unicast(idiagnl, rep, NETLINK_CB(in_skb).pid,
                              MSG_DONTWAIT);
        if (err > 0)
 
 
        nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        r = nlmsg_data(nlh);
        r->rtm_family    = AF_INET;
        return nlmsg_end(skb, nlh);
 
 nla_put_failure:
-       return nlmsg_cancel(skb, nlh);
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
 
 
        nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
                      ifa->idev->dev->ifindex);
        }
 
        if (nla_put(skb, IFA_ADDRESS, 16, &ifa->addr) < 0 ||
-           put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0)
-               return nlmsg_cancel(skb, nlh);
+           put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) {
+               nlmsg_cancel(skb, nlh);
+               return -EMSGSIZE;
+       }
 
        return nlmsg_end(skb, nlh);
 }
 
        nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
        if (nla_put(skb, IFA_MULTICAST, 16, &ifmca->mca_addr) < 0 ||
            put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp,
-                         INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0)
-               return nlmsg_cancel(skb, nlh);
+                         INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
+               nlmsg_cancel(skb, nlh);
+               return -EMSGSIZE;
+       }
 
        return nlmsg_end(skb, nlh);
 }
 
        nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
        if (nla_put(skb, IFA_ANYCAST, 16, &ifaca->aca_addr) < 0 ||
            put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp,
-                         INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0)
-               return nlmsg_cancel(skb, nlh);
+                         INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
+               nlmsg_cancel(skb, nlh);
+               return -EMSGSIZE;
+       }
 
        return nlmsg_end(skb, nlh);
 }
 
        err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
                                nlh->nlmsg_seq, RTM_NEWADDR, 0);
-       /* failure implies BUG in inet6_ifaddr_msgsize() */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout_ifa;
+       }
        err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
 errout_ifa:
        in6_ifa_put(ifa);
                goto errout;
 
        err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0);
-       /* failure implies BUG in inet6_ifaddr_msgsize() */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout;
+       }
        err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
 errout:
        if (err < 0)
 
        nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        hdr = nlmsg_data(nlh);
        hdr->ifi_family = AF_INET6;
        return nlmsg_end(skb, nlh);
 
 nla_put_failure:
-       return nlmsg_cancel(skb, nlh);
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
                goto errout;
 
        err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0);
-       /* failure implies BUG in inet6_if_nlmsg_size() */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in inet6_if_nlmsg_size() */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout;
+       }
        err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
 errout:
        if (err < 0)
 
        nlh = nlmsg_put(skb, pid, seq, event, sizeof(*pmsg), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        pmsg = nlmsg_data(nlh);
        pmsg->prefix_family = AF_INET6;
        return nlmsg_end(skb, nlh);
 
 nla_put_failure:
-       return nlmsg_cancel(skb, nlh);
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 static void inet6_prefix_notify(int event, struct inet6_dev *idev, 
                goto errout;
 
        err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0);
-       /* failure implies BUG in inet6_prefix_nlmsg_size() */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in inet6_prefix_nlmsg_size() */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout;
+       }
        err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
 errout:
        if (err < 0)
 
 
        nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags);
        if (nlh == NULL)
-               return -ENOBUFS;
+               return -EMSGSIZE;
 
        rtm = nlmsg_data(nlh);
        rtm->rtm_family = AF_INET6;
        return nlmsg_end(skb, nlh);
 
 nla_put_failure:
-       return nlmsg_cancel(skb, nlh);
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 int rt6_dump_route(struct rt6_info *rt, void *p_arg)
                goto errout;
 
        err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0);
-       /* failure implies BUG in rt6_nlmsg_size() */
-       BUG_ON(err < 0);
-
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout;
+       }
        err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
 errout:
        if (err < 0)