Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
[powerpc.git] / net / netfilter / nfnetlink.c
index 1caaca0..83f4c53 100644 (file)
@@ -128,18 +128,16 @@ void __nfa_fill(struct sk_buff *skb, int attrtype, int attrlen,
        memset(NFA_DATA(nfa) + attrlen, 0, NFA_ALIGN(size) - size);
 }
 
-int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
+void nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
 {
        memset(tb, 0, sizeof(struct nfattr *) * maxattr);
 
        while (NFA_OK(nfa, len)) {
-               unsigned flavor = nfa->nfa_type;
+               unsigned flavor = NFA_TYPE(nfa);
                if (flavor && flavor <= maxattr)
                        tb[flavor-1] = nfa;
                nfa = NFA_NEXT(nfa, len);
        }
-
-       return 0;
 }
 
 /**
@@ -177,7 +175,7 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys,
                int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
 
                while (NFA_OK(attr, attrlen)) {
-                       unsigned flavor = attr->nfa_type;
+                       unsigned flavor = NFA_TYPE(attr);
                        if (flavor) {
                                if (flavor > attr_count)
                                        return -EINVAL;
@@ -242,15 +240,18 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
        ss = nfnetlink_get_subsys(type);
        if (!ss) {
 #ifdef CONFIG_KMOD
-               /* don't call nfnl_shunlock, since it would reenter
-                * with further packet processing */
-               up(&nfnl_sem);
-               request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
-               nfnl_shlock();
-               ss = nfnetlink_get_subsys(type);
+               if (cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
+                       /* don't call nfnl_shunlock, since it would reenter
+                        * with further packet processing */
+                       up(&nfnl_sem);
+                       request_module("nfnetlink-subsys-%d",
+                                       NFNL_SUBSYS_ID(type));
+                       nfnl_shlock();
+                       ss = nfnetlink_get_subsys(type);
+               }
                if (!ss)
 #endif
-               goto err_inval;
+                       goto err_inval;
        }
 
        nc = nfnetlink_find_client(type, ss);