* [PATCH 2/5] netfilter: nf_ct_sip: fix IPv6 address parsing
From: pablo @ 2012-08-17 14:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1345212573-3076-1-git-send-email-pablo@netfilter.org>
From: Patrick McHardy <kaber@trash.net>
Within SIP messages IPv6 addresses are enclosed in square brackets in most
cases, with the exception of the "received=" header parameter. Currently
the helper fails to parse enclosed addresses.
This patch:
- changes the SIP address parsing function to enforce square brackets
when required, and accept them when not required but present, as
recommended by RFC 5118.
- adds a new SDP address parsing function that never accepts square
brackets since SDP doesn't use them.
With these changes, the SIP helper correctly parses all test messages
from RFC 5118 (Session Initiation Protocol (SIP) Torture Test Messages
for Internet Protocol Version 6 (IPv6)).
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/linux/netfilter/nf_conntrack_sip.h | 2 +-
net/ipv4/netfilter/nf_nat_sip.c | 4 +-
net/netfilter/nf_conntrack_sip.c | 87 ++++++++++++++++++++++------
3 files changed, 73 insertions(+), 20 deletions(-)
diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h
index 0dfc8b7..89f2a62 100644
--- a/include/linux/netfilter/nf_conntrack_sip.h
+++ b/include/linux/netfilter/nf_conntrack_sip.h
@@ -164,7 +164,7 @@ extern int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr
unsigned int dataoff, unsigned int datalen,
const char *name,
unsigned int *matchoff, unsigned int *matchlen,
- union nf_inet_addr *addr);
+ union nf_inet_addr *addr, bool delim);
extern int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr,
unsigned int off, unsigned int datalen,
const char *name,
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index ea4a238..eef8f29 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -173,7 +173,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
* the reply. */
if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
"maddr=", &poff, &plen,
- &addr) > 0 &&
+ &addr, true) > 0 &&
addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) {
buflen = sprintf(buffer, "%pI4",
@@ -187,7 +187,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
* from which the server received the request. */
if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
"received=", &poff, &plen,
- &addr) > 0 &&
+ &addr, false) > 0 &&
addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip &&
addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) {
buflen = sprintf(buffer, "%pI4",
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 2fb6669..5c0a112 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -183,12 +183,12 @@ static int media_len(const struct nf_conn *ct, const char *dptr,
return len + digits_len(ct, dptr, limit, shift);
}
-static int parse_addr(const struct nf_conn *ct, const char *cp,
- const char **endp, union nf_inet_addr *addr,
- const char *limit)
+static int sip_parse_addr(const struct nf_conn *ct, const char *cp,
+ const char **endp, union nf_inet_addr *addr,
+ const char *limit, bool delim)
{
const char *end;
- int ret = 0;
+ int ret;
if (!ct)
return 0;
@@ -197,16 +197,28 @@ static int parse_addr(const struct nf_conn *ct, const char *cp,
switch (nf_ct_l3num(ct)) {
case AF_INET:
ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end);
+ if (ret == 0)
+ return 0;
break;
case AF_INET6:
+ if (cp < limit && *cp == '[')
+ cp++;
+ else if (delim)
+ return 0;
+
ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end);
+ if (ret == 0)
+ return 0;
+
+ if (end < limit && *end == ']')
+ end++;
+ else if (delim)
+ return 0;
break;
default:
BUG();
}
- if (ret == 0 || end == cp)
- return 0;
if (endp)
*endp = end;
return 1;
@@ -219,7 +231,7 @@ static int epaddr_len(const struct nf_conn *ct, const char *dptr,
union nf_inet_addr addr;
const char *aux = dptr;
- if (!parse_addr(ct, dptr, &dptr, &addr, limit)) {
+ if (!sip_parse_addr(ct, dptr, &dptr, &addr, limit, true)) {
pr_debug("ip: %s parse failed.!\n", dptr);
return 0;
}
@@ -296,7 +308,7 @@ int ct_sip_parse_request(const struct nf_conn *ct,
return 0;
dptr += shift;
- if (!parse_addr(ct, dptr, &end, addr, limit))
+ if (!sip_parse_addr(ct, dptr, &end, addr, limit, true))
return -1;
if (end < limit && *end == ':') {
end++;
@@ -550,7 +562,7 @@ int ct_sip_parse_header_uri(const struct nf_conn *ct, const char *dptr,
if (ret == 0)
return ret;
- if (!parse_addr(ct, dptr + *matchoff, &c, addr, limit))
+ if (!sip_parse_addr(ct, dptr + *matchoff, &c, addr, limit, true))
return -1;
if (*c == ':') {
c++;
@@ -599,7 +611,7 @@ int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr,
unsigned int dataoff, unsigned int datalen,
const char *name,
unsigned int *matchoff, unsigned int *matchlen,
- union nf_inet_addr *addr)
+ union nf_inet_addr *addr, bool delim)
{
const char *limit = dptr + datalen;
const char *start, *end;
@@ -613,7 +625,7 @@ int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr,
return 0;
start += strlen(name);
- if (!parse_addr(ct, start, &end, addr, limit))
+ if (!sip_parse_addr(ct, start, &end, addr, limit, delim))
return 0;
*matchoff = start - dptr;
*matchlen = end - start;
@@ -675,6 +687,47 @@ static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr,
return 1;
}
+static int sdp_parse_addr(const struct nf_conn *ct, const char *cp,
+ const char **endp, union nf_inet_addr *addr,
+ const char *limit)
+{
+ const char *end;
+ int ret;
+
+ memset(addr, 0, sizeof(*addr));
+ switch (nf_ct_l3num(ct)) {
+ case AF_INET:
+ ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end);
+ break;
+ case AF_INET6:
+ ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end);
+ break;
+ default:
+ BUG();
+ }
+
+ if (ret == 0)
+ return 0;
+ if (endp)
+ *endp = end;
+ return 1;
+}
+
+/* skip ip address. returns its length. */
+static int sdp_addr_len(const struct nf_conn *ct, const char *dptr,
+ const char *limit, int *shift)
+{
+ union nf_inet_addr addr;
+ const char *aux = dptr;
+
+ if (!sdp_parse_addr(ct, dptr, &dptr, &addr, limit)) {
+ pr_debug("ip: %s parse failed.!\n", dptr);
+ return 0;
+ }
+
+ return dptr - aux;
+}
+
/* SDP header parsing: a SDP session description contains an ordered set of
* headers, starting with a section containing general session parameters,
* optionally followed by multiple media descriptions.
@@ -686,10 +739,10 @@ static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr,
*/
static const struct sip_header ct_sdp_hdrs[] = {
[SDP_HDR_VERSION] = SDP_HDR("v=", NULL, digits_len),
- [SDP_HDR_OWNER_IP4] = SDP_HDR("o=", "IN IP4 ", epaddr_len),
- [SDP_HDR_CONNECTION_IP4] = SDP_HDR("c=", "IN IP4 ", epaddr_len),
- [SDP_HDR_OWNER_IP6] = SDP_HDR("o=", "IN IP6 ", epaddr_len),
- [SDP_HDR_CONNECTION_IP6] = SDP_HDR("c=", "IN IP6 ", epaddr_len),
+ [SDP_HDR_OWNER_IP4] = SDP_HDR("o=", "IN IP4 ", sdp_addr_len),
+ [SDP_HDR_CONNECTION_IP4] = SDP_HDR("c=", "IN IP4 ", sdp_addr_len),
+ [SDP_HDR_OWNER_IP6] = SDP_HDR("o=", "IN IP6 ", sdp_addr_len),
+ [SDP_HDR_CONNECTION_IP6] = SDP_HDR("c=", "IN IP6 ", sdp_addr_len),
[SDP_HDR_MEDIA] = SDP_HDR("m=", NULL, media_len),
};
@@ -775,8 +828,8 @@ static int ct_sip_parse_sdp_addr(const struct nf_conn *ct, const char *dptr,
if (ret <= 0)
return ret;
- if (!parse_addr(ct, dptr + *matchoff, NULL, addr,
- dptr + *matchoff + *matchlen))
+ if (!sdp_parse_addr(ct, dptr + *matchoff, NULL, addr,
+ dptr + *matchoff + *matchlen))
return -1;
return 1;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH 3/5] netfilter: nf_nat_sip: fix via header translation with multiple parameters
From: pablo @ 2012-08-17 14:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1345212573-3076-1-git-send-email-pablo@netfilter.org>
From: Patrick McHardy <kaber@trash.net>
Via-headers are parsed beginning at the first character after the Via-address.
When the address is translated first and its length decreases, the offset to
start parsing at is incorrect and header parameters might be missed.
Update the offset after translating the Via-address to fix this.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/ipv4/netfilter/nf_nat_sip.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index eef8f29..4ad9cf1 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -148,7 +148,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
hdr, NULL, &matchoff, &matchlen,
&addr, &port) > 0) {
- unsigned int matchend, poff, plen, buflen, n;
+ unsigned int olen, matchend, poff, plen, buflen, n;
char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
/* We're only interested in headers related to this
@@ -163,11 +163,12 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
goto next;
}
+ olen = *datalen;
if (!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen,
&addr, port))
return NF_DROP;
- matchend = matchoff + matchlen;
+ matchend = matchoff + matchlen + *datalen - olen;
/* The maddr= parameter (RFC 2361) specifies where to send
* the reply. */
--
1.7.10.4
^ permalink raw reply related
* [PATCH 4/5] netfilter: ctnetlink: fix missing locking while changing conntrack from nfqueue
From: pablo @ 2012-08-17 14:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1345212573-3076-1-git-send-email-pablo@netfilter.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
Since 9cb017665 netfilter: add glue code to integrate nfnetlink_queue and
ctnetlink, we can modify the conntrack entry via nfnl_queue. However, the
change of the conntrack entry via nfnetlink_queue requires appropriate
locking to avoid concurrent updates.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_netlink.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 14f67a2..da4fc37 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1896,10 +1896,15 @@ static int
ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct)
{
struct nlattr *cda[CTA_MAX+1];
+ int ret;
nla_parse_nested(cda, CTA_MAX, attr, ct_nla_policy);
- return ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct);
+ spin_lock_bh(&nf_conntrack_lock);
+ ret = ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct);
+ spin_unlock_bh(&nf_conntrack_lock);
+
+ return ret;
}
static struct nfq_ct_hook ctnetlink_nfqueue_hook = {
--
1.7.10.4
^ permalink raw reply related
* [PATCH 5/5] netfilter: nf_ct_expect: fix possible access to uninitialized timer
From: pablo @ 2012-08-17 14:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1345212573-3076-1-git-send-email-pablo@netfilter.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
In __nf_ct_expect_check, the function refresh_timer returns 1
if a matching expectation is found and its timer is successfully
refreshed. This results in nf_ct_expect_related returning 0.
Note that at this point:
- the passed expectation is not inserted in the expectation table
and its timer was not initialized, since we have refreshed one
matching/existing expectation.
- nf_ct_expect_alloc uses kmem_cache_alloc, so the expectation
timer is in some undefined state just after the allocation,
until it is appropriately initialized.
This can be a problem for the SIP helper during the expectation
addition:
...
if (nf_ct_expect_related(rtp_exp) == 0) {
if (nf_ct_expect_related(rtcp_exp) != 0)
nf_ct_unexpect_related(rtp_exp);
...
Note that nf_ct_expect_related(rtp_exp) may return 0 for the timer refresh
case that is detailed above. Then, if nf_ct_unexpect_related(rtcp_exp)
returns != 0, nf_ct_unexpect_related(rtp_exp) is called, which does:
spin_lock_bh(&nf_conntrack_lock);
if (del_timer(&exp->timeout)) {
nf_ct_unlink_expect(exp);
nf_ct_expect_put(exp);
}
spin_unlock_bh(&nf_conntrack_lock);
Note that del_timer always returns false if the timer has been
initialized. However, the timer was not initialized since setup_timer
was not called, therefore, the expectation timer remains in some
undefined state. If I'm not missing anything, this may lead to the
removal an unexistent expectation.
To fix this, the optimization that allows refreshing an expectation
is removed. Now nf_conntrack_expect_related looks more consistent
to me since it always add the expectation in case that it returns
success.
Thanks to Patrick McHardy for participating in the discussion of
this patch.
I think this may be the source of the problem described by:
http://marc.info/?l=netfilter-devel&m=134073514719421&w=2
Reported-by: Rafal Fitt <rafalf@aplusc.com.pl>
Acked-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_expect.c | 29 ++++++-----------------------
1 file changed, 6 insertions(+), 23 deletions(-)
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 45cf602..527651a 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -361,23 +361,6 @@ static void evict_oldest_expect(struct nf_conn *master,
}
}
-static inline int refresh_timer(struct nf_conntrack_expect *i)
-{
- struct nf_conn_help *master_help = nfct_help(i->master);
- const struct nf_conntrack_expect_policy *p;
-
- if (!del_timer(&i->timeout))
- return 0;
-
- p = &rcu_dereference_protected(
- master_help->helper,
- lockdep_is_held(&nf_conntrack_lock)
- )->expect_policy[i->class];
- i->timeout.expires = jiffies + p->timeout * HZ;
- add_timer(&i->timeout);
- return 1;
-}
-
static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
{
const struct nf_conntrack_expect_policy *p;
@@ -386,7 +369,7 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
struct nf_conn_help *master_help = nfct_help(master);
struct nf_conntrack_helper *helper;
struct net *net = nf_ct_exp_net(expect);
- struct hlist_node *n;
+ struct hlist_node *n, *next;
unsigned int h;
int ret = 1;
@@ -395,12 +378,12 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
goto out;
}
h = nf_ct_expect_dst_hash(&expect->tuple);
- hlist_for_each_entry(i, n, &net->ct.expect_hash[h], hnode) {
+ hlist_for_each_entry_safe(i, n, next, &net->ct.expect_hash[h], hnode) {
if (expect_matches(i, expect)) {
- /* Refresh timer: if it's dying, ignore.. */
- if (refresh_timer(i)) {
- ret = 0;
- goto out;
+ if (del_timer(&i->timeout)) {
+ nf_ct_unlink_expect(i);
+ nf_ct_expect_put(i);
+ break;
}
} else if (expect_clash(i, expect)) {
ret = -EBUSY;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 0/5] netfilter fixes for 3.6-rc
From: pablo @ 2012-08-17 14:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Pablo Neira Ayuso <pablo@netfilter.org>
Hi David,
The following five patches contain fixes for 3.6-rc, they are:
* Two fixes for message parsing in the SIP conntrack helper, from
Patrick McHardy.
* One fix for the SIP helper introduced in the user-space cthelper
infrastructure, from Patrick McHardy.
* fix missing appropriate locking while modifying one conntrack entry
from the nfqueue integration code, from myself.
* fix possible access to uninitiliazed timer in the nf_conntrack
expectation infrastructure, from myself.
You can pull these changes from:
git://1984.lsi.us.es/nf
Thanks!
Pablo Neira Ayuso (2):
netfilter: ctnetlink: fix missing locking while changing conntrack from nfqueue
netfilter: nf_ct_expect: fix possible access to uninitialized timer
Patrick McHardy (3):
netfilter: nf_ct_sip: fix helper name
netfilter: nf_ct_sip: fix IPv6 address parsing
netfilter: nf_nat_sip: fix via header translation with multiple parameters
include/linux/netfilter/nf_conntrack_sip.h | 2 +-
net/ipv4/netfilter/nf_nat_sip.c | 9 +--
net/netfilter/nf_conntrack_expect.c | 29 ++-------
net/netfilter/nf_conntrack_netlink.c | 7 ++-
net/netfilter/nf_conntrack_sip.c | 92 ++++++++++++++++++++++------
5 files changed, 90 insertions(+), 49 deletions(-)
--
1.7.10.4
^ permalink raw reply
* Linux -next build failure
From: Alan Cox @ 2012-08-17 15:03 UTC (permalink / raw)
To: netdev
Build with CONFIG_TIGON3=y and CONFIG_HWMON=m
drivers/built-in.o: In function `tg3_close':
tg3.c:(.text+0xe223a): undefined reference to `hwmon_device_unregister'
drivers/built-in.o: In function `tg3_hwmon_open':
tg3.c:(.text+0xe6109): undefined reference to `hwmon_device_register'
^ permalink raw reply
* [PATCH v1 0/5] cgroup: Assign subsystem IDs during compile time
From: Daniel Wagner @ 2012-08-17 14:58 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Hi,
I was able to 'fix' CGROUP_BUILTIN_SUBSYS_COUNT defition. With this
version there is no unused subsys_id.
The number of builtin subsystem are counted with gcc's predefined
__COUNTER__ macro. This is a bit fragile, because __COUNTER__
is only reset to 0 per compile unit. There is a workaround for this.
When starting to enumate we need to store the current value of
__COUNTER__ and then subtract that from all enums we define.
Not sure if that is okay or not.
cheers,
daniel
Original cover letter:
The patch #1 and #2 are there to be able to introduce (#3, #4) the
jump labels in task_cls_classid() and task_netprioidx(). The jump
labels are needed to know when it is safe to access the controller.
For example not safe means the module is not yet loaded.
All those patches are just preparation for the center piece (#5)
of these series. This one will remove the dynamic subsystem ID
generation and falls back to compile time generated IDs.
This is the first result from the discussion around on the
"cgroup cls & netprio 'cleanups'" patches.
This patches are against net-next
v1: - only use jump labels when built as module (#3, #4)
- get rid of the additional 'pointer' (#5)
v0: - initial version
Daniel Wagner (5):
cgroup: Use empty task_cls_classid() when !CONFIG_NET_CLS(_MODULE)
cgroup: Move sock_update_classid() decleration to cls_cgroup.h
cgroup: Protect access to task_cls_classid() when built as module
cgroup: Protect access to task_netprioidx() when built as module
cgroup: Assign subsystem IDs during compile time
include/linux/cgroup.h | 27 ++++++++++++++++++---------
include/linux/cgroup_subsys.h | 24 ++++++++++++------------
include/net/cls_cgroup.h | 39 ++++++++++++++++++++++++++-------------
include/net/netprio_cgroup.h | 25 +++++++++++--------------
include/net/sock.h | 8 --------
kernel/cgroup.c | 25 ++++++-------------------
net/core/netprio_cgroup.c | 21 ++++++++++-----------
net/core/sock.c | 12 ++++++------
net/sched/cls_cgroup.c | 22 +++++++++-------------
9 files changed, 98 insertions(+), 105 deletions(-)
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply
* [PATCH v1 1/5] cgroup: Use empty task_cls_classid() when !CONFIG_NET_CLS(_MODULE)
From: Daniel Wagner @ 2012-08-17 14:58 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, David S. Miller, Gao feng, Jamal Hadi Salim,
John Fastabend, Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1345215494-9181-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
include/net/cls_cgroup.h | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index a4dc5b0..e2fe2b9 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -24,7 +24,8 @@ struct cgroup_cls_state
u32 classid;
};
-#ifdef CONFIG_NET_CLS_CGROUP
+#if IS_BUILTIN(CONFIG_NET_CLS_CGROUP)
+
static inline u32 task_cls_classid(struct task_struct *p)
{
int classid;
@@ -39,7 +40,9 @@ static inline u32 task_cls_classid(struct task_struct *p)
return classid;
}
-#else
+
+#elif IS_MODULE(CONFIG_NET_CLS_CGROUP)
+
extern int net_cls_subsys_id;
static inline u32 task_cls_classid(struct task_struct *p)
@@ -60,11 +63,16 @@ static inline u32 task_cls_classid(struct task_struct *p)
return classid;
}
-#endif
+
#else
+
static inline u32 task_cls_classid(struct task_struct *p)
{
return 0;
}
-#endif
+
+#endif /* CONFIG_NET_CLS_CGROUP */
+
+#endif /* CONFIG_CGROURPS */
+
#endif /* _NET_CLS_CGROUP_H */
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v1 2/5] cgroup: Move sock_update_classid() decleration to cls_cgroup.h
From: Daniel Wagner @ 2012-08-17 14:58 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, Gao feng, Jamal Hadi Salim, John Fastabend,
Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1345215494-9181-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
The only user of sock_update_classid() is net/socket.c which
happens to include cls_cgroup.h direclty.
Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
include/net/cls_cgroup.h | 8 ++++++++
include/net/sock.h | 8 --------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index e2fe2b9..401672c 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -24,6 +24,8 @@ struct cgroup_cls_state
u32 classid;
};
+extern void sock_update_classid(struct sock *sk);
+
#if IS_BUILTIN(CONFIG_NET_CLS_CGROUP)
static inline u32 task_cls_classid(struct task_struct *p)
@@ -73,6 +75,12 @@ static inline u32 task_cls_classid(struct task_struct *p)
#endif /* CONFIG_NET_CLS_CGROUP */
+#else /* !CONFIG_CGROUPS */
+
+static inline void sock_update_classid(struct sock *sk)
+{
+}
+
#endif /* CONFIG_CGROURPS */
#endif /* _NET_CLS_CGROUP_H */
diff --git a/include/net/sock.h b/include/net/sock.h
index 72132ae..160a680 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1486,14 +1486,6 @@ extern void *sock_kmalloc(struct sock *sk, int size,
extern void sock_kfree_s(struct sock *sk, void *mem, int size);
extern void sk_send_sigurg(struct sock *sk);
-#ifdef CONFIG_CGROUPS
-extern void sock_update_classid(struct sock *sk);
-#else
-static inline void sock_update_classid(struct sock *sk)
-{
-}
-#endif
-
/*
* Functions to fill in entries in struct proto_ops when a protocol
* does not implement a particular function.
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v1 3/5] cgroup: Protect access to task_cls_classid() when built as module
From: Daniel Wagner @ 2012-08-17 14:58 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, David S. Miller, Gao feng, Jamal Hadi Salim,
John Fastabend, Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1345215494-9181-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
The module version of task_cls_classid() checks if net_cls_sbusys_id
is valid to indentify when it is okay to access the controller.
Instead relying on the subusys_id to be set, make it explicit
with a jump label.
Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
include/net/cls_cgroup.h | 5 ++++-
net/core/sock.c | 5 +++++
net/sched/cls_cgroup.c | 9 +++++++++
3 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index 401672c..bbbd957 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -16,6 +16,7 @@
#include <linux/cgroup.h>
#include <linux/hardirq.h>
#include <linux/rcupdate.h>
+#include <linux/jump_label.h>
#ifdef CONFIG_CGROUPS
struct cgroup_cls_state
@@ -44,6 +45,8 @@ static inline u32 task_cls_classid(struct task_struct *p)
}
#elif IS_MODULE(CONFIG_NET_CLS_CGROUP)
+extern struct static_key cgroup_cls_enabled;
+#define clscg_enabled static_key_false(&cgroup_cls_enabled)
extern int net_cls_subsys_id;
@@ -52,7 +55,7 @@ static inline u32 task_cls_classid(struct task_struct *p)
int id;
u32 classid = 0;
- if (in_interrupt())
+ if (!clscg_enabled || in_interrupt())
return 0;
rcu_read_lock();
diff --git a/net/core/sock.c b/net/core/sock.c
index 8f67ced..8106e77 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -327,6 +327,11 @@ int __sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
EXPORT_SYMBOL(__sk_backlog_rcv);
#if defined(CONFIG_CGROUPS)
+#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
+struct static_key cgroup_cls_enabled = STATIC_KEY_INIT_FALSE;
+EXPORT_SYMBOL_GPL(cgroup_cls_enabled);
+#endif
+
#if !defined(CONFIG_NET_CLS_CGROUP)
int net_cls_subsys_id = -1;
EXPORT_SYMBOL_GPL(net_cls_subsys_id);
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 7743ea8..0635894 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -44,12 +44,21 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp)
if (cgrp->parent)
cs->classid = cgrp_cls_state(cgrp->parent)->classid;
+#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
+ else if (!clscg_enabled)
+ static_key_slow_inc(&cgroup_cls_enabled);
+#endif
return &cs->css;
}
static void cgrp_destroy(struct cgroup *cgrp)
{
+#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
+ if (!cgrp->parent && clscg_enabled)
+ static_key_slow_dec(&cgroup_cls_enabled);
+#endif
+
kfree(cgrp_cls_state(cgrp));
}
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v1 4/5] cgroup: Protect access to task_netprioidx() when built as module
From: Daniel Wagner @ 2012-08-17 14:58 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, David S. Miller, Gao feng, Jamal Hadi Salim,
John Fastabend, Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1345215494-9181-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
The module version of task_netprioidex() checks if net_prio_subsys_id
is valid to indentify when it is okay to access the controller.
Instead relying on the net_prio_subsys_id to be set, make it explicit
with a jump label.
Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
include/net/netprio_cgroup.h | 8 +++++++-
net/core/netprio_cgroup.c | 10 ++++++++++
net/core/sock.c | 4 ++++
3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/include/net/netprio_cgroup.h b/include/net/netprio_cgroup.h
index 2719dec..9ff58e4 100644
--- a/include/net/netprio_cgroup.h
+++ b/include/net/netprio_cgroup.h
@@ -16,7 +16,7 @@
#include <linux/cgroup.h>
#include <linux/hardirq.h>
#include <linux/rcupdate.h>
-
+#include <linux/jump_label.h>
struct netprio_map {
struct rcu_head rcu;
@@ -54,12 +54,18 @@ static inline u32 task_netprioidx(struct task_struct *p)
#elif IS_MODULE(CONFIG_NETPRIO_CGROUP)
+extern struct static_key cgroup_netprio_enabled;
+#define netpriocg_enabled static_key_false(&cgroup_netprio_enabled)
+
static inline u32 task_netprioidx(struct task_struct *p)
{
struct cgroup_netprio_state *state;
int subsys_id;
u32 idx = 0;
+ if (!netpriocg_enabled)
+ return 0;
+
rcu_read_lock();
subsys_id = rcu_dereference_index_check(net_prio_subsys_id,
rcu_read_lock_held());
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index ed0c043..94e1270 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -155,6 +155,11 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp)
goto out;
}
+#if IS_MODULE(CONFIG_NETPRIO_CGROUP)
+ if (!netpriocg_enabled && !cgrp->parent)
+ static_key_slow_inc(&cgroup_netprio_enabled);
+#endif
+
ret = update_netdev_tables();
if (ret < 0) {
put_prioidx(cs->prioidx);
@@ -173,6 +178,11 @@ static void cgrp_destroy(struct cgroup *cgrp)
struct net_device *dev;
struct netprio_map *map;
+#if IS_MODULE(CONFIG_NETPRIO_CGROUP)
+ if (netpriocg_enabled && !cgrp->parent)
+ static_key_slow_dec(&cgroup_netprio_enabled);
+#endif
+
cs = cgrp_netprio_state(cgrp);
rtnl_lock();
for_each_netdev(&init_net, dev) {
diff --git a/net/core/sock.c b/net/core/sock.c
index 8106e77..1f119d2 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -331,6 +331,10 @@ EXPORT_SYMBOL(__sk_backlog_rcv);
struct static_key cgroup_cls_enabled = STATIC_KEY_INIT_FALSE;
EXPORT_SYMBOL_GPL(cgroup_cls_enabled);
#endif
+#if IS_MODULE(CONFIG_NETPRIO_CGROUP)
+struct static_key cgroup_netprio_enabled = STATIC_KEY_INIT_FALSE;
+EXPORT_SYMBOL_GPL(cgroup_netprio_enabled);
+#endif
#if !defined(CONFIG_NET_CLS_CGROUP)
int net_cls_subsys_id = -1;
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v1 5/5] cgroup: Assign subsystem IDs during compile time
From: Daniel Wagner @ 2012-08-17 14:58 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, David S. Miller, Andrew Morton, Eric Dumazet,
Gao feng, Glauber Costa, Jamal Hadi Salim, John Fastabend,
Kamezawa Hiroyuki, Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1345215494-9181-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
We are able to safe some space when we assign the subsystem
IDs at compile time. Instead of allocating per cgroup
cgroup->subsys[CGROUP_SUBSYS_COUNT] where CGROUP_SUBSYS_COUNT is
always 64, we allocate at max 12 (at this point there are 12
subsystem).
The enum is created by passing in cgroup_subsys.h twice and
redefine the IS_SUBSYS_ENABLED. In the first pass, we just select
the builtin subsystem and in the second pass only the module
subsystems.
task_cls_classid() and task_netprioidx() (when built as
module) are protected by a jump label and therefore we can
simply replace the subsystem index lookup with the enum.
Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
Cc: Eric Dumazet <edumazet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
include/linux/cgroup.h | 27 ++++++++++++++++++---------
include/linux/cgroup_subsys.h | 24 ++++++++++++------------
include/net/cls_cgroup.h | 12 +++---------
include/net/netprio_cgroup.h | 17 ++++-------------
kernel/cgroup.c | 25 ++++++-------------------
net/core/netprio_cgroup.c | 11 -----------
net/core/sock.c | 9 ---------
net/sched/cls_cgroup.c | 13 -------------
8 files changed, 43 insertions(+), 95 deletions(-)
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index c90eaa8..1b9c8d9 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -44,18 +44,25 @@ extern void cgroup_unload_subsys(struct cgroup_subsys *ss);
extern const struct file_operations proc_cgroup_operations;
/* Define the enumeration of all builtin cgroup subsystems */
-#define SUBSYS(_x) _x ## _subsys_id,
+#define INCREASE_COUNTER() __COUNTER__
enum cgroup_subsys_id {
+
+#define SUBSYS(_x) _x ## _subsys_id = INCREASE_COUNTER(),
+#define IS_SUBSYS_ENABLED(option) IS_BUILTIN(option)
#include <linux/cgroup_subsys.h>
- CGROUP_BUILTIN_SUBSYS_COUNT
-};
#undef SUBSYS
-/*
- * This define indicates the maximum number of subsystems that can be loaded
- * at once. We limit to this many since cgroupfs_root has subsys_bits to keep
- * track of all of them.
- */
-#define CGROUP_SUBSYS_COUNT (BITS_PER_BYTE*sizeof(unsigned long))
+#undef IS_SUBSYS_ENABLED
+
+#define SUBSYS(_x) _x ## _subsys_id,
+#define IS_SUBSYS_ENABLED(option) IS_MODULE(option)
+#include <linux/cgroup_subsys.h>
+#undef SUBSYS
+#undef IS_SUBSYS_ENABLED
+
+ CGROUP_SUBSYS_COUNT,
+ CGROUP_BUILTIN_SUBSYS_COUNT = INCREASE_COUNTER()
+};
+#undef INCREASE_COUNTER
/* Per-subsystem/per-cgroup state maintained by the system. */
struct cgroup_subsys_state {
@@ -521,7 +528,9 @@ struct cgroup_subsys {
};
#define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys;
+#define IS_SUBSYS_ENABLED(option) IS_ENABLED(option)
#include <linux/cgroup_subsys.h>
+#undef IS_SUBSYS_ENABLED
#undef SUBSYS
static inline struct cgroup_subsys_state *cgroup_subsys_state(
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
index dfae957..f204a7a 100644
--- a/include/linux/cgroup_subsys.h
+++ b/include/linux/cgroup_subsys.h
@@ -7,73 +7,73 @@
/* */
-#ifdef CONFIG_CPUSETS
+#if IS_SUBSYS_ENABLED(CONFIG_CPUSETS)
SUBSYS(cpuset)
#endif
/* */
-#ifdef CONFIG_CGROUP_DEBUG
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_DEBUG)
SUBSYS(debug)
#endif
/* */
-#ifdef CONFIG_CGROUP_SCHED
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_SCHED)
SUBSYS(cpu_cgroup)
#endif
/* */
-#ifdef CONFIG_CGROUP_CPUACCT
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_CPUACCT)
SUBSYS(cpuacct)
#endif
/* */
-#ifdef CONFIG_MEMCG
+#if IS_SUBSYS_ENABLED(CONFIG_MEMCG)
SUBSYS(mem_cgroup)
#endif
/* */
-#ifdef CONFIG_CGROUP_DEVICE
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_DEVICE)
SUBSYS(devices)
#endif
/* */
-#ifdef CONFIG_CGROUP_FREEZER
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_FREEZER)
SUBSYS(freezer)
#endif
/* */
-#ifdef CONFIG_NET_CLS_CGROUP
+#if IS_SUBSYS_ENABLED(CONFIG_NET_CLS_CGROUP)
SUBSYS(net_cls)
#endif
/* */
-#ifdef CONFIG_BLK_CGROUP
+#if IS_SUBSYS_ENABLED(CONFIG_BLK_CGROUP)
SUBSYS(blkio)
#endif
/* */
-#ifdef CONFIG_CGROUP_PERF
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_PERF)
SUBSYS(perf)
#endif
/* */
-#ifdef CONFIG_NETPRIO_CGROUP
+#if IS_SUBSYS_ENABLED(CONFIG_NETPRIO_CGROUP)
SUBSYS(net_prio)
#endif
/* */
-#ifdef CONFIG_CGROUP_HUGETLB
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_HUGETLB)
SUBSYS(hugetlb)
#endif
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index bbbd957..037bfb1 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -48,22 +48,16 @@ static inline u32 task_cls_classid(struct task_struct *p)
extern struct static_key cgroup_cls_enabled;
#define clscg_enabled static_key_false(&cgroup_cls_enabled)
-extern int net_cls_subsys_id;
-
static inline u32 task_cls_classid(struct task_struct *p)
{
- int id;
- u32 classid = 0;
+ u32 classid;
if (!clscg_enabled || in_interrupt())
return 0;
rcu_read_lock();
- id = rcu_dereference_index_check(net_cls_subsys_id,
- rcu_read_lock_held());
- if (id >= 0)
- classid = container_of(task_subsys_state(p, id),
- struct cgroup_cls_state, css)->classid;
+ classid = container_of(task_subsys_state(p, net_cls_subsys_id),
+ struct cgroup_cls_state, css)->classid;
rcu_read_unlock();
return classid;
diff --git a/include/net/netprio_cgroup.h b/include/net/netprio_cgroup.h
index 9ff58e4..66241c6 100644
--- a/include/net/netprio_cgroup.h
+++ b/include/net/netprio_cgroup.h
@@ -31,10 +31,6 @@ struct cgroup_netprio_state {
u32 prioidx;
};
-#ifndef CONFIG_NETPRIO_CGROUP
-extern int net_prio_subsys_id;
-#endif
-
extern void sock_update_netprioidx(struct sock *sk, struct task_struct *task);
#if IS_BUILTIN(CONFIG_NETPRIO_CGROUP)
@@ -60,20 +56,15 @@ extern struct static_key cgroup_netprio_enabled;
static inline u32 task_netprioidx(struct task_struct *p)
{
struct cgroup_netprio_state *state;
- int subsys_id;
- u32 idx = 0;
+ u32 idx;
if (!netpriocg_enabled)
return 0;
rcu_read_lock();
- subsys_id = rcu_dereference_index_check(net_prio_subsys_id,
- rcu_read_lock_held());
- if (subsys_id >= 0) {
- state = container_of(task_subsys_state(p, subsys_id),
- struct cgroup_netprio_state, css);
- idx = state->prioidx;
- }
+ state = container_of(task_subsys_state(p, net_prio_subsys_id),
+ struct cgroup_netprio_state, css);
+ idx = state->prioidx;
rcu_read_unlock();
return idx;
}
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 7981850..b00ae8a 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -93,9 +93,12 @@ static DEFINE_MUTEX(cgroup_root_mutex);
* cgroup_mutex.
*/
#define SUBSYS(_x) &_x ## _subsys,
+#define IS_SUBSYS_ENABLED(option) IS_BUILTIN(option)
static struct cgroup_subsys *subsys[CGROUP_SUBSYS_COUNT] = {
#include <linux/cgroup_subsys.h>
};
+#undef IS_SUBSYS_ENABLED
+#undef SUBSYS
#define MAX_CGROUP_ROOT_NAMELEN 64
@@ -4330,24 +4333,8 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
/* init base cftset */
cgroup_init_cftsets(ss);
- /*
- * need to register a subsys id before anything else - for example,
- * init_cgroup_css needs it.
- */
mutex_lock(&cgroup_mutex);
- /* find the first empty slot in the array */
- for (i = CGROUP_BUILTIN_SUBSYS_COUNT; i < CGROUP_SUBSYS_COUNT; i++) {
- if (subsys[i] == NULL)
- break;
- }
- if (i == CGROUP_SUBSYS_COUNT) {
- /* maximum number of subsystems already registered! */
- mutex_unlock(&cgroup_mutex);
- return -EBUSY;
- }
- /* assign ourselves the subsys_id */
- ss->subsys_id = i;
- subsys[i] = ss;
+ subsys[ss->subsys_id] = ss;
/*
* no ss->create seems to need anything important in the ss struct, so
@@ -4356,7 +4343,7 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
css = ss->create(dummytop);
if (IS_ERR(css)) {
/* failure case - need to deassign the subsys[] slot. */
- subsys[i] = NULL;
+ subsys[ss->subsys_id] = NULL;
mutex_unlock(&cgroup_mutex);
return PTR_ERR(css);
}
@@ -4372,7 +4359,7 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
if (ret) {
dummytop->subsys[ss->subsys_id] = NULL;
ss->destroy(dummytop);
- subsys[i] = NULL;
+ subsys[ss->subsys_id] = NULL;
mutex_unlock(&cgroup_mutex);
return ret;
}
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index 94e1270..3a1d5cc 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -352,9 +352,7 @@ struct cgroup_subsys net_prio_subsys = {
.create = cgrp_create,
.destroy = cgrp_destroy,
.attach = net_prio_attach,
-#ifdef CONFIG_NETPRIO_CGROUP
.subsys_id = net_prio_subsys_id,
-#endif
.base_cftypes = ss_files,
.module = THIS_MODULE
};
@@ -392,10 +390,6 @@ static int __init init_cgroup_netprio(void)
ret = cgroup_load_subsys(&net_prio_subsys);
if (ret)
goto out;
-#ifndef CONFIG_NETPRIO_CGROUP
- smp_wmb();
- net_prio_subsys_id = net_prio_subsys.subsys_id;
-#endif
register_netdevice_notifier(&netprio_device_notifier);
@@ -412,11 +406,6 @@ static void __exit exit_cgroup_netprio(void)
cgroup_unload_subsys(&net_prio_subsys);
-#ifndef CONFIG_NETPRIO_CGROUP
- net_prio_subsys_id = -1;
- synchronize_rcu();
-#endif
-
rtnl_lock();
for_each_netdev(&init_net, dev) {
old = rtnl_dereference(dev->priomap);
diff --git a/net/core/sock.c b/net/core/sock.c
index 1f119d2..aa762d9 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -335,15 +335,6 @@ EXPORT_SYMBOL_GPL(cgroup_cls_enabled);
struct static_key cgroup_netprio_enabled = STATIC_KEY_INIT_FALSE;
EXPORT_SYMBOL_GPL(cgroup_netprio_enabled);
#endif
-
-#if !defined(CONFIG_NET_CLS_CGROUP)
-int net_cls_subsys_id = -1;
-EXPORT_SYMBOL_GPL(net_cls_subsys_id);
-#endif
-#if !defined(CONFIG_NETPRIO_CGROUP)
-int net_prio_subsys_id = -1;
-EXPORT_SYMBOL_GPL(net_prio_subsys_id);
-#endif
#endif
static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 0635894..5dd6fe6 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -86,9 +86,7 @@ struct cgroup_subsys net_cls_subsys = {
.name = "net_cls",
.create = cgrp_create,
.destroy = cgrp_destroy,
-#ifdef CONFIG_NET_CLS_CGROUP
.subsys_id = net_cls_subsys_id,
-#endif
.base_cftypes = ss_files,
.module = THIS_MODULE,
};
@@ -292,12 +290,6 @@ static int __init init_cgroup_cls(void)
if (ret)
goto out;
-#ifndef CONFIG_NET_CLS_CGROUP
- /* We can't use rcu_assign_pointer because this is an int. */
- smp_wmb();
- net_cls_subsys_id = net_cls_subsys.subsys_id;
-#endif
-
ret = register_tcf_proto_ops(&cls_cgroup_ops);
if (ret)
cgroup_unload_subsys(&net_cls_subsys);
@@ -310,11 +302,6 @@ static void __exit exit_cgroup_cls(void)
{
unregister_tcf_proto_ops(&cls_cgroup_ops);
-#ifndef CONFIG_NET_CLS_CGROUP
- net_cls_subsys_id = -1;
- synchronize_rcu();
-#endif
-
cgroup_unload_subsys(&net_cls_subsys);
}
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* Re: [RFC PATCH 0/1] sched: Add a new API to find the prefer idlest cpu
From: Shirley Ma @ 2012-08-17 15:39 UTC (permalink / raw)
To: linux-kernel, mingo, peterz; +Cc: netdev, Michael S. Tsirkin, vivek, sri, sri
In-Reply-To: <1343026634.13461.15.camel@oc3660625478.ibm.com>
Hello Ingo, Peter,
Have you had chance to review below patch?
Thanks
Shirley
On Sun, 2012-07-22 at 23:57 -0700, Shirley Ma wrote:
> Introduce a new API to choose per-cpu thread from cgroup control cpuset
> (allowed) and preferred cpuset (local numa-node).
>
> The receiving cpus of a networking device are not under cgroup controls.
> When such a networking device uses per-cpu thread model, the cpu which
> is chose to process the packets might not be part of cgroup cpusets
> without this API. On numa system, the preferred cpusets would help to
> reduce expensive cross memory access to/from the other node.
>
> Signed-off-by: Shirley Ma <xma@us.ibm.com>
> ---
>
> include/linux/sched.h | 2 ++
> kernel/sched/fair.c | 30 ++++++++++++++++++++++++++++++
> 2 files changed, 32 insertions(+), 0 deletions(-)
>
> Thanks
> Shirley
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH 0/5] Call netif_carrier_off() after register_netdev()
From: Stephen Hemminger @ 2012-08-17 16:20 UTC (permalink / raw)
To: Ilya Shchepetkov
Cc: bjorn, David S. Miller, Ben Hutchings, netdev, linux-kernel,
ldv-project
In-Reply-To: <1345190143-12050-1-git-send-email-shchepetkov@ispras.ru>
On Fri, 17 Aug 2012 11:55:43 +0400
Ilya Shchepetkov <shchepetkov@ispras.ru> wrote:
> >> Ben Hutchings <bhutchings@solarflare.com> writes:
> >>> But if you do it beforehand then it doesn't have the intended effect.
> >>> (Supposed to be fixed by 22604c866889c4b2e12b73cbf1683bda1b72a313, which
> >>> had to be reverted: c276e098d3ee33059b4a1c747354226cec58487c.)
> >>>
> >>> So you have to do it after, but without dropping the RTNL lock in
> >>> between.
> >> So you may want to add something like
> >>
> >> int register_netdev_carrier_off(struct net_device *dev)
> >> {
> >> int err;
> >>
> >> rtnl_lock();
> >> err = register_netdevice(dev);
> >> if (!err)
> >> set_bit(__LINK_STATE_NOCARRIER, &dev->state)
> >> rtnl_unlock();
> >> return err;
> >> }
> >>
> >>
> >> for these drivers?
>
> t looks like this variant is equivalent to the existing code:
>
> netif_carrier_off(dev);
> err = register_netdev(dev);
> if (err)
> goto out;
>
> According to explanation in commit 22604c866889c4b2e12b73cbf1683bda1b72a313,
> in this case "this causes these drivers to incorrectly report their
> link status as IF_OPER_UNKNOWN which can falsely set the IFF_RUNNING
> flag when the interface is first brought up".
>
> As far as I understand, to fix the issue it is required to call
> netif_carrier_off() itself:
>
> int register_netdev_carrier_off(struct net_device *dev)
> {
> int err;
>
> rtnl_lock();
> err = register_netdevice(dev);
> if (!err)
> netif_carrier_off(dev);
> rtnl_unlock();
> return err;
> }
>
> What do you think?
Does this prevent multiple link events from being reported to user space?
If the root cause of the problem is the link status
(commit 22604c866889c4b2e12b73cbf1683bda1b72a313), then the kernel
should be fixed to do link status correctly.
>From an application point of view IFF_RUNNING is meaningless unless IFF_UP
is set.
^ permalink raw reply
* Re: [PATCH] smsc75xx: add missing entry to MAINTAINERS
From: Joe Perches @ 2012-08-17 16:21 UTC (permalink / raw)
To: Steve Glendinning; +Cc: linux-kernel, netdev, trivial
In-Reply-To: <1345103618-22753-1-git-send-email-steve.glendinning@shawell.net>
On Thu, 2012-08-16 at 08:53 +0100, Steve Glendinning wrote:
> Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
[]
> diff --git a/MAINTAINERS b/MAINTAINERS
[]
> +USB SMSC75XX ETHERNET DRIVER
> +M: Steve Glendinning <steve.glendinning@shawell.net>
> +L: netdev@vger.kernel.org
> +S: Maintained
> +F: drivers/net/usb/smsc75xx.*
> +
> USB SMSC95XX ETHERNET DRIVER
> M: Steve Glendinning <steve.glendinning@shawell.net>
> L: netdev@vger.kernel.org
Hi Steve.
Perhaps you could have a single updated [79]5xx entry with
F: drivers/net/usb/smsc[79]5xx.*
or
F: drivers/net/usb/smsc?5xx.*
Also, diff makes it seem the drivers aren't significantly
different. Might it be better to integrate the 2 drivers
into a single driver that supports both?
^ permalink raw reply
* Re: [RFC PATCH 0/1] sched: Add a new API to find the prefer idlest cpu
From: Peter Zijlstra @ 2012-08-17 16:48 UTC (permalink / raw)
To: Shirley Ma; +Cc: linux-kernel, mingo, netdev, Michael S. Tsirkin, vivek, sri
In-Reply-To: <1345217986.16533.1.camel@oc3660625478.ibm.com>
On Fri, 2012-08-17 at 08:39 -0700, Shirley Ma wrote:
> Hello Ingo, Peter,
> Have you had chance to review below patch?
Well no of course not, nobody CC'ed us..
Your patch submission sucks, you split the changelog and the actual
patch into two different emails.
It doesn't mention who would be calling this and how often. Nor does it
seem to explain where the cpumask arguments come from.
Please try again.
^ permalink raw reply
* Re: [RFC PATCH 0/1] sched: Add a new API to find the prefer idlest cpu
From: Shirley Ma @ 2012-08-17 16:58 UTC (permalink / raw)
To: Peter Zijlstra
Cc: linux-kernel, mingo, netdev, Michael S. Tsirkin, vivek, sri
In-Reply-To: <1345222134.29668.63.camel@twins>
On Fri, 2012-08-17 at 18:48 +0200, Peter Zijlstra wrote:
> On Fri, 2012-08-17 at 08:39 -0700, Shirley Ma wrote:
>
> > Hello Ingo, Peter,
> > Have you had chance to review below patch?
>
> Well no of course not, nobody CC'ed us..
>
> Your patch submission sucks, you split the changelog and the actual
> patch into two different emails.
>
> It doesn't mention who would be calling this and how often. Nor does
> it
> seem to explain where the cpumask arguments come from.
>
> Please try again.
Thanks for your comments. I must be spoiled by net-dev maintainers. I
used to submit the patch this way thought my linux email in the past
many years. So I need to reply on the changelog for the actual patch? I
hope I won't make any more suck submissions again.
I will try to explain more details why this API needs to be exported.
Thanks again.
Shirley
^ permalink raw reply
* Re: [RFC Patch net-next] ipv6: unify conntrack reassembly expire code with standard one
From: Michal Kubeček @ 2012-08-17 17:05 UTC (permalink / raw)
To: Cong Wang
Cc: netdev, Herbert Xu, David S. Miller, Hideaki YOSHIFUJI,
Patrick McHardy, Shan Wei, Pablo Neira Ayuso, netfilter-devel
In-Reply-To: <1345190565-21689-1-git-send-email-amwang@redhat.com>
On Friday 17 of August 2012 16:02EN, Cong Wang wrote:
> Two years ago, Shan Wei tried to fix this:
> http://patchwork.ozlabs.org/patch/43905/
>
...
>
> As Herbert suggested, we could actually use the standard IPv6
> reassembly code which follows RFC2460.
I tested the patch and I ran into a problem in this place in
ip6_expire_frag_queue():
> net = container_of(fq->q.net, struct net, ipv6.frags);
For frag queues coming from IPv6 conntrack, fq->q.net points to
nf_init_frags which is not embedded into struct net so that the
following device lookup leads to reading from an invalid address.
The same problem has been discussed on the page linked above.
I didn't test with current net-next source but as far as I can tell,
this hasn't changed. Did I miss something?
Michal Kubecek
^ permalink raw reply
* [PATCH 0/2] netlink patches
From: pablo @ 2012-08-17 17:22 UTC (permalink / raw)
To: netdev; +Cc: davem
From: Pablo Neira Ayuso <pablo@netfilter.org>
Hi,
The following two patches contain one update to replace
netlink_set_nonroot and one RFC to resolve possible Netlink
spoofing from the kernel itself by disabling one of the Netlink
features (please, read [PATCH 2/2] for details).
The first patch removes the netlink_set_nonroot to use the recently
added struct netlink_kernel_cfg passed to netlink_kernel_create.
The second tries to address netlink spoofing for non-root processes
from the kernel while disabling the ability of two processes to
communicate. Yes, this may be controversial I guess.
Specifically for the second patch, please, let me know if I'm
missing anything that makes me reach bogus conclusions in the RFC
patch.
Thanks!
Pablo Neira Ayuso (2):
netlink: kill netlink_set_nonroot
[RFC] netlink: fix possible spoofing from non-root processes
include/linux/netlink.h | 9 ++++-----
lib/kobject_uevent.c | 2 +-
net/core/rtnetlink.c | 2 +-
net/netlink/af_netlink.c | 21 ++++++++-------------
net/netlink/genetlink.c | 3 +--
security/selinux/netlink.c | 2 +-
6 files changed, 16 insertions(+), 23 deletions(-)
--
1.7.10.4
^ permalink raw reply
* [PATCH 1/2] netlink: kill netlink_set_nonroot
From: pablo @ 2012-08-17 17:22 UTC (permalink / raw)
To: netdev; +Cc: davem
In-Reply-To: <1345224149-5946-1-git-send-email-pablo@netfilter.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
Replace netlink_set_nonroot by one new field `flags' in
struct netlink_kernel_cfg that is passed to netlink_kernel_create.
This patch also renames NL_NONROOT_* to NL_CFG_F_NONROOT_* since
now the flags field in nl_table is generic (so we can add more
flags if needed in the future).
Also adjust all callers in the net-next tree to use these flags
instead of netlink_set_nonroot.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/linux/netlink.h | 9 ++++-----
lib/kobject_uevent.c | 2 +-
net/core/rtnetlink.c | 2 +-
net/netlink/af_netlink.c | 20 +++++++-------------
net/netlink/genetlink.c | 3 +--
security/selinux/netlink.c | 2 +-
6 files changed, 15 insertions(+), 23 deletions(-)
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index f74dd13..2f67621 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -174,12 +174,16 @@ struct netlink_skb_parms {
extern void netlink_table_grab(void);
extern void netlink_table_ungrab(void);
+#define NL_CFG_F_NONROOT_RECV (1 << 0)
+#define NL_CFG_F_NONROOT_SEND (1 << 1)
+
/* optional Netlink kernel configuration parameters */
struct netlink_kernel_cfg {
unsigned int groups;
void (*input)(struct sk_buff *skb);
struct mutex *cb_mutex;
void (*bind)(int group);
+ unsigned int flags;
};
extern struct sock *netlink_kernel_create(struct net *net, int unit,
@@ -258,11 +262,6 @@ extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
const struct nlmsghdr *nlh,
struct netlink_dump_control *control);
-
-#define NL_NONROOT_RECV 0x1
-#define NL_NONROOT_SEND 0x2
-extern void netlink_set_nonroot(int protocol, unsigned flag);
-
#endif /* __KERNEL__ */
#endif /* __LINUX_NETLINK_H */
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 0401d29..c2e9778 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -375,6 +375,7 @@ static int uevent_net_init(struct net *net)
struct uevent_sock *ue_sk;
struct netlink_kernel_cfg cfg = {
.groups = 1,
+ .flags = NL_CFG_F_NONROOT_RECV,
};
ue_sk = kzalloc(sizeof(*ue_sk), GFP_KERNEL);
@@ -422,7 +423,6 @@ static struct pernet_operations uevent_net_ops = {
static int __init kobject_uevent_init(void)
{
- netlink_set_nonroot(NETLINK_KOBJECT_UEVENT, NL_NONROOT_RECV);
return register_pernet_subsys(&uevent_net_ops);
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 34d975b..d83f73b 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2381,6 +2381,7 @@ static int __net_init rtnetlink_net_init(struct net *net)
.groups = RTNLGRP_MAX,
.input = rtnetlink_rcv,
.cb_mutex = &rtnl_mutex,
+ .flags = NL_CFG_F_NONROOT_RECV,
};
sk = netlink_kernel_create(net, NETLINK_ROUTE, THIS_MODULE, &cfg);
@@ -2416,7 +2417,6 @@ void __init rtnetlink_init(void)
if (register_pernet_subsys(&rtnetlink_net_ops))
panic("rtnetlink_init: cannot initialize rtnetlink\n");
- netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV);
register_netdevice_notifier(&rtnetlink_dev_notifier);
rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink,
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 5463969..d04f923 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -121,7 +121,7 @@ struct netlink_table {
struct nl_pid_hash hash;
struct hlist_head mc_list;
struct listeners __rcu *listeners;
- unsigned int nl_nonroot;
+ unsigned int flags;
unsigned int groups;
struct mutex *cb_mutex;
struct module *module;
@@ -596,7 +596,7 @@ retry:
static inline int netlink_capable(const struct socket *sock, unsigned int flag)
{
- return (nl_table[sock->sk->sk_protocol].nl_nonroot & flag) ||
+ return (nl_table[sock->sk->sk_protocol].flags & flag) ||
capable(CAP_NET_ADMIN);
}
@@ -659,7 +659,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
/* Only superuser is allowed to listen multicasts */
if (nladdr->nl_groups) {
- if (!netlink_capable(sock, NL_NONROOT_RECV))
+ if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV))
return -EPERM;
err = netlink_realloc_groups(sk);
if (err)
@@ -721,7 +721,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
return -EINVAL;
/* Only superuser is allowed to send multicasts */
- if (nladdr->nl_groups && !netlink_capable(sock, NL_NONROOT_SEND))
+ if (nladdr->nl_groups && !netlink_capable(sock, NL_CFG_F_NONROOT_SEND))
return -EPERM;
if (!nlk->pid)
@@ -1242,7 +1242,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
break;
case NETLINK_ADD_MEMBERSHIP:
case NETLINK_DROP_MEMBERSHIP: {
- if (!netlink_capable(sock, NL_NONROOT_RECV))
+ if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV))
return -EPERM;
err = netlink_realloc_groups(sk);
if (err)
@@ -1373,7 +1373,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
dst_pid = addr->nl_pid;
dst_group = ffs(addr->nl_groups);
err = -EPERM;
- if (dst_group && !netlink_capable(sock, NL_NONROOT_SEND))
+ if (dst_group && !netlink_capable(sock, NL_CFG_F_NONROOT_SEND))
goto out;
} else {
dst_pid = nlk->dst_pid;
@@ -1578,6 +1578,7 @@ netlink_kernel_create(struct net *net, int unit,
nl_table[unit].cb_mutex = cb_mutex;
nl_table[unit].module = module;
nl_table[unit].bind = cfg ? cfg->bind : NULL;
+ nl_table[unit].flags = cfg ? cfg->flags : 0;
nl_table[unit].registered = 1;
} else {
kfree(listeners);
@@ -1676,13 +1677,6 @@ void netlink_clear_multicast_users(struct sock *ksk, unsigned int group)
netlink_table_ungrab();
}
-void netlink_set_nonroot(int protocol, unsigned int flags)
-{
- if ((unsigned int)protocol < MAX_LINKS)
- nl_table[protocol].nl_nonroot = flags;
-}
-EXPORT_SYMBOL(netlink_set_nonroot);
-
struct nlmsghdr *
__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
{
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index fda4974..c1b71ae 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -918,6 +918,7 @@ static int __net_init genl_pernet_init(struct net *net)
struct netlink_kernel_cfg cfg = {
.input = genl_rcv,
.cb_mutex = &genl_mutex,
+ .flags = NL_CFG_F_NONROOT_RECV,
};
/* we'll bump the group number right afterwards */
@@ -955,8 +956,6 @@ static int __init genl_init(void)
if (err < 0)
goto problem;
- netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
-
err = register_pernet_subsys(&genl_pernet_ops);
if (err)
goto problem;
diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c
index 8a77725..0d2cd11 100644
--- a/security/selinux/netlink.c
+++ b/security/selinux/netlink.c
@@ -113,13 +113,13 @@ static int __init selnl_init(void)
{
struct netlink_kernel_cfg cfg = {
.groups = SELNLGRP_MAX,
+ .flags = NL_CFG_F_NONROOT_RECV,
};
selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX,
THIS_MODULE, &cfg);
if (selnl == NULL)
panic("SELinux: Cannot create netlink socket.");
- netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV);
return 0;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/2] [RFC] netlink: fix possible spoofing from non-root processes
From: pablo @ 2012-08-17 17:22 UTC (permalink / raw)
To: netdev; +Cc: davem
In-Reply-To: <1345224149-5946-1-git-send-email-pablo@netfilter.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
Non-root user-space processes can send netlink messages to other
processes that are well-known for being subscribed to Netlink
asynchronous notifications. This allows ilegitimate non-root
process to send forged messages to them.
This is usually fixed by checking for Netlink portID in the
message receival path of the user-space process. In general,
portID == 0 means that the origin of the messages comes from the
kernel. Thus, discarding any message not coming from the kernel.
This is true for rtnetlink.
However, ctnetlink sets the portID in event messages that has
been triggered by some user-space process, eg. conntrack utility.
So other processes subscribed to ctnetlink events, eg. conntrackd,
know that the event was triggered by some user-space action.
This patch adds capability validation in case that dst_pid is set
in netlink_sendmsg(). This approach is aggressive since any existing
application using any of the Netlink busses to deliver messages
between two user-space processes will break.
[ I don't know any FOSS program making use of Netlink to communicate
to processes, please, let me know if I'm missing anyone important ]
Anyway, if we want to ensure full backward compatibility, a new
version of this patch including NL_CFG_F_NONROOT_SEND flags need
to be set in all kernel subsystems. However, I don't think it
makes sense to use NETLINK_ROUTE to communicate two processes
that are sending no matter what information that is not related
to link/neighbouring/routing?
Still, if someone wants to make use of Netlink for this, eg.
I remember people willing to implement D-BUS over Netlink,
then we can reserve some Netlink bus explicitly for this and
set NL_CFG_F_NONROOT_SEND to it.
Not related to this, but I noticed that some existing well-known
user-space programs set SO_PASSCRED to obtain credentials while
trying to solve this. But they do it wrong, since they misinterpret
credentials containing pid == 0 as "yes, this message is really
coming from the kernel". So those programs will be also happy
that if this patch gets in, since it will fix spoofing for them.
Reported-by: Florian Weimer <fweimer@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netlink/af_netlink.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index d04f923..758993f 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1373,7 +1373,8 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
dst_pid = addr->nl_pid;
dst_group = ffs(addr->nl_groups);
err = -EPERM;
- if (dst_group && !netlink_capable(sock, NL_CFG_F_NONROOT_SEND))
+ if ((dst_group || dst_pid) &&
+ !netlink_capable(sock, NL_CFG_F_NONROOT_SEND))
goto out;
} else {
dst_pid = nlk->dst_pid;
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH v2 0/7] TCP Fast Open client
From: Yuchung Cheng @ 2012-08-17 18:15 UTC (permalink / raw)
To: David Laight; +Cc: davem, hkchu, edumazet, ncardwell, sivasankar, netdev
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B6FB6@saturn3.aculab.com>
On Thu, Aug 16, 2012 at 1:50 AM, David Laight <David.Laight@aculab.com> wrote:
> This comment is a bit late but ...
>
>> ...
>> This patch series implement the client functionality of TCP Fast Open.
>> TCP Fast Open (TFO) allows data to be carried in the SYN and SYN-ACK
>> packets and consumed by the receiving end during the initial
> connection
>> handshake, thus providing a saving of up to one full round trip time
>> (RTT)
>> compared to standard TCP requiring a three-way handshake (3WHS) to
>> complete before data can be exchanged.
>> ...
>> To use Fast Open, the client application (active SYN sender) must
>> replace connect() socket call with sendmsg() or sendto() with the new
>> MSG_FASTOPEN flag. If the server supports Fast Open the data exchange
>> starts at TCP handshake. Otherwise the connection will automatically
>> fall back to conventional TCP.
>
> It seems wrong to be using sendmsg() to perform a 'connect' action.
> Anything that tries to monitor the socket state from a trace, or
> validate the sequence of library calls will get it all wrong.
>
> IMHO this should be a new connect_xxx() function - and probably
> a new system call entry.
>
> This is similar to the complete fubar where sctp abuses setsockopt().
>
> For development hacking using sendmsg() probably avoided the need
> to hack at some code paths, but I'm sure it will cause grief in
> the long term.
>
> Other OS may have much more difficultly in abusing sendmsg().
User/developers' feedback are always welcome so thanks for that.
First of all, sendmsg(MSG_FASTOPEN) does not exclude a new socket
call like connect_with_data().
Unlike many TCP features that don't require API change, TFO does.
When we started, we have several non-exclusive choices:
a) connect_xxx() like you proposed
b) send{to|msg}(MSG_FASTOPEN)
c) setsockopt(optval=data)
d) setsockopt(optval=TFO), make connect() a nop, first write() sends SYN+data.
We surveyed existing works and also discussed with a few developers
before landing on (b). For example, R. Stevens implemented the
pioneer work T/TCP with sendto(MSG_EOF) in BSD in his TCP/IP
illustrated vol3. There is also a Linux patch too. So we know at
least (b) is a viable route. Chrome browser developers chose (b) and
quickly modified the browser accordingly to support TFO.
Another benefit of sendmsg is it allows vector writes right away
and may support MSG_EOF in the future (connect()+write()+close()=SYN+data+FIN).
Most importantly, we want to minimize the application change in
the hope of broader usage to collect more feedbacks about TFO.
If many developers think a new connect() API is better, it's not
that difficult to add one in the kernel IMO. I am happy to do try that.
Cheers,
Yuchung
>
> David
>
>
>
^ permalink raw reply
* Re: [PATCH v1 3/5] cgroup: Protect access to task_cls_classid() when built as module
From: Neil Horman @ 2012-08-17 18:28 UTC (permalink / raw)
To: Daniel Wagner
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Daniel Wagner, David S. Miller, Gao feng, Jamal Hadi Salim,
John Fastabend, Li Zefan, Tejun Heo
In-Reply-To: <1345215494-9181-4-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
On Fri, Aug 17, 2012 at 04:58:12PM +0200, Daniel Wagner wrote:
> From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
>
> The module version of task_cls_classid() checks if net_cls_sbusys_id
> is valid to indentify when it is okay to access the controller.
>
> Instead relying on the subusys_id to be set, make it explicit
> with a jump label.
>
> Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
> Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
> Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
> Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
> Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
> Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> ---
> include/net/cls_cgroup.h | 5 ++++-
> net/core/sock.c | 5 +++++
> net/sched/cls_cgroup.c | 9 +++++++++
> 3 files changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
> index 401672c..bbbd957 100644
> --- a/include/net/cls_cgroup.h
> +++ b/include/net/cls_cgroup.h
> @@ -16,6 +16,7 @@
> #include <linux/cgroup.h>
> #include <linux/hardirq.h>
> #include <linux/rcupdate.h>
> +#include <linux/jump_label.h>
>
> #ifdef CONFIG_CGROUPS
> struct cgroup_cls_state
> @@ -44,6 +45,8 @@ static inline u32 task_cls_classid(struct task_struct *p)
> }
>
> #elif IS_MODULE(CONFIG_NET_CLS_CGROUP)
> +extern struct static_key cgroup_cls_enabled;
> +#define clscg_enabled static_key_false(&cgroup_cls_enabled)
>
> extern int net_cls_subsys_id;
>
> @@ -52,7 +55,7 @@ static inline u32 task_cls_classid(struct task_struct *p)
> int id;
> u32 classid = 0;
>
> - if (in_interrupt())
> + if (!clscg_enabled || in_interrupt())
> return 0;
>
> rcu_read_lock();
> diff --git a/net/core/sock.c b/net/core/sock.c
> index 8f67ced..8106e77 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -327,6 +327,11 @@ int __sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
> EXPORT_SYMBOL(__sk_backlog_rcv);
>
> #if defined(CONFIG_CGROUPS)
> +#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
> +struct static_key cgroup_cls_enabled = STATIC_KEY_INIT_FALSE;
> +EXPORT_SYMBOL_GPL(cgroup_cls_enabled);
> +#endif
> +
> #if !defined(CONFIG_NET_CLS_CGROUP)
> int net_cls_subsys_id = -1;
> EXPORT_SYMBOL_GPL(net_cls_subsys_id);
> diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
> index 7743ea8..0635894 100644
> --- a/net/sched/cls_cgroup.c
> +++ b/net/sched/cls_cgroup.c
> @@ -44,12 +44,21 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp)
>
> if (cgrp->parent)
> cs->classid = cgrp_cls_state(cgrp->parent)->classid;
> +#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
> + else if (!clscg_enabled)
> + static_key_slow_inc(&cgroup_cls_enabled);
This is racy I think. The read of the static key is atomic with other reads,
but the entire conditional is not atomic. If two cpus were creating cgroups in
parallel, it would be possible for both to read the static key as being zero
(the second cpu would read the key before the first cpu could increment it).
> +#endif
>
> return &cs->css;
> }
>
> static void cgrp_destroy(struct cgroup *cgrp)
> {
> +#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
> + if (!cgrp->parent && clscg_enabled)
> + static_key_slow_dec(&cgroup_cls_enabled);
Ditto here with the race above. I think what you want is one of:
1) Use static_key_slow_[inc|dec] unconditionally
2) Keep a separate internal counter to track the number of cgroup instances
so that you only inc the static key on the first create and dec it on the last
delete.
I would think (1) would be sufficent. It looks like static_key_slow_inc uses
atomic_inc_not_zero to just do an inc anyway in the event that multiple inc
events are made.
Neil
> +#endif
> +
> kfree(cgrp_cls_state(cgrp));
> }
>
> --
> 1.7.12.rc1.16.g05a20c8
>
>
^ permalink raw reply
* Re: [PATCH 1/2] ipv6: do not hold route table lock when send ndisc probe
From: Debabrata Banerjee @ 2012-08-17 18:54 UTC (permalink / raw)
To: Cong Wang
Cc: netdev, Banerjee, Debabrata, David S. Miller, Hideaki YOSHIFUJI,
Patrick McHardy
In-Reply-To: <1345187499-16929-1-git-send-email-amwang@redhat.com>
Well it get rids of the deadlock for sure, but I am not sure it
doesn't break something else, one would have to know all of this code
much better to tell. You'll notice read_unlock_bh(&table->tb6_lock)
for the first lock in ip6_pol_route() has more in the critical section
after the rt6_select() call, especially that rather scary BACKTRACK()
macro.
-Debabrata
On Fri, Aug 17, 2012 at 3:11 AM, Cong Wang <amwang@redhat.com> wrote:
> In rt6_probe(), we call ndisc_send_ns() with root->rwlock,
> but this is not necessary, so we can drop it before calling
> ndisc_send_ns().
>
> This could probably fix the deadlock reported by Debabrata:
> https://lkml.org/lkml/2012/8/16/432
>
> Reported-by: "Banerjee, Debabrata" <dbanerje@akamai.com>
> Cc: "Banerjee, Debabrata" <dbanerje@akamai.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
> Cc: Patrick McHardy <kaber@trash.net>
> Signed-off-by: Cong Wang <amwang@redhat.com>
> ---
> net/ipv6/route.c | 7 ++++++-
> 1 files changed, 6 insertions(+), 1 deletions(-)
>
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index 0ddf2d1..7a36df2 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -460,13 +460,18 @@ static void rt6_probe(struct rt6_info *rt)
> time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) {
> struct in6_addr mcaddr;
> struct in6_addr *target;
> + struct net_device *dev = rt->dst.dev;
> + struct fib6_table *table = rt->rt6i_table;
>
> neigh->updated = jiffies;
> read_unlock_bh(&neigh->lock);
> + read_unlock_bh(&table->tb6_lock);
>
> target = (struct in6_addr *)&neigh->primary_key;
> addrconf_addr_solict_mult(target, &mcaddr);
> - ndisc_send_ns(rt->dst.dev, NULL, target, &mcaddr, NULL);
> + ndisc_send_ns(dev, NULL, target, &mcaddr, NULL);
> +
> + read_lock_bh(&table->tb6_lock);
> } else {
> read_unlock_bh(&neigh->lock);
> }
> --
> 1.7.7.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [RFC PATCH 1/1] fair.c: Add/Export find_idlest_perfer_cpu API
From: Shirley Ma @ 2012-08-17 19:46 UTC (permalink / raw)
To: linux-kernel, Peter Zijlstra, mingo
Cc: mingo, Michael S. Tsirkin, netdev, sri, vivek
Add/Export a new API for per-cpu thread model networking device driver
to choose a preferred idlest cpu within allowed cpumask.
The receiving CPUs of a networking device are not under cgroup controls.
Normally the receiving work will be scheduled on the cpu on which the
interrupts are received. When such a networking device uses per-cpu
thread model, the cpu which is chose to process the packets might not be
part of cgroup cpusets without using such an API here.
On NUMA system, by using the preferred cpumask from the same NUMA node
would help to reduce expensive cross memory access to/from the other
NUMA node.
KVM per-cpu vhost will be the first one to use this API. Any other
device driver which uses per-cpu thread model and has cgroup cpuset
control will use this API later.
Signed-off-by: Shirley Ma <xma@us.ibm.com>
---
include/linux/sched.h | 2 ++
kernel/sched/fair.c | 41 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+), 0 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 64d9df5..46cc4a7 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2806,4 +2806,6 @@ static inline unsigned long rlimit_max(unsigned int limit)
#endif /* __KERNEL__ */
+extern int find_idlest_prefer_cpu(struct cpumask *prefer,
+ struct cpumask *allowed, int prev_cpu);
#endif
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index c099cc6..d3da151 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -26,6 +26,7 @@
#include <linux/slab.h>
#include <linux/profile.h>
#include <linux/interrupt.h>
+#include <linux/export.h>
#include <trace/events/sched.h>
@@ -2809,6 +2810,46 @@ unlock:
return new_cpu;
}
+
+/*
+ * This API is used to find the most idle cpu from both preferred and
+ * allowed cpuset.
+ *
+ * allowed: The allowed cpumask is the caller's task allowed cpuset, which could * be from cgroup cpuset control.
+ * prefer: The perfer cpumask is caller's perferred cpuset choice, which could
+ * be a cpuset of a NUMA node for better performance.
+ *
+ * It helps per-cpu thread model to choose the preferred cpu in the allowed
+ * cpuset to be scheduled when the work doesn't want to be scheduled on the
+ * same cpu on which the work is received for better performance. For example
+ * the network work doesn't want to be on the same cpu on which the
+ * interrupt is received.
+ *
+ * If these two cpusets have intersects, the cpu is chose from the intersects;
+ * if there is no intersects, then the cpu is chose from the allowed cpuset.
+ *
+ * prev_cpu helps to better local cache when prev_cpu is not busy.
+ */
+int find_idlest_prefer_cpu(struct cpumask *prefer, struct cpumask *allowed,
+ int prev_cpu)
+{
+ unsigned long load, min_load = ULONG_MAX;
+ int check, i, idlest = -1;
+
+ check = cpumask_intersects(prefer, allowed);
+ /* Traverse only the allowed CPUs */
+ if (check == 0)
+ prefer = allowed;
+ for_each_cpu_and(i, prefer, allowed) {
+ load = weighted_cpuload(i);
+ if (load < min_load || (load == min_load && i == prev_cpu)) {
+ min_load = load;
+ idlest = i;
+ }
+ }
+ return idlest;
+}
+EXPORT_SYMBOL(find_idlest_prefer_cpu);
#endif /* CONFIG_SMP */
static unsigned long
thanks
Shirley
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox