* Re: [PATCH net-2.6.25] qdisc: new rate limiter
From: Patrick McHardy @ 2007-12-08 2:57 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David S. Miller, netdev
In-Reply-To: <20071207162618.35715892@freepuppy.rosehill>
Stephen Hemminger wrote:
> This is a time based rate limiter for use in network testing. When doing
> network tests it is often useful to test at reduced bandwidths. The existing
> Token Bucket Filter provides rate control, but causes bursty traffic that
> can cause different performance than real world. Another alternative is
> the PSPacer, but it depends on pause frames which may also cause issues.
>
> The qdisc depends on high resolution timers and clocks, so it will probably
> use more CPU than others making it a poor choice for use when doing traffic
> shaping for QOS.
>
> Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
>
> --- a/include/linux/pkt_sched.h 2007-10-30 09:18:29.000000000 -0700
> +++ b/include/linux/pkt_sched.h 2007-12-07 13:37:50.000000000 -0800
> @@ -475,4 +475,10 @@ struct tc_netem_corrupt
>
> #define NETEM_DIST_SCALE 8192
>
> +struct tc_rlim_qopt
> +{
> + __u32 limit; /* fifo limit (packets) */
> + __u32 rate; /* bits per sec */
>
This seems a bit small, 512mbit is the maximum rate.
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ b/net/sched/sch_rlim.c 2007-12-07 16:22:10.000000000 -0800
> @@ -0,0 +1,350 @@
> +static struct sk_buff *rlim_dequeue(struct Qdisc *sch)
> +{
> + struct rlim_sched_data *q = qdisc_priv(sch);
> + struct sk_buff *skb;
> + ktime_t now = ktime_get();
> +
> + /* if haven't reached the correct time slot, start timer */
> + if (now.tv64 < q->next_send.tv64) {
> + sch->flags |= TCQ_F_THROTTLED;
> + hrtimer_start(&q->watchdog.timer, q->next_send,
> + HRTIMER_MODE_ABS);
> + return NULL;
> + }
> +
> + skb = q->qdisc->dequeue(q->qdisc);
> + if (skb) {
> + q->next_send = ktime_add_ns(now, pkt_time(q, skb));
> + sch->flags &= ~TCQ_F_THROTTLED;
>
qlen is not decremented here.
> + }
> + return skb;
> +}
> +
> +static int rlim_requeue(struct sk_buff *skb, struct Qdisc *sch)
> +{
> + struct rlim_sched_data *q = qdisc_priv(sch);
> + int ret;
> +
> + ret = q->qdisc->ops->requeue(skb, q->qdisc);
> + if (!ret) {
> + q->next_send = ktime_sub_ns(q->next_send, pkt_time(q, skb));
> + sch->q.qlen++;
> + sch->qstats.requeues++;
> + }
> +
> + return ret;
> +}
> +
> +static void rlim_reset(struct Qdisc *sch)
> +{
> + struct rlim_sched_data *q = qdisc_priv(sch);
> +
> + qdisc_reset_queue(sch);
This should reset the child.
> +
> + q->next_send = ktime_get();
> + qdisc_watchdog_cancel(&q->watchdog);
> +}
> +
> +static int rlim_change(struct Qdisc *sch, struct rtattr *opt)
> +{
> + struct rlim_sched_data *q = qdisc_priv(sch);
> + const struct tc_rlim_qopt *qopt;
> + int err;
> +
> + if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(struct tc_rlim_qopt))
> + return -EINVAL;
> +
> + qopt = RTA_DATA(opt);
>
Using nested attributes would make sure we don't run into
problems with extensibility.
> + err = set_fifo_limit(q->qdisc, qopt->limit);
> + if (err)
> + return err;
> +
> + q->limit = qopt->limit;
> + if (qopt->rate == 0)
> + q->cost = 0; /* unlimited */
> + else {
> + q->cost = (u64)NSEC_PER_SEC << NSEC_SCALE;
> + do_div(q->cost, qopt->rate);
> + }
> +
> + pr_debug("rlim_change: rate=%u cost=%llu\n",
> + qopt->rate, q->cost);
> +
> + return 0;
> +}
> +
> +static struct Qdisc_class_ops rlim_class_ops = {
>
This can be const.
> + .graft = rlim_graft,
> + .leaf = rlim_leaf,
> + .get = rlim_get,
> + .put = rlim_put,
> + .change = rlim_change_class,
> + .delete = rlim_delete,
> + .walk = rlim_walk,
> + .tcf_chain = rlim_find_tcf,
> + .dump = rlim_dump_class,
> +};
>
>
>
^ permalink raw reply
* Re: [PATCH] iproute2: support dotted-quad netmask notation.
From: Andreas Henriksson @ 2007-12-07 23:41 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20071206115350.18e9204f@freepuppy.rosehill>
On tor, 2007-12-06 at 11:53 -0800, Stephen Hemminger wrote:
> On Tue, 4 Dec 2007 14:58:18 +0100
> Andreas Henriksson <andreas@fatal.se> wrote:
>
> > Suggested patch for allowing netmask to be specified in dotted quad format.
> > See http://bugs.debian.org/357172
> >
> > (Known problem: this will not prevent some invalid syntaxes,
> > ie. "255.0.255.0" will be treated as "255.255.255.0")
> >
> > Comments? Suggestions? Improvements?
>
> Fix the bug you mentioned?
>
> [... snip example code ...]
Updated patch, added your netmask validation code but without the check
that made 0.0.0.0 (default) and 255.255.255.255 (one address) invalid
netmasks as they are permitted in CIDR format.
Signed-off-by: Andreas Henriksson <andreas@fatal.se>
diff --git a/lib/utils.c b/lib/utils.c
index 4c42dfd..b4a6125 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -47,6 +47,41 @@ int get_integer(int *val, const char *arg, int base)
return 0;
}
+/* a valid netmask must be 2^n - 1 (n = 1..31) */
+static int is_valid_netmask(const inet_prefix *addr)
+{
+ uint32_t host;
+
+ if (addr->family != AF_INET)
+ return 0;
+
+ host = ~ntohl(addr->data[0]);
+
+ return (host & (host + 1)) == 0;
+}
+
+static int get_netmask(unsigned *val, const char *arg, int base)
+{
+ inet_prefix addr;
+
+ if (!get_unsigned(val, arg, base))
+ return 0;
+
+ /* try coverting dotted quad to CIDR */
+ if (!get_addr_1(&addr, arg, AF_INET)) {
+ u_int32_t mask;
+
+ *val=0;
+ for (mask = addr.data[0]; mask; mask >>= 1)
+ (*val)++;
+
+ if (is_valid_netmask(&addr))
+ return 0;
+ }
+
+ return -1;
+}
+
int get_unsigned(unsigned *val, const char *arg, int base)
{
unsigned long res;
@@ -304,7 +339,8 @@ int get_prefix_1(inet_prefix *dst, char *arg, int family)
dst->bitlen = 32;
}
if (slash) {
- if (get_unsigned(&plen, slash+1, 0) || plen > dst->bitlen) {
+ if (get_netmask(&plen, slash+1, 0)
+ || plen > dst->bitlen) {
err = -1;
goto done;
}
--
Regards,
Andreas Henriksson
^ permalink raw reply related
* Re: [PATCH net-2.6.25] Cleanup IN_DEV_MFORWARD macro
From: Herbert Xu @ 2007-12-08 1:37 UTC (permalink / raw)
To: Pavel Emelyanov; +Cc: David Miller, Linux Netdev List, devel
In-Reply-To: <4759729A.4030403@openvz.org>
On Fri, Dec 07, 2007 at 07:19:38PM +0300, Pavel Emelyanov wrote:
> This is essentially IN_DEV_ANDCONF with proper arguments.
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Thanks Pavel! I must have written that one before writing the
AND macro :)
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [RFC] TCP illinois max rtt aging
From: David Miller @ 2007-12-08 1:32 UTC (permalink / raw)
To: ilpo.jarvinen; +Cc: lachlan.andrew, netdev, quetchen
In-Reply-To: <Pine.LNX.4.64.0712071442530.18529@kivilampi-30.cs.helsinki.fi>
From: "Ilpo_Järvinen" <ilpo.jarvinen@helsinki.fi>
Date: Fri, 7 Dec 2007 15:05:59 +0200 (EET)
> On Fri, 7 Dec 2007, David Miller wrote:
>
> > From: "Ilpo_Järvinen" <ilpo.jarvinen@helsinki.fi>
> > Date: Fri, 7 Dec 2007 13:05:46 +0200 (EET)
> >
> > > I guess if you get a large cumulative ACK, the amount of processing is
> > > still overwhelming (added DaveM if he has some idea how to combat it).
> > >
> > > Even a simple scenario (this isn't anything fancy at all, will occur all
> > > the time): Just one loss => rest skbs grow one by one into a single
> > > very large SACK block (and we do that efficiently for sure) => then the
> > > fast retransmit gets delivered and a cumulative ACK for whole orig_window
> > > arrives => clean_rtx_queue has to do a lot of processing. In this case we
> > > could optimize RB-tree cleanup away (by just blanking it all) but still
> > > getting rid of all those skbs is going to take a larger moment than I'd
> > > like to see.
> > >
> > > That tree blanking could be extended to cover anything which ACK more than
> > > half of the tree by just replacing the root (and dealing with potential
> > > recolorization of the root).
> >
> > Yes, it's the classic problem. But it ought to be at least
> > partially masked when TSO is in use, because we'll only process
> > a handful of SKBs. The more effectively TSO batches, the
> > less work clean_rtx_queue() will do.
>
> No, that's not what is going to happen, TSO won't help at all
> because one-by-one SACKs will fragment every single one of them
> (see tcp_match_skb_to_sack) :-(. ...So we're back in non-TSO
> case, or am I missing something?
You're of course right, and it's ironic that I wrote the SACK
splitting code so I should have known this :-)
A possible approach just occurred to me wherein we maintain
the SACK state external to the SKBs so that we don't need to
mess with them at all.
That would allow us to eliminate the TSO splitting but it would
not remove the general problem of clean_rtx_queue()'s overhead.
I'll try to give some thought to this over the weekend.
^ permalink raw reply
* [PATCH iproute2] rlim qdisc support.
From: Stephen Hemminger @ 2007-12-08 0:29 UTC (permalink / raw)
To: David S. Miller; +Cc: Patrick McHardy, netdev
In-Reply-To: <20071207162618.35715892@freepuppy.rosehill>
Setup code for new rlim qdisc. For use by anyone who wants to
test rlim before kernel inclusion.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
---
include/linux/pkt_sched.h | 6 ++
tc/Makefile | 1 +
tc/q_rlim.c | 115 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 122 insertions(+), 0 deletions(-)
create mode 100644 tc/q_rlim.c
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index 919af93..7973dc4 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -475,4 +475,10 @@ struct tc_netem_corrupt
#define NETEM_DIST_SCALE 8192
+struct tc_rlim_qopt
+{
+ __u32 limit; /* fifo limit (packets) */
+ __u32 rate; /* bits per sec */
+};
+
#endif
diff --git a/tc/Makefile b/tc/Makefile
index a715566..e46954d 100644
--- a/tc/Makefile
+++ b/tc/Makefile
@@ -13,6 +13,7 @@ TCMODULES += q_tbf.o
TCMODULES += q_cbq.o
TCMODULES += q_rr.o
TCMODULES += q_netem.o
+TCMODULES += q_rlim.o
TCMODULES += f_rsvp.o
TCMODULES += f_u32.o
TCMODULES += f_route.o
diff --git a/tc/q_rlim.c b/tc/q_rlim.c
new file mode 100644
index 0000000..5f634a8
--- /dev/null
+++ b/tc/q_rlim.c
@@ -0,0 +1,115 @@
+/*
+ * q_rlim.c RLIM.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors: Stephen Hemminger <shemminger@linux-foundation.org>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+
+#include "utils.h"
+#include "tc_util.h"
+
+static void explain(void)
+{
+ fprintf(stderr, "Usage: ... rlim limit PACKETS rate KBPS\n");
+}
+
+static void explain1(char *arg)
+{
+ fprintf(stderr, "Illegal \"%s\"\n", arg);
+}
+
+
+#define usage() return(-1)
+
+static int rlim_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
+{
+ struct tc_rlim_qopt opt;
+ unsigned x;
+
+ memset(&opt, 0, sizeof(opt));
+
+ while (argc > 0) {
+ if (matches(*argv, "limit") == 0) {
+ NEXT_ARG();
+ if (opt.limit) {
+ fprintf(stderr, "Double \"limit\" spec\n");
+ return -1;
+ }
+ if (get_size(&opt.limit, *argv)) {
+ explain1("limit");
+ return -1;
+ }
+ } else if (strcmp(*argv, "rate") == 0) {
+ NEXT_ARG();
+ if (opt.rate) {
+ fprintf(stderr, "Double \"rate\" spec\n");
+ return -1;
+ }
+
+ if (get_rate(&x, *argv)) {
+ explain1("rate");
+ return -1;
+ }
+ opt.rate = x;
+ } else if (strcmp(*argv, "help") == 0) {
+ explain();
+ return -1;
+ } else {
+ fprintf(stderr, "What is \"%s\"?\n", *argv);
+ explain();
+ return -1;
+ }
+ argc--; argv++;
+ }
+
+ if (opt.rate == 0) {
+ fprintf(stderr, "\"rate\" is required.\n");
+ return -1;
+ }
+
+ if (opt.limit == 0) {
+ fprintf(stderr, "\"limit\" is required.\n");
+ return -1;
+ }
+
+ addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt));
+ return 0;
+}
+
+static int rlim_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
+{
+ struct tc_rlim_qopt *qopt;
+ SPRINT_BUF(b1);
+
+ if (opt == NULL)
+ return 0;
+
+ if (RTA_PAYLOAD(opt) < sizeof(*qopt))
+ return -1;
+ qopt = RTA_DATA(opt);
+ fprintf(f, "limit %up rate %s", qopt->limit, sprint_rate(qopt->rate, b1));
+
+ return 0;
+}
+
+struct qdisc_util rlim_qdisc_util = {
+ .id = "rlim",
+ .parse_qopt = rlim_parse_opt,
+ .print_qopt = rlim_print_opt,
+};
+
--
1.5.3.4
^ permalink raw reply related
* [PATCH net-2.6.25] qdisc: new rate limiter
From: Stephen Hemminger @ 2007-12-08 0:26 UTC (permalink / raw)
To: David S. Miller; +Cc: Patrick McHardy, netdev
This is a time based rate limiter for use in network testing. When doing
network tests it is often useful to test at reduced bandwidths. The existing
Token Bucket Filter provides rate control, but causes bursty traffic that
can cause different performance than real world. Another alternative is
the PSPacer, but it depends on pause frames which may also cause issues.
The qdisc depends on high resolution timers and clocks, so it will probably
use more CPU than others making it a poor choice for use when doing traffic
shaping for QOS.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/include/linux/pkt_sched.h 2007-10-30 09:18:29.000000000 -0700
+++ b/include/linux/pkt_sched.h 2007-12-07 13:37:50.000000000 -0800
@@ -475,4 +475,10 @@ struct tc_netem_corrupt
#define NETEM_DIST_SCALE 8192
+struct tc_rlim_qopt
+{
+ __u32 limit; /* fifo limit (packets) */
+ __u32 rate; /* bits per sec */
+};
+
#endif
--- a/net/sched/Kconfig 2007-12-07 13:37:25.000000000 -0800
+++ b/net/sched/Kconfig 2007-12-07 13:37:50.000000000 -0800
@@ -196,6 +196,19 @@ config NET_SCH_NETEM
If unsure, say N.
+config NET_SCH_RLIM
+ tristate "Network Rate Limiter"
+ ---help---
+ Say Y here if you want to use timer based network rate limiter
+ algorithm.
+
+ See the top of <file:net/sched/sch_rlim.c> for more details.
+
+ To compile this code as a module, choose M here: the
+ module will be called sch_rlim.
+
+ If unsure, say N.
+
config NET_SCH_INGRESS
tristate "Ingress Qdisc"
---help---
--- a/net/sched/Makefile 2007-10-30 09:18:30.000000000 -0700
+++ b/net/sched/Makefile 2007-12-07 13:37:50.000000000 -0800
@@ -28,6 +28,7 @@ obj-$(CONFIG_NET_SCH_TEQL) += sch_teql.o
obj-$(CONFIG_NET_SCH_PRIO) += sch_prio.o
obj-$(CONFIG_NET_SCH_ATM) += sch_atm.o
obj-$(CONFIG_NET_SCH_NETEM) += sch_netem.o
+obj-$(CONFIG_NET_SCH_RLIM) += sch_rlim.o
obj-$(CONFIG_NET_CLS_U32) += cls_u32.o
obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o
obj-$(CONFIG_NET_CLS_FW) += cls_fw.o
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/net/sched/sch_rlim.c 2007-12-07 16:22:10.000000000 -0800
@@ -0,0 +1,350 @@
+/*
+ * net/sched/sch_rate.c Timer based rate control
+ *
+ * Copyright (c) 2007 Stephen Hemminger <shemminger@linux-foundation.org>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+#include <net/netlink.h>
+#include <net/pkt_sched.h>
+#include <asm/div64.h>
+
+/* Simple Rate control
+
+ Algorthim used in NISTnet and others.
+ Logically similar to Token Bucket, but more real time and less lumpy.
+
+ A packet is not allowed to be dequeued until a after the deadline.
+ Each packet dequeued increases the deadline by rate * size.
+
+ If qdisc throttles, it starts a timer, which will wake it up
+ when it is ready to transmit. This scheduler works much better
+ if high resolution timers are available.
+
+ Like classful TBF, limit is just kept for backwards compatibility.
+ It is passed to the default pfifo qdisc - if the inner qdisc is
+ changed the limit is not effective anymore.
+
+*/
+
+/* Use scaled math to get 1/64 ns resolution */
+#define NSEC_SCALE 6
+
+struct rlim_sched_data {
+ ktime_t next_send; /* next scheduled departure */
+ u64 cost; /* nsec/byte * 64 */
+ u32 limit; /* upper bound on fifo (packets) */
+
+ struct Qdisc *qdisc; /* Inner qdisc, default - bfifo queue */
+ struct qdisc_watchdog watchdog;
+};
+
+static int rlim_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+ int ret;
+
+ ret = q->qdisc->enqueue(skb, q->qdisc);
+ if (ret)
+ sch->qstats.drops++;
+ else {
+ sch->q.qlen++;
+ sch->bstats.bytes += skb->len;
+ sch->bstats.packets++;
+ }
+
+ return ret;
+}
+
+
+static u64 pkt_time(const struct rlim_sched_data *q,
+ const struct sk_buff *skb)
+{
+ return (q->cost * skb->len) >> NSEC_SCALE;
+}
+
+static unsigned int rlim_drop(struct Qdisc *sch)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+ unsigned int len = 0;
+
+ if (q->qdisc->ops->drop && (len = q->qdisc->ops->drop(q->qdisc)) != 0) {
+ sch->q.qlen--;
+ sch->qstats.drops++;
+ }
+
+ return len;
+}
+
+static struct sk_buff *rlim_dequeue(struct Qdisc *sch)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+ struct sk_buff *skb;
+ ktime_t now = ktime_get();
+
+ /* if haven't reached the correct time slot, start timer */
+ if (now.tv64 < q->next_send.tv64) {
+ sch->flags |= TCQ_F_THROTTLED;
+ hrtimer_start(&q->watchdog.timer, q->next_send,
+ HRTIMER_MODE_ABS);
+ return NULL;
+ }
+
+ skb = q->qdisc->dequeue(q->qdisc);
+ if (skb) {
+ q->next_send = ktime_add_ns(now, pkt_time(q, skb));
+ sch->flags &= ~TCQ_F_THROTTLED;
+ }
+ return skb;
+}
+
+static int rlim_requeue(struct sk_buff *skb, struct Qdisc *sch)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+ int ret;
+
+ ret = q->qdisc->ops->requeue(skb, q->qdisc);
+ if (!ret) {
+ q->next_send = ktime_sub_ns(q->next_send, pkt_time(q, skb));
+ sch->q.qlen++;
+ sch->qstats.requeues++;
+ }
+
+ return ret;
+}
+
+static void rlim_reset(struct Qdisc *sch)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+
+ qdisc_reset_queue(sch);
+
+ q->next_send = ktime_get();
+ qdisc_watchdog_cancel(&q->watchdog);
+}
+
+
+/* Pass size change message down to embedded FIFO */
+static int set_fifo_limit(struct Qdisc *q, int limit)
+{
+ struct rtattr *rta;
+ int ret = -ENOMEM;
+
+ /* Hack to avoid sending change message to non-FIFO */
+ if (strncmp(q->ops->id + 1, "fifo", 4) != 0)
+ return 0;
+
+ rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
+ if (rta) {
+ rta->rta_type = RTM_NEWQDISC;
+ rta->rta_len = RTA_LENGTH(sizeof(struct tc_fifo_qopt));
+ ((struct tc_fifo_qopt *)RTA_DATA(rta))->limit = limit;
+
+ ret = q->ops->change(q, rta);
+ kfree(rta);
+ }
+ return ret;
+}
+
+static int rlim_change(struct Qdisc *sch, struct rtattr *opt)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+ const struct tc_rlim_qopt *qopt;
+ int err;
+
+ if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(struct tc_rlim_qopt))
+ return -EINVAL;
+
+ qopt = RTA_DATA(opt);
+ err = set_fifo_limit(q->qdisc, qopt->limit);
+ if (err)
+ return err;
+
+ q->limit = qopt->limit;
+ if (qopt->rate == 0)
+ q->cost = 0; /* unlimited */
+ else {
+ q->cost = (u64)NSEC_PER_SEC << NSEC_SCALE;
+ do_div(q->cost, qopt->rate);
+ }
+
+ pr_debug("rlim_change: rate=%u cost=%llu\n",
+ qopt->rate, q->cost);
+
+ return 0;
+}
+
+static int rlim_init(struct Qdisc *sch, struct rtattr *opt)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+
+ if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(struct tc_rlim_qopt))
+ return -EINVAL;
+
+ qdisc_watchdog_init(&q->watchdog, sch);
+
+ q->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
+ TC_H_MAKE(sch->handle, 1));
+ if (!q->qdisc)
+ return -ENOMEM;
+
+ q->next_send = ktime_get();
+
+ return rlim_change(sch, opt);
+}
+
+static void rlim_destroy(struct Qdisc *sch)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+
+ qdisc_watchdog_cancel(&q->watchdog);
+ qdisc_destroy(q->qdisc);
+}
+
+static int rlim_dump(struct Qdisc *sch, struct sk_buff *skb)
+{
+ const struct rlim_sched_data *q = qdisc_priv(sch);
+ unsigned char *b = skb_tail_pointer(skb);
+ struct rtattr *rta;
+ struct tc_rlim_qopt opt;
+
+ rta = (struct rtattr *)b;
+ RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+
+ opt.limit = q->limit;
+ if (q->cost == 0)
+ opt.rate = 0;
+ else
+ opt.rate = div64_64(NSEC_PER_SEC << NSEC_SCALE, q->cost);
+
+ RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+ rta->rta_len = skb_tail_pointer(skb) - b;
+
+ return skb->len;
+
+ rtattr_failure:
+ nlmsg_trim(skb, b);
+ return -1;
+}
+
+static int rlim_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
+ struct Qdisc **old)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+
+ if (new == NULL)
+ new = &noop_qdisc;
+
+ sch_tree_lock(sch);
+ *old = xchg(&q->qdisc, new);
+ qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
+ qdisc_reset(*old);
+ sch_tree_unlock(sch);
+
+ return 0;
+}
+
+static struct Qdisc *rlim_leaf(struct Qdisc *sch, unsigned long arg)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+ return q->qdisc;
+}
+
+static unsigned long rlim_get(struct Qdisc *sch, u32 classid)
+{
+ return 1;
+}
+
+static void rlim_put(struct Qdisc *sch, unsigned long arg)
+{
+}
+
+static int rlim_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+ struct rtattr **tca, unsigned long *arg)
+{
+ return -ENOSYS;
+}
+
+static int rlim_delete(struct Qdisc *sch, unsigned long arg)
+{
+ return -ENOSYS;
+}
+
+static void rlim_walk(struct Qdisc *sch, struct qdisc_walker *walker)
+{
+ if (!walker->stop) {
+ if (walker->count >= walker->skip)
+ if (walker->fn(sch, 1, walker) < 0) {
+ walker->stop = 1;
+ return;
+ }
+ walker->count++;
+ }
+}
+
+static struct tcf_proto **rlim_find_tcf(struct Qdisc *sch, unsigned long cl)
+{
+ return NULL;
+}
+
+static int rlim_dump_class(struct Qdisc *sch, unsigned long cl,
+ struct sk_buff *skb, struct tcmsg *tcm)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+
+ if (cl != 1) /* only one class */
+ return -ENOENT;
+
+ tcm->tcm_handle |= TC_H_MIN(1);
+ tcm->tcm_info = q->qdisc->handle;
+
+ return 0;
+}
+
+static struct Qdisc_class_ops rlim_class_ops = {
+ .graft = rlim_graft,
+ .leaf = rlim_leaf,
+ .get = rlim_get,
+ .put = rlim_put,
+ .change = rlim_change_class,
+ .delete = rlim_delete,
+ .walk = rlim_walk,
+ .tcf_chain = rlim_find_tcf,
+ .dump = rlim_dump_class,
+};
+
+static struct Qdisc_ops rlim_qdisc_ops = {
+ .id = "rlim",
+ .cl_ops = &rlim_class_ops,
+ .priv_size = sizeof(struct rlim_sched_data),
+ .enqueue = rlim_enqueue,
+ .dequeue = rlim_dequeue,
+ .requeue = rlim_requeue,
+ .drop = rlim_drop,
+ .init = rlim_init,
+ .reset = rlim_reset,
+ .destroy = rlim_destroy,
+ .change = rlim_change,
+ .dump = rlim_dump,
+ .owner = THIS_MODULE,
+};
+
+static int __init rlim_module_init(void)
+{
+ return register_qdisc(&rlim_qdisc_ops);
+}
+
+static void __exit rlim_module_exit(void)
+{
+ unregister_qdisc(&rlim_qdisc_ops);
+}
+
+module_init(rlim_module_init)
+module_exit(rlim_module_exit)
+MODULE_LICENSE("GPL");
^ permalink raw reply
* Re: [PATCH 2/2] cxgb3 - Parity initialization for T3C adapters
From: Divy Le Ray @ 2007-12-08 0:14 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-kernel, Steve Wise, wenxiong
In-Reply-To: <4759D6AF.5050205@garzik.org>
Jeff Garzik wrote:
>
> Divy Le Ray wrote:
> > Jeff Garzik wrote:
> >> Divy Le Ray wrote:
> >>> From: Divy Le Ray <divy@chelsio.com>
> >>>
> >>> Add parity initialization for T3C adapters.
> >>>
> >>> Signed-off-by: Divy Le Ray <divy@chelsio.com>
> >>> ---
> >>>
> >>> drivers/net/cxgb3/adapter.h | 1
> >>> drivers/net/cxgb3/cxgb3_main.c | 82 ++++++++++++
> >>> drivers/net/cxgb3/cxgb3_offload.c | 15 ++
> >>> drivers/net/cxgb3/regs.h | 248
> >>> +++++++++++++++++++++++++++++++++++++
> >>> drivers/net/cxgb3/sge.c | 24 +++-
> >>> drivers/net/cxgb3/t3_hw.c | 131 +++++++++++++++++---
> >>> 6 files changed, 472 insertions(+), 29 deletions(-)
> >>
> >> dropped patches 2-3, did not apply
> >>
> >>
> >
> > Hi Jeff,
> >
> > I noticed that you applied the first one of this 3 patches series to the
> > #upstream-fixes branch.
> > These patches are intended to the #upstream (2.6.25) branch, as they are
> > built on top of the
> > last 10 patches committed - 9 from me, and the white space clean up
> > (thanks!).
> > May be this is the reason why they did not apply.
>
> Ah... you need to tell me these things. I looked for a kernel version
> in your messages but did not see one.
>
I had put it in the introduction mail, I should have added the kernel
version in the patch titles.
I'll do from now on.
>
> Does the patch #1 need to be reverted for 2.6.24?
>
No, it can be applied to 2.6.24.
The 2 next patches seem to apply cleanly on #upstream when patch #1 is
popped out the patch stack.
>
> > On this topic, I have a question: how do I get to see all the netdev-2.6
> > branches ?
>
>
> git fetch -f $NETDEV_URL upstream:upstream
>
> copies the latest upstream branch from netdev-2.6.git, and stores it as
> your local upstream branch.
>
> You may do the same for #upstream-fixes too.
>
That made it.
Thanks a lot!
Cheers,
Divy
^ permalink raw reply
* Re: [PATCH 2/2] cxgb3 - Parity initialization for T3C adapters
From: Jeff Garzik @ 2007-12-07 23:26 UTC (permalink / raw)
To: Divy Le Ray; +Cc: netdev, linux-kernel, swise, wenxiong
In-Reply-To: <4759CD92.2070604@chelsio.com>
Divy Le Ray wrote:
> Jeff Garzik wrote:
>> Divy Le Ray wrote:
>>> From: Divy Le Ray <divy@chelsio.com>
>>>
>>> Add parity initialization for T3C adapters.
>>>
>>> Signed-off-by: Divy Le Ray <divy@chelsio.com>
>>> ---
>>>
>>> drivers/net/cxgb3/adapter.h | 1
>>> drivers/net/cxgb3/cxgb3_main.c | 82 ++++++++++++
>>> drivers/net/cxgb3/cxgb3_offload.c | 15 ++
>>> drivers/net/cxgb3/regs.h | 248
>>> +++++++++++++++++++++++++++++++++++++
>>> drivers/net/cxgb3/sge.c | 24 +++-
>>> drivers/net/cxgb3/t3_hw.c | 131 +++++++++++++++++---
>>> 6 files changed, 472 insertions(+), 29 deletions(-)
>>
>> dropped patches 2-3, did not apply
>>
>>
>
> Hi Jeff,
>
> I noticed that you applied the first one of this 3 patches series to the
> #upstream-fixes branch.
> These patches are intended to the #upstream (2.6.25) branch, as they are
> built on top of the
> last 10 patches committed - 9 from me, and the white space clean up
> (thanks!).
> May be this is the reason why they did not apply.
Ah... you need to tell me these things. I looked for a kernel version
in your messages but did not see one.
Does the patch #1 need to be reverted for 2.6.24?
> On this topic, I have a question: how do I get to see all the netdev-2.6
> branches ?
> After cloning a free netdev-2.6 tree, 'git branch' shows only the
> master branch:
>
> bash-3.1$ git --version
> git version 1.5.3.rc4.29.g74276-dirty
> -bash-3.1$ stg clone
> git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
> netdev-2.6-fresh
> Cloning
> "git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git"
> into "netdev-2.6-fresh"...
> Initialized empty Git repository in /opt/sources/netdev-2.6-fresh/.git/
> remote: Generating pack...
> remote: Counting objects: 620879
> Done counting 633562 objects.
> remote: Deltifying 633562 objects...
> remote: 100% (633562/633562) done
> Indexing 633562 objects...
> remote: Total 633562 (delta 517968), reused 594305 (delta 478716)
> 100% (633562/633562) done
> Resolving 517968 deltas...
> 100% (517968/517968) done
> Checking 23058 files out...
> 100% (23058/23058) done
> done
> -bash-3.1$ cd netdev-2.6-fresh/
> -bash-3.1$ git branch
> * master
git fetch -f $NETDEV_URL upstream:upstream
copies the latest upstream branch from netdev-2.6.git, and stores it as
your local upstream branch.
You may do the same for #upstream-fixes too.
Jeff
^ permalink raw reply
* [PATCH] sky2: RX lockup fix
From: Stephen Hemminger @ 2007-12-07 23:22 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Peter Tyser, netdev
In-Reply-To: <1196957697.24978.24.camel@localhost.localdomain>
I'm using a Marvell 88E8062 on a custom PPC64 blade and ran into RX
lockups while validating the sky2 driver. The receive MAC FIFO would
become stuck during testing with high traffic. One port of the 88E8062
would lockup, while the other port remained functional. Re-inserting
the sky2 module would not fix the problem - only a power cycle would.
I looked over Marvell's most recent sk98lin driver and it looks like
they had a "workaround" for the Yukon XL that the sky2 doesn't have yet.
The sk98lin driver disables the RX MAC FIFO flush feature for all
revisions of the Yukon XL.
According to skgeinit.c of the sk98lin driver, "Flushing must be enabled
(needed for ASF see dev. #4.29), but the flushing mask should be
disabled (see dev. #4.115)". Nice. I implemented this same change in
the sky2 driver and verified that the RX lockup I was seeing was
resolved.
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
---
Original patch reformatted to remove line wrap.
--- a/drivers/net/sky2.c 2007-12-06 09:39:12.000000000 -0800
+++ b/drivers/net/sky2.c 2007-12-06 09:54:14.000000000 -0800
@@ -821,8 +821,13 @@ static void sky2_mac_init(struct sky2_hw
sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg);
- /* Flush Rx MAC FIFO on any flow control or error */
- sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
+ if (hw->chip_id == CHIP_ID_YUKON_XL) {
+ /* Hardware errata - clear flush mask */
+ sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), 0);
+ } else {
+ /* Flush Rx MAC FIFO on any flow control or error */
+ sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
+ }
/* Set threshold to 0xa (64 bytes) + 1 to workaround pause bug */
reg = RX_GMF_FL_THR_DEF + 1;
^ permalink raw reply
* Re: [PATCH 2/2] cxgb3 - Parity initialization for T3C adapters
From: Divy Le Ray @ 2007-12-07 22:47 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-kernel, swise, wenxiong
In-Reply-To: <4759A6EA.1050106@garzik.org>
Jeff Garzik wrote:
> Divy Le Ray wrote:
>> From: Divy Le Ray <divy@chelsio.com>
>>
>> Add parity initialization for T3C adapters.
>>
>> Signed-off-by: Divy Le Ray <divy@chelsio.com>
>> ---
>>
>> drivers/net/cxgb3/adapter.h | 1
>> drivers/net/cxgb3/cxgb3_main.c | 82 ++++++++++++
>> drivers/net/cxgb3/cxgb3_offload.c | 15 ++
>> drivers/net/cxgb3/regs.h | 248
>> +++++++++++++++++++++++++++++++++++++
>> drivers/net/cxgb3/sge.c | 24 +++-
>> drivers/net/cxgb3/t3_hw.c | 131 +++++++++++++++++---
>> 6 files changed, 472 insertions(+), 29 deletions(-)
>
> dropped patches 2-3, did not apply
>
>
Hi Jeff,
I noticed that you applied the first one of this 3 patches series to the
#upstream-fixes branch.
These patches are intended to the #upstream (2.6.25) branch, as they are
built on top of the
last 10 patches committed - 9 from me, and the white space clean up
(thanks!).
May be this is the reason why they did not apply.
On this topic, I have a question: how do I get to see all the netdev-2.6
branches ?
After cloning a free netdev-2.6 tree, 'git branch' shows only the
master branch:
bash-3.1$ git --version
git version 1.5.3.rc4.29.g74276-dirty
-bash-3.1$ stg clone
git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
netdev-2.6-fresh
Cloning
"git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git"
into "netdev-2.6-fresh"...
Initialized empty Git repository in /opt/sources/netdev-2.6-fresh/.git/
remote: Generating pack...
remote: Counting objects: 620879
Done counting 633562 objects.
remote: Deltifying 633562 objects...
remote: 100% (633562/633562) done
Indexing 633562 objects...
remote: Total 633562 (delta 517968), reused 594305 (delta 478716)
100% (633562/633562) done
Resolving 517968 deltas...
100% (517968/517968) done
Checking 23058 files out...
100% (23058/23058) done
done
-bash-3.1$ cd netdev-2.6-fresh/
-bash-3.1$ git branch
* master
Cheers,
Divy
^ permalink raw reply
* Re: [PATCH] XFRM: RFC4303 compliant auditing
From: Joy Latten @ 2007-12-07 22:50 UTC (permalink / raw)
To: Paul Moore; +Cc: Eric Paris, netdev, linux-audit
In-Reply-To: <200712071606.38108.paul.moore@hp.com>
On Fri, 2007-12-07 at 16:06 -0500, Paul Moore wrote:
> On Friday 07 December 2007 3:52:31 pm Eric Paris wrote:
> > On Fri, 2007-12-07 at 14:57 -0500, Paul Moore wrote:
> > > NOTE: This really is an RFC patch, it compiles and boots but that is
> > > pretty much all I can promise at this point. I'm posting this patch to
> > > gather feedback from the audit crowd about the continued overloading of
> > > the AUDIT_MAC_IPSEC_EVENT message type - continue to use it or create a
> > > new audit message type? Of course any other comments people may have are
> > > always welcome.
> >
> > I'm all for continuing to use it, but I feel like the op= strings should
> > probably all get collected up in one place to ease maintenance in the
> > future, might not matter but it's nice to be able to look only on place
> > in the code to find all of the possible op=
>
> Agreed. I punted on doing anything here for two main reasons:
>
> 1. It makes sense to do this in the xfrm_audit_start() function which I
> couldn't use here without some overhaul ...
> 2. ... I didn't want to overhaul anything if I was going to end up using
> separate message types.
>
> If we decide to go with a single audit message type (kinda sounds like it)
> I'll fix this up in the next version.
>
> > The one advantage to multiple messages is the ability to exclude and not
> > audit certain things. How often will these extra messages actually pop
> > out of a system? Enough that people would likely still care about some
> > of them but decide they don't want others? I don't know this stuff, so
> > tell me how often would any of these show up?
>
> Bingo, this is the whole reason why I was wondering about a different message
> type. Currently only SAD and SPD changes are audited and only because they
> effect the security labels that are assigned to packets as they are
> imported/exported out of the system (look at the LSPP requirements for
> auditing the import and export of data). These new audit messages apply to
> individual packets and/or a particular SA and have nothing to do with
> security labels, rather they indicate error conditions found during normal
> IPsec processing. It would be difficult to think of all of the particular
> cases where these error conditions but in general I would say that these
> audit messages should not be common.
>
Yes, I agree. They should not happen often. Especially compared to LSPP
requirements of auditing whenever SA or SPD entries were added or
deleted, which are common events.
> The only reason for creating a separate audit message type for these packet/SA
> messages would be to meet a RFC requirement that states that the
> implementation MUST allow the administrator to enable and disable ESP
> auditing. Now, we can probably say we fulfill that requirement regardless,
> but more message types allow us greater granularity and flexibility ...
>
Also, there is great possibility of additional messages.
This is for RFC 4303, which is ESP. There are also audit messages
listed for rfc 4301-IPsec architecture and rfc 4302-AH that may
happen later.
^ permalink raw reply
* [RFC] [PATCH] easier PBR for dynamic source tables (via multipath)
From: Brian S Julin @ 2007-12-07 22:21 UTC (permalink / raw)
To: netdev@vger.kernel.org
[-- Attachment #1: Type: text/plain, Size: 3447 bytes --]
This is a first swat and not in final form. I hope folks here will help vet
my thinking on it.
This fills in a missed niche in policy routing support. It allows multipath
routes to select nexthop based on the source realm, inside the routing
decision step, immediately after RPF is performed. It moves RPF before
multipath selection.
This would be for people wanting to do policy routing based on a table
injected by a dynamic routing protocol, e.g. quagga, rather than static rules.
The existing methods for achieving this effect are all a bit tacky for
various reasons:
1) "iptables -m realm --realm X -j ROUTE" in FORWARD,mangle
because ipt_ROUTE is not a well supported iptables target
and has started to get dropped from mainstream distros. Maybe
for lack of maintenence, but perhaps it is intentionally
deprecated. (?)
2) "tc route from" ... "action mirred egress redirect" happens
too late in the packet processing to do much else to the
packet, like say edit the MAC addresses which remain what they
were on the original output dev. Doing this is really an
abuse of the queueing system and involves setting up qdiscs in
weird ways when one may only want to route.
3) Userspace scripts to glue loading from a kernel routing table
to a pre-routing ipset, iptables -j MARK, then "ip rule add fwmark"
because the kernel then has to check the source address against two
tables rather than one, and they could get quite large. Plus it's
hackery.
This patch is a raw proof-of-concept I put together to get
things working just enough to ensure that nothing blows up when
packets are routed this way. As such it does a couple of distasteful
things and has a couple rough edges:
Reuses the nh_weight field as the realm
Does not allow normal load balancing to fully mix in
ipv4 only
forward only, no code for local/output route.
probably will break ifndef CONFIG_NET_CLS_ROUTE
Were this general idea to be deemed worthy, and as long as limiting
sizeof(struct fib_nh) is not a major concern to any linux routing
application. I could work up a more thorough/cleaner patch allowing
statistical multipath and SAD policy-routing multipath to play nicely
together.
Especially needing comments on proper multipath RPF: The mainline code
only checks the selected path and if RPF fails it does not choose a
different one. From this I assumed it is OK to do RPF on any old nexthop,
and we just assume the user won't or can't put any PR rule in that would gum
that up. Otherwise both the mainline code and this code would have to
RPF multiple times, defeating the goal of good performance. (Not to
mention that could get extra confusing when you are using the source
realm to choose.) Special attention to the spec_dest handling, what
should be (?) OK since this is forward-only.
Also to consider is what this means to multipath caching should that
make a comeback.
I've only tested this code lightly so far, just bouncing things around
to static arp maps on the same if.
After patching iproute2, just substitute "weight X" with "byrealm X" to
activate it. Probably you want to avoid realm 0. You should be able to
put catch-all nexthops in with "weight X" alongside the "byrealm" ones
but they do not interact statistically. Comments on that syntax
also welcome.
Sorry about the attachments, no real MUAs available here that won't
corrupt tabs.
[-- Attachment #2: linux-2.6.23.dsad.diff --]
[-- Type: text/plain, Size: 5737 bytes --]
diff -r -U2 linux-source-2.6.23-dsc/include/linux/rtnetlink.h linux-source-2.6.23-dsc-dsad/include/linux/rtnetlink.h
--- linux-source-2.6.23-dsc/include/linux/rtnetlink.h 2007-10-09 16:31:38.000000000 -0400
+++ linux-source-2.6.23-dsc-dsad/include/linux/rtnetlink.h 2007-12-06 20:23:25.000000000 -0500
@@ -294,4 +294,5 @@
#define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */
#define RTNH_F_ONLINK 4 /* Gateway is forced on link */
+#define RTNH_F_DSAD 8 /* Dynamic PBR (weight = source realm) */
/* Macros to handle hexthops */
diff -r -U2 linux-source-2.6.23-dsc/include/net/ip_fib.h linux-source-2.6.23-dsc-dsad/include/net/ip_fib.h
--- linux-source-2.6.23-dsc/include/net/ip_fib.h 2007-10-09 16:31:38.000000000 -0400
+++ linux-source-2.6.23-dsc-dsad/include/net/ip_fib.h 2007-12-06 20:23:25.000000000 -0500
@@ -202,5 +202,6 @@
extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
struct net_device *dev, __be32 *spec_dst, u32 *itag);
-extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
+extern void fib_select_multipath(const struct flowi *flp,
+ struct fib_result *res, u32 itag);
struct rtentry;
diff -r -U2 linux-source-2.6.23-dsc/net/ipv4/fib_semantics.c linux-source-2.6.23-dsc-dsad/net/ipv4/fib_semantics.c
--- linux-source-2.6.23-dsc/net/ipv4/fib_semantics.c 2007-10-09 16:31:38.000000000 -0400
+++ linux-source-2.6.23-dsc-dsad/net/ipv4/fib_semantics.c 2007-12-07 14:36:10.000000000 -0500
@@ -1164,5 +1164,6 @@
*/
-void fib_select_multipath(const struct flowi *flp, struct fib_result *res)
+void fib_select_multipath(const struct flowi *flp, struct fib_result *res,
+ u32 itag)
{
struct fib_info *fi = res->fi;
@@ -1170,8 +1171,20 @@
spin_lock_bh(&fib_multipath_lock);
+ change_nexthops(fi) {
+ if (net_ratelimit())
+ printk(KERN_CRIT "DSAD Considering %x %x\n",nh->nh_weight,itag);
+ if ((nh->nh_flags & RTNH_F_DSAD) &&
+ (((u32)nh->nh_weight - 1) == (itag >> 16))) {
+ res->nh_sel = nhsel;
+ spin_unlock_bh(&fib_multipath_lock);
+ if (net_ratelimit())
+ printk(KERN_CRIT "Chose a DSAD multiroute\n");
+ return;
+ }
+ } endfor_nexthops(fi);
if (fi->fib_power <= 0) {
int power = 0;
change_nexthops(fi) {
- if (!(nh->nh_flags&RTNH_F_DEAD)) {
+ if (!(nh->nh_flags&(RTNH_F_DEAD|RTNH_F_DSAD))) {
power += nh->nh_weight;
nh->nh_power = nh->nh_weight;
@@ -1195,5 +1208,5 @@
change_nexthops(fi) {
- if (!(nh->nh_flags&RTNH_F_DEAD) && nh->nh_power) {
+ if (!(nh->nh_flags&(RTNH_F_DEAD|RTNH_F_DSAD)) && nh->nh_power) {
if ((w -= nh->nh_power) <= 0) {
nh->nh_power--;
diff -r -U2 linux-source-2.6.23-dsc/net/ipv4/route.c linux-source-2.6.23-dsc-dsad/net/ipv4/route.c
--- linux-source-2.6.23-dsc/net/ipv4/route.c 2007-10-09 16:31:38.000000000 -0400
+++ linux-source-2.6.23-dsc-dsad/net/ipv4/route.c 2007-12-06 20:24:45.000000000 -0500
@@ -1622,19 +1622,20 @@
}
-static inline int __mkroute_input(struct sk_buff *skb,
- struct fib_result* res,
- struct in_device *in_dev,
- __be32 daddr, __be32 saddr, u32 tos,
- struct rtable **result)
+static inline int ip_mkroute_input(struct sk_buff *skb,
+ struct fib_result* res,
+ const struct flowi *fl,
+ struct in_device *in_dev,
+ __be32 daddr, __be32 saddr, u32 tos)
{
-
- struct rtable *rth;
- int err;
+ struct rtable* rth = NULL;
struct in_device *out_dev;
unsigned flags = 0;
__be32 spec_dst;
u32 itag;
+ int err;
+ unsigned hash;
- /* get a working reference to the output device */
+ /* get a working reference to a potential output device */
+ res->nh_sel = 0; /* needed? */
out_dev = in_dev_get(FIB_RES_DEV(*res));
if (out_dev == NULL) {
@@ -1645,7 +1646,8 @@
}
-
+ /* Do not check each. spec_dest entirely source dep (I hope.) */
err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res),
in_dev->dev, &spec_dst, &itag);
+
if (err < 0) {
ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr,
@@ -1659,4 +1661,19 @@
flags |= RTCF_DIRECTSRC;
+#ifdef CONFIG_IP_ROUTE_MULTIPATH
+ if (res->fi && res->fi->fib_nhs > 1 && fl->oif == 0)
+ fib_select_multipath(fl, res, itag);
+#endif
+
+ /* Get reference to actual output device */
+ in_dev_put(out_dev);
+ out_dev = in_dev_get(FIB_RES_DEV(*res));
+ if (out_dev == NULL) {
+ if (net_ratelimit())
+ printk(KERN_CRIT "Bug in ip_route_input" \
+ "_slow(). Please, report\n");
+ return -EINVAL;
+ }
+
if (out_dev == in_dev && err && !(flags & (RTCF_NAT | RTCF_MASQ)) &&
(IN_DEV_SHARED_MEDIA(out_dev) ||
@@ -1708,36 +1725,13 @@
rth->rt_flags = flags;
-
- *result = rth;
err = 0;
- cleanup:
- /* release the working reference to the output device */
- in_dev_put(out_dev);
- return err;
-}
-
-static inline int ip_mkroute_input(struct sk_buff *skb,
- struct fib_result* res,
- const struct flowi *fl,
- struct in_device *in_dev,
- __be32 daddr, __be32 saddr, u32 tos)
-{
- struct rtable* rth = NULL;
- int err;
- unsigned hash;
-
-#ifdef CONFIG_IP_ROUTE_MULTIPATH
- if (res->fi && res->fi->fib_nhs > 1 && fl->oif == 0)
- fib_select_multipath(fl, res);
-#endif
-
- /* create a routing cache entry */
- err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth);
- if (err)
- return err;
/* put it into the cache */
hash = rt_hash(daddr, saddr, fl->iif);
return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
+ cleanup:
+ /* release the working reference to the output device */
+ in_dev_put(out_dev);
+ return err;
}
@@ -2305,5 +2299,5 @@
#ifdef CONFIG_IP_ROUTE_MULTIPATH
if (res.fi->fib_nhs > 1 && fl.oif == 0)
- fib_select_multipath(&fl, &res);
+ fib_select_multipath(&fl, &res, 0);
else
#endif
[-- Attachment #3: iproute.dsad.diff --]
[-- Type: text/plain, Size: 2107 bytes --]
diff -r -U2 iproute-20070313-dsc/include/linux/rtnetlink.h iproute-20070313-dsc-dsad/include/linux/rtnetlink.h
--- iproute-20070313-dsc/include/linux/rtnetlink.h 2007-03-13 17:50:56.000000000 -0400
+++ iproute-20070313-dsc-dsad/include/linux/rtnetlink.h 2007-12-06 19:56:50.000000000 -0500
@@ -295,4 +295,5 @@
#define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */
#define RTNH_F_ONLINK 4 /* Gateway is forced on link */
+#define RTNH_F_DSAD 8 /* Dynamic PBR (choose nh by src) */
/* Macros to handle hexthops */
Binary files iproute-20070313-dsc/ip/ip and iproute-20070313-dsc-dsad/ip/ip differ
diff -r -U2 iproute-20070313-dsc/ip/iproute.c iproute-20070313-dsc-dsad/ip/iproute.c
--- iproute-20070313-dsc/ip/iproute.c 2007-12-07 16:39:48.000000000 -0500
+++ iproute-20070313-dsc-dsad/ip/iproute.c 2007-12-06 19:57:01.000000000 -0500
@@ -70,5 +70,5 @@
fprintf(stderr, " [ mpath MP_ALGO ]\n");
fprintf(stderr, "INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]...\n");
- fprintf(stderr, "NH := [ via ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS\n");
+ fprintf(stderr, "NH := [ via ADDRESS ] [ dev STRING ] [ weight NUMBER | byrealm REALM ] NHFLAGS\n");
fprintf(stderr, "OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ]\n");
fprintf(stderr, " [ rtt NUMBER ] [ rttvar NUMBER ]\n");
@@ -583,5 +583,9 @@
} else {
fprintf(fp, " dev %s", ll_index_to_name(nh->rtnh_ifindex));
- fprintf(fp, " weight %d", nh->rtnh_hops+1);
+ if (nh->rtnh_flags & RTNH_F_DSAD) {
+ fprintf(fp, " byrealm %x", nh->rtnh_hops);
+ } else {
+ fprintf(fp, " weight %d", nh->rtnh_hops+1);
+ }
}
if (nh->rtnh_flags & RTNH_F_DEAD)
@@ -623,4 +627,11 @@
invarg("\"weight\" is invalid\n", *argv);
rtnh->rtnh_hops = w - 1;
+ } else if (strcmp(*argv, "byrealm") == 0) {
+ unsigned r;
+ NEXT_ARG();
+ if (get_unsigned(&r, *argv, 0) || r == 0 || r > 0x7fff)
+ invarg("\"byrealm\" is invalid\n", *argv);
+ rtnh->rtnh_hops = r;
+ rtnh->rtnh_flags |= RTNH_F_DSAD;
} else if (strcmp(*argv, "onlink") == 0) {
rtnh->rtnh_flags |= RTNH_F_ONLINK;
^ permalink raw reply
* Re: [PATCH] s2io: fix inconsistent hardware VLAN tagging during driver init
From: Jeff Garzik @ 2007-12-07 21:17 UTC (permalink / raw)
To: Ramkrishna Vepa
Cc: Andy Gospodarek, netdev, Rastapur Santosh, Sivakumar Subramani,
Sreenivasa Honnur
In-Reply-To: <78C9135A3D2ECE4B8162EBDCE82CAD7702A82C8C@nekter>
Ramkrishna Vepa wrote:
> Jeff,
> This patch looks good. Please accept.
>
> Ram
>> -----Original Message-----
>> From: Andy Gospodarek [mailto:andy@greyhouse.net]
>> Sent: Thursday, December 06, 2007 11:57 AM
>> To: netdev@vger.kernel.org
>> Cc: ram.vepa@neterion.com; Rastapur Santosh; Sivakumar Subramani;
>> Sreenivasa Honnur
>> Subject: [PATCH] s2io: fix inconsistent hardware VLAN tagging during
>> driver init
queued for my next patch run...
^ permalink raw reply
* Re: [PATCH] XFRM: RFC4303 compliant auditing
From: Paul Moore @ 2007-12-07 21:06 UTC (permalink / raw)
To: Eric Paris; +Cc: netdev, linux-audit
In-Reply-To: <1197060751.3183.22.camel@dhcp231-215.rdu.redhat.com>
On Friday 07 December 2007 3:52:31 pm Eric Paris wrote:
> On Fri, 2007-12-07 at 14:57 -0500, Paul Moore wrote:
> > NOTE: This really is an RFC patch, it compiles and boots but that is
> > pretty much all I can promise at this point. I'm posting this patch to
> > gather feedback from the audit crowd about the continued overloading of
> > the AUDIT_MAC_IPSEC_EVENT message type - continue to use it or create a
> > new audit message type? Of course any other comments people may have are
> > always welcome.
>
> I'm all for continuing to use it, but I feel like the op= strings should
> probably all get collected up in one place to ease maintenance in the
> future, might not matter but it's nice to be able to look only on place
> in the code to find all of the possible op=
Agreed. I punted on doing anything here for two main reasons:
1. It makes sense to do this in the xfrm_audit_start() function which I
couldn't use here without some overhaul ...
2. ... I didn't want to overhaul anything if I was going to end up using
separate message types.
If we decide to go with a single audit message type (kinda sounds like it)
I'll fix this up in the next version.
> The one advantage to multiple messages is the ability to exclude and not
> audit certain things. How often will these extra messages actually pop
> out of a system? Enough that people would likely still care about some
> of them but decide they don't want others? I don't know this stuff, so
> tell me how often would any of these show up?
Bingo, this is the whole reason why I was wondering about a different message
type. Currently only SAD and SPD changes are audited and only because they
effect the security labels that are assigned to packets as they are
imported/exported out of the system (look at the LSPP requirements for
auditing the import and export of data). These new audit messages apply to
individual packets and/or a particular SA and have nothing to do with
security labels, rather they indicate error conditions found during normal
IPsec processing. It would be difficult to think of all of the particular
cases where these error conditions but in general I would say that these
audit messages should not be common.
The only reason for creating a separate audit message type for these packet/SA
messages would be to meet a RFC requirement that states that the
implementation MUST allow the administrator to enable and disable ESP
auditing. Now, we can probably say we fulfill that requirement regardless,
but more message types allow us greater granularity and flexibility ...
--
paul moore
linux security @ hp
^ permalink raw reply
* RE: [PATCH] s2io: fix inconsistent hardware VLAN tagging during driver init
From: Ramkrishna Vepa @ 2007-12-07 21:02 UTC (permalink / raw)
To: Andy Gospodarek, netdev, Jeff Garzik
Cc: Rastapur Santosh, Sivakumar Subramani, Sreenivasa Honnur
In-Reply-To: <20071206195713.GA25879@gospo.usersys.redhat.com>
Jeff,
This patch looks good. Please accept.
Ram
> -----Original Message-----
> From: Andy Gospodarek [mailto:andy@greyhouse.net]
> Sent: Thursday, December 06, 2007 11:57 AM
> To: netdev@vger.kernel.org
> Cc: ram.vepa@neterion.com; Rastapur Santosh; Sivakumar Subramani;
> Sreenivasa Honnur
> Subject: [PATCH] s2io: fix inconsistent hardware VLAN tagging during
> driver init
>
>
> The s2io driver keeps a local variable around (vlan_strip_flag) to
keep
> track of the current state of the hardware and whether or not it will
> strip VLAN tags on incoming packets. It seems as though the hardware
> default is to strip them, but that variable is not set correctly
during
> initialization if the default setup is used. This check ensures
> vlan_strip_flag and the hardware setting are in sync.
>
> These variables were introduced by this patch:
>
> commit 926930b202d56c3dfb6aea0a0c6bfba2b87a8c03
> Author: Sivakumar Subramani <Sivakumar.Subramani@neterion.com>
> Date: Sat Feb 24 01:59:39 2007 -0500
>
> so this problem hasn't been around forever.
>
> Recent patches from Ramkrishna Vepa <ram.vepa@neterion.com> removed
this
> variable and would have worked around the problem, but they were not
> accepted.
>
> Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
>
> ---
>
> s2io.c | 5 +++++
> 1 files changed, 5 insertions(+)
>
> diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
> index 8b9f0ea..08c08de 100644
> --- a/drivers/net/s2io.c
> +++ b/drivers/net/s2io.c
> @@ -2151,6 +2151,11 @@ static int start_nic(struct s2io_nic *nic)
> val64 &= ~RX_PA_CFG_STRIP_VLAN_TAG;
> writeq(val64, &bar0->rx_pa_cfg);
> vlan_strip_flag = 0;
> + } else {
> + val64 = readq(&bar0->rx_pa_cfg);
> + val64 |= RX_PA_CFG_STRIP_VLAN_TAG;
> + writeq(val64, &bar0->rx_pa_cfg);
> + vlan_strip_flag = 1;
> }
>
> /*
^ permalink raw reply
* Re: [PATCH] XFRM: RFC4303 compliant auditing
From: Eric Paris @ 2007-12-07 20:52 UTC (permalink / raw)
To: Paul Moore; +Cc: netdev, linux-audit
In-Reply-To: <20071207195752.31819.44606.stgit@flek.americas.hpqcorp.net>
On Fri, 2007-12-07 at 14:57 -0500, Paul Moore wrote:
> NOTE: This really is an RFC patch, it compiles and boots but that is pretty
> much all I can promise at this point. I'm posting this patch to gather
> feedback from the audit crowd about the continued overloading of
> the AUDIT_MAC_IPSEC_EVENT message type - continue to use it or create
> a new audit message type? Of course any other comments people may have
> are always welcome.
I'm all for continuing to use it, but I feel like the op= strings should
probably all get collected up in one place to ease maintenance in the
future, might not matter but it's nice to be able to look only on place
in the code to find all of the possible op=
The one advantage to multiple messages is the ability to exclude and not
audit certain things. How often will these extra messages actually pop
out of a system? Enough that people would likely still care about some
of them but decide they don't want others? I don't know this stuff, so
tell me how often would any of these show up?
-Eric
>
> This patch adds a number of new IPsec audit events to meet the auditing
> requirements of RFC4303. This includes audit hooks for the following events:
>
> * Could not find a valid SA [sections 2.1, 3.4.2]
> . xfrm_audit_state_notfound()
> . xfrm_audit_state_notfound_simple()
>
> * Sequence number overflow [section 3.3.3]
> . xfrm_audit_state_replay_overflow()
>
> * Replayed packet [section 3.4.3]
> . xfrm_audit_state_replay()
>
> * Integrity check failure [sections 3.4.4.1, 3.4.4.2]
> . xfrm_audit_state_icvfail()
>
> While RFC4304 deals only with ESP most of the changes in this patch apply to
> IPsec in general, i.e. both AH and ESP. The one case, integrity check
> failure, where ESP specific code had to be modified the same was done to the
> AH code for the sake of consistency.
> ---
>
> include/net/xfrm.h | 14 ++++
> net/ipv4/ah4.c | 1
> net/ipv4/esp4.c | 1
> net/ipv4/xfrm4_input.c | 6 +-
> net/ipv6/ah6.c | 1
> net/ipv6/esp6.c | 1
> net/ipv6/xfrm6_input.c | 10 ++-
> net/xfrm/xfrm_output.c | 2 +
> net/xfrm/xfrm_state.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++--
> 9 files changed, 177 insertions(+), 14 deletions(-)
>
> diff --git a/include/net/xfrm.h b/include/net/xfrm.h
> index c02e230..85ce8c1 100644
> --- a/include/net/xfrm.h
> +++ b/include/net/xfrm.h
> @@ -492,11 +492,22 @@ extern void xfrm_audit_state_add(struct xfrm_state *x, int result,
> u32 auid, u32 secid);
> extern void xfrm_audit_state_delete(struct xfrm_state *x, int result,
> u32 auid, u32 secid);
> +extern void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
> + struct sk_buff *skb);
> +extern void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
> +extern void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
> + __be32 net_spi, __be32 net_seq);
> +extern void xfrm_audit_state_icvfail(struct xfrm_state *x,
> + struct sk_buff *skb, u8 proto);
> #else
> #define xfrm_audit_policy_add(x, r, a, s) do { ; } while (0)
> #define xfrm_audit_policy_delete(x, r, a, s) do { ; } while (0)
> #define xfrm_audit_state_add(x, r, a, s) do { ; } while (0)
> #define xfrm_audit_state_delete(x, r, a, s) do { ; } while (0)
> +#define xfrm_audit_state_replay_overflow(x, s) do { ; } while (0)
> +#define xfrm_audit_state_notfound_simple(s, f) do { ; } while (0)
> +#define xfrm_audit_state_notfound(s, f, sp, sq) do { ; } while (0)
> +#define xfrm_audit_state_icvfail(x, s, p) do { ; } while (0)
> #endif /* CONFIG_AUDITSYSCALL */
>
> static inline void xfrm_pol_hold(struct xfrm_policy *policy)
> @@ -1045,7 +1056,8 @@ extern int xfrm_state_delete(struct xfrm_state *x);
> extern int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
> extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si);
> extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si);
> -extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq);
> +extern int xfrm_replay_check(struct xfrm_state *x,
> + struct sk_buff *skb, __be32 seq);
> extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq);
> extern void xfrm_replay_notify(struct xfrm_state *x, int event);
> extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
> diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
> index 5fc346d..8eb19c9 100644
> --- a/net/ipv4/ah4.c
> +++ b/net/ipv4/ah4.c
> @@ -180,6 +180,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
> err = -EINVAL;
> if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
> x->stats.integrity_failed++;
> + xfrm_audit_state_icvfail(x, skb, IPPROTO_AH);
> goto out;
> }
> }
> diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
> index c31bccb..00ec285 100644
> --- a/net/ipv4/esp4.c
> +++ b/net/ipv4/esp4.c
> @@ -183,6 +183,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
>
> if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
> x->stats.integrity_failed++;
> + xfrm_audit_state_icvfail(x, skb, IPPROTO_ESP);
> goto out;
> }
> }
> diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
> index 5e95c8a..6d7be5e 100644
> --- a/net/ipv4/xfrm4_input.c
> +++ b/net/ipv4/xfrm4_input.c
> @@ -56,8 +56,10 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
>
> x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
> nexthdr, AF_INET);
> - if (x == NULL)
> + if (x == NULL) {
> + xfrm_audit_state_notfound(skb, AF_INET, spi, seq);
> goto drop;
> + }
>
> spin_lock(&x->lock);
> if (unlikely(x->km.state != XFRM_STATE_VALID))
> @@ -66,7 +68,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
> if ((x->encap ? x->encap->encap_type : 0) != encap_type)
> goto drop_unlock;
>
> - if (x->props.replay_window && xfrm_replay_check(x, seq))
> + if (x->props.replay_window && xfrm_replay_check(x, skb, seq))
> goto drop_unlock;
>
> if (xfrm_state_check_expire(x))
> diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
> index 4eaf550..b7d2e19 100644
> --- a/net/ipv6/ah6.c
> +++ b/net/ipv6/ah6.c
> @@ -383,6 +383,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
> if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
> LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n");
> x->stats.integrity_failed++;
> + xfrm_audit_state_icvfail(x, skb, IPPROTO_AH);
> goto free_out;
> }
> }
> diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
> index 7db66f1..d56db2b 100644
> --- a/net/ipv6/esp6.c
> +++ b/net/ipv6/esp6.c
> @@ -178,6 +178,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
>
> if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
> x->stats.integrity_failed++;
> + xfrm_audit_state_icvfail(x, skb, IPPROTO_ESP);
> ret = -EINVAL;
> goto out;
> }
> diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
> index 5157837..28c1e1b 100644
> --- a/net/ipv6/xfrm6_input.c
> +++ b/net/ipv6/xfrm6_input.c
> @@ -40,13 +40,15 @@ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
>
> x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
> nexthdr, AF_INET6);
> - if (x == NULL)
> + if (x == NULL) {
> + xfrm_audit_state_notfound(skb, AF_INET6, spi, seq);
> goto drop;
> + }
> spin_lock(&x->lock);
> if (unlikely(x->km.state != XFRM_STATE_VALID))
> goto drop_unlock;
>
> - if (x->props.replay_window && xfrm_replay_check(x, seq))
> + if (x->props.replay_window && xfrm_replay_check(x, skb, seq))
> goto drop_unlock;
>
> if (xfrm_state_check_expire(x))
> @@ -217,8 +219,10 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
> break;
> }
>
> - if (!xfrm_vec_one)
> + if (!xfrm_vec_one) {
> + xfrm_audit_state_notfound_simple(skb, AF_INET6);
> goto drop;
> + }
>
> /* Allocate new secpath or COW existing one. */
> if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
> diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
> index f4bfd6c..14ce897 100644
> --- a/net/xfrm/xfrm_output.c
> +++ b/net/xfrm/xfrm_output.c
> @@ -59,6 +59,8 @@ int xfrm_output(struct sk_buff *skb)
>
> if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
> XFRM_SKB_CB(skb)->seq = ++x->replay.oseq;
> + if (unlikely(x->replay.oseq == 0))
> + xfrm_audit_state_replay_overflow(x, skb);
> if (xfrm_aevent_is_on())
> xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
> }
> diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
> index b291a82..cfef149 100644
> --- a/net/xfrm/xfrm_state.c
> +++ b/net/xfrm/xfrm_state.c
> @@ -61,6 +61,13 @@ static unsigned int xfrm_state_genid;
> static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
> static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
>
> +#ifdef CONFIG_AUDITSYSCALL
> +static void xfrm_audit_state_replay(struct xfrm_state *x,
> + struct sk_buff *skb, __be32 net_seq);
> +#else
> +#define xfrm_audit_state_replay(x, s, sq) do { ; } while (0)
> +#endif /* CONFIG_AUDITSYSCALL */
> +
> static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr,
> xfrm_address_t *saddr,
> u32 reqid,
> @@ -1610,13 +1617,14 @@ static void xfrm_replay_timer_handler(unsigned long data)
> spin_unlock(&x->lock);
> }
>
> -int xfrm_replay_check(struct xfrm_state *x, __be32 net_seq)
> +int xfrm_replay_check(struct xfrm_state *x,
> + struct sk_buff *skb, __be32 net_seq)
> {
> u32 diff;
> u32 seq = ntohl(net_seq);
>
> if (unlikely(seq == 0))
> - return -EINVAL;
> + goto err;
>
> if (likely(seq > x->replay.seq))
> return 0;
> @@ -1625,14 +1633,18 @@ int xfrm_replay_check(struct xfrm_state *x, __be32 net_seq)
> if (diff >= min_t(unsigned int, x->props.replay_window,
> sizeof(x->replay.bitmap) * 8)) {
> x->stats.replay_window++;
> - return -EINVAL;
> + goto err;
> }
>
> if (x->replay.bitmap & (1U << diff)) {
> x->stats.replay++;
> - return -EINVAL;
> + goto err;
> }
> return 0;
> +
> +err:
> + xfrm_audit_state_replay(x, skb, net_seq);
> + return -EINVAL;
> }
> EXPORT_SYMBOL(xfrm_replay_check);
>
> @@ -1995,8 +2007,8 @@ void __init xfrm_state_init(void)
> }
>
> #ifdef CONFIG_AUDITSYSCALL
> -static inline void xfrm_audit_common_stateinfo(struct xfrm_state *x,
> - struct audit_buffer *audit_buf)
> +static inline void xfrm_audit_helper_sainfo(struct xfrm_state *x,
> + struct audit_buffer *audit_buf)
> {
> struct xfrm_sec_ctx *ctx = x->security;
> u32 spi = ntohl(x->id.spi);
> @@ -2023,6 +2035,34 @@ static inline void xfrm_audit_common_stateinfo(struct xfrm_state *x,
> audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
> }
>
> +static inline void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family,
> + struct audit_buffer *audit_buf)
> +{
> + struct iphdr *iph4;
> + struct ipv6hdr *iph6;
> +
> + switch (family) {
> + case AF_INET:
> + iph4 = ip_hdr(skb);
> + audit_log_format(audit_buf,
> + " src=" NIPQUAD_FMT " dst=" NIPQUAD_FMT,
> + NIPQUAD(iph4->saddr),
> + NIPQUAD(iph4->daddr));
> + break;
> + case AF_INET6:
> + iph6 = ipv6_hdr(skb);
> + audit_log_format(audit_buf,
> + " src=" NIP6_FMT " dst=" NIP6_FMT
> + " flowlbl=0x%x%x%x",
> + NIP6(iph6->saddr),
> + NIP6(iph6->daddr),
> + iph6->flow_lbl[0] & 0x0f,
> + iph6->flow_lbl[1],
> + iph6->flow_lbl[2]);
> + break;
> + }
> +}
> +
> void xfrm_audit_state_add(struct xfrm_state *x, int result,
> u32 auid, u32 secid)
> {
> @@ -2034,7 +2074,7 @@ void xfrm_audit_state_add(struct xfrm_state *x, int result,
> if (audit_buf == NULL)
> return;
> audit_log_format(audit_buf, " op=SAD-add res=%u", result);
> - xfrm_audit_common_stateinfo(x, audit_buf);
> + xfrm_audit_helper_sainfo(x, audit_buf);
> audit_log_end(audit_buf);
> }
> EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
> @@ -2050,8 +2090,107 @@ void xfrm_audit_state_delete(struct xfrm_state *x, int result,
> if (audit_buf == NULL)
> return;
> audit_log_format(audit_buf, " op=SAD-delete res=%u", result);
> - xfrm_audit_common_stateinfo(x, audit_buf);
> + xfrm_audit_helper_sainfo(x, audit_buf);
> audit_log_end(audit_buf);
> }
> EXPORT_SYMBOL_GPL(xfrm_audit_state_delete);
> +
> +void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
> + struct sk_buff *skb)
> +{
> + struct audit_buffer *audit_buf;
> + u32 spi = ntohl(x->id.spi);
> +
> + if (audit_enabled == 0)
> + return;
> + audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
> + AUDIT_MAC_IPSEC_EVENT);
> + if (audit_buf == NULL)
> + return;
> + audit_log_format(audit_buf, " op=SA-replay-overflow");
> + xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf);
> + /* don't record the sequence number because it's inherent in this kind
> + * of audit message */
> + audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
> + audit_log_end(audit_buf);
> +}
> +EXPORT_SYMBOL_GPL(xfrm_audit_state_replay_overflow);
> +
> +static void xfrm_audit_state_replay(struct xfrm_state *x,
> + struct sk_buff *skb, __be32 net_seq)
> +{
> + struct audit_buffer *audit_buf;
> + u32 spi = ntohl(x->id.spi);
> +
> + if (audit_enabled == 0)
> + return;
> + audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
> + AUDIT_MAC_IPSEC_EVENT);
> + if (audit_buf == NULL)
> + return;
> + audit_log_format(audit_buf, " op=SA-replayed-pkt");
> + xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf);
> + audit_log_format(audit_buf, " spi=%u(0x%x) seqno=%u",
> + spi, spi, ntohl(net_seq));
> + audit_log_end(audit_buf);
> +}
> +
> +void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family)
> +{
> + struct audit_buffer *audit_buf;
> +
> + if (audit_enabled == 0)
> + return;
> + audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
> + AUDIT_MAC_IPSEC_EVENT);
> + if (audit_buf == NULL)
> + return;
> + audit_log_format(audit_buf, " op=SA-notfound");
> + xfrm_audit_helper_pktinfo(skb, family, audit_buf);
> + audit_log_end(audit_buf);
> +}
> +EXPORT_SYMBOL_GPL(xfrm_audit_state_notfound_simple);
> +
> +void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
> + __be32 net_spi, __be32 net_seq)
> +{
> + struct audit_buffer *audit_buf;
> + u32 spi = ntohl(net_spi);
> +
> + if (audit_enabled == 0)
> + return;
> + audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
> + AUDIT_MAC_IPSEC_EVENT);
> + if (audit_buf == NULL)
> + return;
> + audit_log_format(audit_buf, " op=SA-notfound");
> + xfrm_audit_helper_pktinfo(skb, family, audit_buf);
> + audit_log_format(audit_buf, " spi=%u(0x%x) seqno=%u",
> + spi, spi, ntohl(net_seq));
> + audit_log_end(audit_buf);
> +}
> +EXPORT_SYMBOL_GPL(xfrm_audit_state_notfound);
> +
> +void xfrm_audit_state_icvfail(struct xfrm_state *x,
> + struct sk_buff *skb, u8 proto)
> +{
> + struct audit_buffer *audit_buf;
> + __be32 net_spi;
> + __be32 net_seq;
> + u32 spi;
> +
> + audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
> + AUDIT_MAC_IPSEC_EVENT);
> + if (audit_buf == NULL)
> + return;
> + audit_log_format(audit_buf, " op=SA-icv-failure");
> + xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf);
> + if (xfrm_parse_spi(skb, proto, &net_spi, &net_seq) == 0) {
> + spi = ntohl(net_spi);
> + audit_log_format(audit_buf, " spi=%u(0x%x) seqno=%u",
> + spi, spi, ntohl(net_seq));
> + }
> + audit_log_end(audit_buf);
> +}
> +EXPORT_SYMBOL_GPL(xfrm_audit_state_icvfail);
> #endif /* CONFIG_AUDITSYSCALL */
>
> --
> Linux-audit mailing list
> Linux-audit@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit
^ permalink raw reply
* Re: [PATCH] XFRM: assorted IPsec fixups
From: Paul Moore @ 2007-12-07 20:45 UTC (permalink / raw)
To: Eric Paris; +Cc: netdev, linux-audit, selinux
In-Reply-To: <1197059769.3183.16.camel@dhcp231-215.rdu.redhat.com>
On Friday 07 December 2007 3:36:08 pm Eric Paris wrote:
> On Fri, 2007-12-07 at 12:11 -0500, Paul Moore wrote:
> > This patch fixes a number of small but potentially troublesome things in
> > the XFRM/IPsec code:
> >
> > * Use the 'audit_enabled' variable already in include/linux/audit.h
> > Removed the need for extern declarations local to each XFRM audit
> > fuction
{snip}
> although it does make me wonder why audit_log_start doesn't just check
> audit_enabled itself....
/me shrugs ... I have no idea, I've just always followed the lead of what was
already written, but now that you mention it - it doesn't make much sense. I
suppose at some point we can go through and change all the 'audit_enabled'
users, but I wonder if there is some point (?performance?) to having the
callers check?
--
paul moore
linux security @ hp
^ permalink raw reply
* Re: [PATCH] XFRM: assorted IPsec fixups
From: Eric Paris @ 2007-12-07 20:36 UTC (permalink / raw)
To: Paul Moore; +Cc: netdev, linux-audit, selinux
In-Reply-To: <20071207171116.18151.42328.stgit@flek.americas.hpqcorp.net>
On Fri, 2007-12-07 at 12:11 -0500, Paul Moore wrote:
> This patch fixes a number of small but potentially troublesome things in the
> XFRM/IPsec code:
>
> * Use the 'audit_enabled' variable already in include/linux/audit.h
> Removed the need for extern declarations local to each XFRM audit fuction
>
> * Convert 'sid' to 'secid'
> The 'sid' name is specific to SELinux, 'secid' is the common naming
> convention used by the kernel when refering to tokenized LSM labels
>
> * Convert address display to use standard NIP* macros
> Similar to what was recently done with the SPD audit code, this also
> includes the removal of some unnecessary memcpy() calls
>
> * Move common code to xfrm_audit_common_stateinfo()
> Code consolidation from the "less is more" book on software development
>
> * Convert the SPI in audit records to host byte order
> The current SPI values in the audit record are being displayed in
> network byte order, probably not what was intended
>
> * Proper spacing around commas in function arguments
> Minor style tweak since I was already touching the code
>
> Signed-off-by: Paul Moore <paul.moore@hp.com>
Acked-by: Eric Paris <eparis@redhat.com>
although it does make me wonder why audit_log_start doesn't just check
audit_enabled itself.... Anyway, this patch looks good.
> ---
>
> include/linux/xfrm.h | 2 +
> include/net/xfrm.h | 18 ++++++------
> net/xfrm/xfrm_policy.c | 15 +++++-----
> net/xfrm/xfrm_state.c | 69 +++++++++++++++++++++--------------------------
> security/selinux/xfrm.c | 20 +++++++-------
> 5 files changed, 58 insertions(+), 66 deletions(-)
>
> diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
> index b58adc5..f75a337 100644
> --- a/include/linux/xfrm.h
> +++ b/include/linux/xfrm.h
> @@ -31,7 +31,7 @@ struct xfrm_sec_ctx {
> __u8 ctx_doi;
> __u8 ctx_alg;
> __u16 ctx_len;
> - __u32 ctx_sid;
> + __u32 ctx_secid;
> char ctx_str[0];
> };
>
> diff --git a/include/net/xfrm.h b/include/net/xfrm.h
> index 58dfa82..c02e230 100644
> --- a/include/net/xfrm.h
> +++ b/include/net/xfrm.h
> @@ -462,7 +462,7 @@ struct xfrm_audit
> };
>
> #ifdef CONFIG_AUDITSYSCALL
> -static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
> +static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 secid)
> {
> struct audit_buffer *audit_buf = NULL;
> char *secctx;
> @@ -475,8 +475,8 @@ static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
>
> audit_log_format(audit_buf, "auid=%u", auid);
>
> - if (sid != 0 &&
> - security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) {
> + if (secid != 0 &&
> + security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) {
> audit_log_format(audit_buf, " subj=%s", secctx);
> security_release_secctx(secctx, secctx_len);
> } else
> @@ -485,13 +485,13 @@ static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
> }
>
> extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
> - u32 auid, u32 sid);
> + u32 auid, u32 secid);
> extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
> - u32 auid, u32 sid);
> + u32 auid, u32 secid);
> extern void xfrm_audit_state_add(struct xfrm_state *x, int result,
> - u32 auid, u32 sid);
> + u32 auid, u32 secid);
> extern void xfrm_audit_state_delete(struct xfrm_state *x, int result,
> - u32 auid, u32 sid);
> + u32 auid, u32 secid);
> #else
> #define xfrm_audit_policy_add(x, r, a, s) do { ; } while (0)
> #define xfrm_audit_policy_delete(x, r, a, s) do { ; } while (0)
> @@ -621,13 +621,13 @@ extern int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
>
> #ifdef CONFIG_SECURITY_NETWORK_XFRM
> /* If neither has a context --> match
> - * Otherwise, both must have a context and the sids, doi, alg must match
> + * Otherwise, both must have a context and the secids, doi, alg must match
> */
> static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
> {
> return ((!s1 && !s2) ||
> (s1 && s2 &&
> - (s1->ctx_sid == s2->ctx_sid) &&
> + (s1->ctx_secid == s2->ctx_secid) &&
> (s1->ctx_doi == s2->ctx_doi) &&
> (s1->ctx_alg == s2->ctx_alg)));
> }
> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
> index b702bd8..75f25c4 100644
> --- a/net/xfrm/xfrm_policy.c
> +++ b/net/xfrm/xfrm_policy.c
> @@ -23,6 +23,7 @@
> #include <linux/netfilter.h>
> #include <linux/module.h>
> #include <linux/cache.h>
> +#include <linux/audit.h>
> #include <net/xfrm.h>
> #include <net/ip.h>
>
> @@ -2150,15 +2151,14 @@ static inline void xfrm_audit_common_policyinfo(struct xfrm_policy *xp,
> }
> }
>
> -void
> -xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
> +void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
> + u32 auid, u32 secid)
> {
> struct audit_buffer *audit_buf;
> - extern int audit_enabled;
>
> if (audit_enabled == 0)
> return;
> - audit_buf = xfrm_audit_start(sid, auid);
> + audit_buf = xfrm_audit_start(secid, auid);
> if (audit_buf == NULL)
> return;
> audit_log_format(audit_buf, " op=SPD-add res=%u", result);
> @@ -2167,15 +2167,14 @@ xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
> }
> EXPORT_SYMBOL_GPL(xfrm_audit_policy_add);
>
> -void
> -xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
> +void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
> + u32 auid, u32 secid)
> {
> struct audit_buffer *audit_buf;
> - extern int audit_enabled;
>
> if (audit_enabled == 0)
> return;
> - audit_buf = xfrm_audit_start(sid, auid);
> + audit_buf = xfrm_audit_start(secid, auid);
> if (audit_buf == NULL)
> return;
> audit_log_format(audit_buf, " op=SPD-delete res=%u", result);
> diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
> index cf43c49..b291a82 100644
> --- a/net/xfrm/xfrm_state.c
> +++ b/net/xfrm/xfrm_state.c
> @@ -19,6 +19,7 @@
> #include <linux/ipsec.h>
> #include <linux/module.h>
> #include <linux/cache.h>
> +#include <linux/audit.h>
> #include <asm/uaccess.h>
>
> #include "xfrm_hash.h"
> @@ -1997,67 +1998,59 @@ void __init xfrm_state_init(void)
> static inline void xfrm_audit_common_stateinfo(struct xfrm_state *x,
> struct audit_buffer *audit_buf)
> {
> - if (x->security)
> - audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
> - x->security->ctx_alg, x->security->ctx_doi,
> - x->security->ctx_str);
> + struct xfrm_sec_ctx *ctx = x->security;
> + u32 spi = ntohl(x->id.spi);
>
> - switch(x->props.family) {
> - case AF_INET:
> - audit_log_format(audit_buf, " src=%u.%u.%u.%u dst=%u.%u.%u.%u",
> - NIPQUAD(x->props.saddr.a4),
> - NIPQUAD(x->id.daddr.a4));
> - break;
> - case AF_INET6:
> - {
> - struct in6_addr saddr6, daddr6;
> -
> - memcpy(&saddr6, x->props.saddr.a6,
> - sizeof(struct in6_addr));
> - memcpy(&daddr6, x->id.daddr.a6,
> - sizeof(struct in6_addr));
> - audit_log_format(audit_buf,
> - " src=" NIP6_FMT " dst=" NIP6_FMT,
> - NIP6(saddr6), NIP6(daddr6));
> - }
> - break;
> - }
> + if (ctx)
> + audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
> + ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str);
> +
> + switch(x->props.family) {
> + case AF_INET:
> + audit_log_format(audit_buf,
> + " src=" NIPQUAD_FMT " dst=" NIPQUAD_FMT,
> + NIPQUAD(x->props.saddr.a4),
> + NIPQUAD(x->id.daddr.a4));
> + break;
> + case AF_INET6:
> + audit_log_format(audit_buf,
> + " src=" NIP6_FMT " dst=" NIP6_FMT,
> + NIP6(*(struct in6_addr *)x->props.saddr.a6),
> + NIP6(*(struct in6_addr *)x->id.daddr.a6));
> + break;
> + }
> +
> + audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
> }
>
> -void
> -xfrm_audit_state_add(struct xfrm_state *x, int result, u32 auid, u32 sid)
> +void xfrm_audit_state_add(struct xfrm_state *x, int result,
> + u32 auid, u32 secid)
> {
> struct audit_buffer *audit_buf;
> - extern int audit_enabled;
>
> if (audit_enabled == 0)
> return;
> - audit_buf = xfrm_audit_start(sid, auid);
> + audit_buf = xfrm_audit_start(secid, auid);
> if (audit_buf == NULL)
> return;
> - audit_log_format(audit_buf, " op=SAD-add res=%u",result);
> + audit_log_format(audit_buf, " op=SAD-add res=%u", result);
> xfrm_audit_common_stateinfo(x, audit_buf);
> - audit_log_format(audit_buf, " spi=%lu(0x%lx)",
> - (unsigned long)x->id.spi, (unsigned long)x->id.spi);
> audit_log_end(audit_buf);
> }
> EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
>
> -void
> -xfrm_audit_state_delete(struct xfrm_state *x, int result, u32 auid, u32 sid)
> +void xfrm_audit_state_delete(struct xfrm_state *x, int result,
> + u32 auid, u32 secid)
> {
> struct audit_buffer *audit_buf;
> - extern int audit_enabled;
>
> if (audit_enabled == 0)
> return;
> - audit_buf = xfrm_audit_start(sid, auid);
> + audit_buf = xfrm_audit_start(secid, auid);
> if (audit_buf == NULL)
> return;
> - audit_log_format(audit_buf, " op=SAD-delete res=%u",result);
> + audit_log_format(audit_buf, " op=SAD-delete res=%u", result);
> xfrm_audit_common_stateinfo(x, audit_buf);
> - audit_log_format(audit_buf, " spi=%lu(0x%lx)",
> - (unsigned long)x->id.spi, (unsigned long)x->id.spi);
> audit_log_end(audit_buf);
> }
> EXPORT_SYMBOL_GPL(xfrm_audit_state_delete);
> diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
> index e076039..c925880 100644
> --- a/security/selinux/xfrm.c
> +++ b/security/selinux/xfrm.c
> @@ -85,7 +85,7 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
> if (!selinux_authorizable_ctx(ctx))
> return -EINVAL;
>
> - sel_sid = ctx->ctx_sid;
> + sel_sid = ctx->ctx_secid;
> }
> else
> /*
> @@ -132,7 +132,7 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
> /* Not a SELinux-labeled SA */
> return 0;
>
> - state_sid = x->security->ctx_sid;
> + state_sid = x->security->ctx_secid;
>
> if (fl->secid != state_sid)
> return 0;
> @@ -175,13 +175,13 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
> struct xfrm_sec_ctx *ctx = x->security;
>
> if (!sid_set) {
> - *sid = ctx->ctx_sid;
> + *sid = ctx->ctx_secid;
> sid_set = 1;
>
> if (!ckall)
> break;
> }
> - else if (*sid != ctx->ctx_sid)
> + else if (*sid != ctx->ctx_secid)
> return -EINVAL;
> }
> }
> @@ -232,7 +232,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
> ctx->ctx_str[str_len] = 0;
> rc = security_context_to_sid(ctx->ctx_str,
> str_len,
> - &ctx->ctx_sid);
> + &ctx->ctx_secid);
>
> if (rc)
> goto out;
> @@ -240,7 +240,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
> /*
> * Does the subject have permission to set security context?
> */
> - rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
> + rc = avc_has_perm(tsec->sid, ctx->ctx_secid,
> SECCLASS_ASSOCIATION,
> ASSOCIATION__SETCONTEXT, NULL);
> if (rc)
> @@ -264,7 +264,7 @@ not_from_user:
>
> ctx->ctx_doi = XFRM_SC_DOI_LSM;
> ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
> - ctx->ctx_sid = sid;
> + ctx->ctx_secid = sid;
> ctx->ctx_len = str_len;
> memcpy(ctx->ctx_str,
> ctx_str,
> @@ -341,7 +341,7 @@ int selinux_xfrm_policy_delete(struct xfrm_policy *xp)
> int rc = 0;
>
> if (ctx)
> - rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
> + rc = avc_has_perm(tsec->sid, ctx->ctx_secid,
> SECCLASS_ASSOCIATION,
> ASSOCIATION__SETCONTEXT, NULL);
>
> @@ -383,7 +383,7 @@ int selinux_xfrm_state_delete(struct xfrm_state *x)
> int rc = 0;
>
> if (ctx)
> - rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
> + rc = avc_has_perm(tsec->sid, ctx->ctx_secid,
> SECCLASS_ASSOCIATION,
> ASSOCIATION__SETCONTEXT, NULL);
>
> @@ -412,7 +412,7 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
>
> if (x && selinux_authorizable_xfrm(x)) {
> struct xfrm_sec_ctx *ctx = x->security;
> - sel_sid = ctx->ctx_sid;
> + sel_sid = ctx->ctx_secid;
> break;
> }
> }
>
> --
> Linux-audit mailing list
> Linux-audit@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit
^ permalink raw reply
* [git patches] net driver fixes
From: Jeff Garzik @ 2007-12-07 20:31 UTC (permalink / raw)
To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML
Nothing remarkable. Mainly bonding fixes and bringing ibm_newemac up to
snuff.
Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus
to receive the following updates:
Documentation/networking/bonding.txt | 29 ++++++++-
arch/powerpc/boot/dts/sequoia.dts | 5 ++
drivers/net/Kconfig | 1 +
drivers/net/bonding/bond_main.c | 116 +++++++++++++++++++++-------------
drivers/net/bonding/bond_sysfs.c | 94 +++++++++-------------------
drivers/net/bonding/bonding.h | 4 +-
drivers/net/cxgb3/regs.h | 27 ++++++++-
drivers/net/cxgb3/t3_hw.c | 6 +-
drivers/net/cxgb3/xgmac.c | 44 +++++++++-----
drivers/net/e100.c | 6 +-
drivers/net/e1000/e1000_ethtool.c | 2 +-
drivers/net/e1000e/ethtool.c | 2 +-
drivers/net/ibm_newemac/core.c | 56 +++++++++++-----
drivers/net/ibm_newemac/core.h | 11 +++-
drivers/net/ibm_newemac/debug.c | 5 ++
drivers/net/ibm_newemac/debug.h | 5 ++
drivers/net/ibm_newemac/emac.h | 5 ++
drivers/net/ibm_newemac/mal.c | 5 ++
drivers/net/ibm_newemac/mal.h | 5 ++
drivers/net/ibm_newemac/phy.c | 81 +++++++++++++++++++++++
drivers/net/ibm_newemac/phy.h | 5 ++
drivers/net/ibm_newemac/rgmii.c | 25 +++++---
drivers/net/ibm_newemac/rgmii.h | 10 +++-
drivers/net/ibm_newemac/tah.c | 8 ++-
drivers/net/ibm_newemac/tah.h | 5 ++
drivers/net/ibm_newemac/zmii.c | 9 +++-
drivers/net/ibm_newemac/zmii.h | 5 ++
drivers/net/s2io-regs.h | 1 +
drivers/net/s2io.c | 16 +++++-
include/linux/if_bonding.h | 3 +-
30 files changed, 423 insertions(+), 173 deletions(-)
Auke Kok (1):
e100: cleanup unneeded math
Benjamin Herrenschmidt (5):
ibm_newemac: Fix ZMII refcounting bug
ibm_newemac: Workaround reset timeout when no link
ibm_newemac: Cleanup/Fix RGMII MDIO support detection
ibm_newemac: Cleanup/fix support for STACR register variants
ibm_newemac: Update file headers copyright notices
David Sterba (1):
bonding: Fix time comparison
Divy Le Ray (1):
cxgb3 - T3C support update
Eliezer Tamir (1):
make bnx2x select ZLIB_INFLATE
Hugh Blemings (1):
ibm_newemac: Skip EMACs that are marked unused by the firmware
Jay Vosburgh (2):
bonding: Add new layer2+3 hash for xor/802.3ad modes
bonding: Fix race at module unload
Roel Kluin (1):
e1000: fix memcpy in e1000_get_strings
Sreenivasa Honnur (1):
S2io: Check for register initialization completion before accesing device registers
Stefan Roese (2):
ibm_newemac: Add BCM5248 and Marvell 88E1111 PHY support
ibm_newemac: Add ET1011c PHY support
Valentine Barshak (3):
ibm_newemac: Correct opb_bus_freq value
ibm_newemac: Fix typo reading TAH channel info
ibm_newemac: Call dev_set_drvdata() before tah_reset()
Wagner Ferenc (5):
bonding: Remove trailing NULs from sysfs interface.
bonding: Return nothing for not applicable values
bonding: Purely cosmetic: rename a local variable
bonding: Coding style: break line after the if condition
bonding: Allow setting and querying xmit policy regardless of mode
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index 1134062..6cc30e0 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -554,6 +554,30 @@ xmit_hash_policy
This algorithm is 802.3ad compliant.
+ layer2+3
+
+ This policy uses a combination of layer2 and layer3
+ protocol information to generate the hash.
+
+ Uses XOR of hardware MAC addresses and IP addresses to
+ generate the hash. The formula is
+
+ (((source IP XOR dest IP) AND 0xffff) XOR
+ ( source MAC XOR destination MAC ))
+ modulo slave count
+
+ This algorithm will place all traffic to a particular
+ network peer on the same slave. For non-IP traffic,
+ the formula is the same as for the layer2 transmit
+ hash policy.
+
+ This policy is intended to provide a more balanced
+ distribution of traffic than layer2 alone, especially
+ in environments where a layer3 gateway device is
+ required to reach most destinations.
+
+ This algorithm is 802.3ad complient.
+
layer3+4
This policy uses upper layer protocol information,
@@ -589,8 +613,9 @@ xmit_hash_policy
or may not tolerate this noncompliance.
The default value is layer2. This option was added in bonding
-version 2.6.3. In earlier versions of bonding, this parameter does
-not exist, and the layer2 policy is the only policy.
+ version 2.6.3. In earlier versions of bonding, this parameter
+ does not exist, and the layer2 policy is the only policy. The
+ layer2+3 value was added for bonding version 3.2.2.
3. Configuring Bonding Devices
diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts
index 8833dfe..10784ff 100644
--- a/arch/powerpc/boot/dts/sequoia.dts
+++ b/arch/powerpc/boot/dts/sequoia.dts
@@ -245,6 +245,7 @@
device_type = "rgmii-interface";
compatible = "ibm,rgmii-440epx", "ibm,rgmii";
reg = <ef601000 8>;
+ has-mdio;
};
EMAC0: ethernet@ef600e00 {
@@ -273,6 +274,8 @@
zmii-channel = <0>;
rgmii-device = <&RGMII0>;
rgmii-channel = <0>;
+ has-inverted-stacr-oc;
+ has-new-stacr-staopc;
};
EMAC1: ethernet@ef600f00 {
@@ -301,6 +304,8 @@
zmii-channel = <1>;
rgmii-device = <&RGMII0>;
rgmii-channel = <1>;
+ has-inverted-stacr-oc;
+ has-new-stacr-staopc;
};
};
};
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index d9107e5..6cde4ed 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2588,6 +2588,7 @@ config MLX4_DEBUG
config TEHUTI
tristate "Tehuti Networks 10G Ethernet"
depends on PCI
+ select ZLIB_INFLATE
help
Tehuti Networks 10G Ethernet NIC
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 423298c..b0b2603 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -74,6 +74,7 @@
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/if_bonding.h>
+#include <linux/jiffies.h>
#include <net/route.h>
#include <net/net_namespace.h>
#include "bonding.h"
@@ -174,6 +175,7 @@ struct bond_parm_tbl bond_mode_tbl[] = {
struct bond_parm_tbl xmit_hashtype_tbl[] = {
{ "layer2", BOND_XMIT_POLICY_LAYER2},
{ "layer3+4", BOND_XMIT_POLICY_LAYER34},
+{ "layer2+3", BOND_XMIT_POLICY_LAYER23},
{ NULL, -1},
};
@@ -2722,8 +2724,8 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
*/
bond_for_each_slave(bond, slave, i) {
if (slave->link != BOND_LINK_UP) {
- if (((jiffies - slave->dev->trans_start) <= delta_in_ticks) &&
- ((jiffies - slave->dev->last_rx) <= delta_in_ticks)) {
+ if (time_before_eq(jiffies, slave->dev->trans_start + delta_in_ticks) &&
+ time_before_eq(jiffies, slave->dev->last_rx + delta_in_ticks)) {
slave->link = BOND_LINK_UP;
slave->state = BOND_STATE_ACTIVE;
@@ -2754,8 +2756,8 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
* when the source ip is 0, so don't take the link down
* if we don't know our ip yet
*/
- if (((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) ||
- (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) &&
+ if (time_after_eq(jiffies, slave->dev->trans_start + 2*delta_in_ticks) ||
+ (time_after_eq(jiffies, slave->dev->last_rx + 2*delta_in_ticks) &&
bond_has_ip(bond))) {
slave->link = BOND_LINK_DOWN;
@@ -2848,8 +2850,8 @@ void bond_activebackup_arp_mon(struct work_struct *work)
*/
bond_for_each_slave(bond, slave, i) {
if (slave->link != BOND_LINK_UP) {
- if ((jiffies - slave_last_rx(bond, slave)) <=
- delta_in_ticks) {
+ if (time_before_eq(jiffies,
+ slave_last_rx(bond, slave) + delta_in_ticks)) {
slave->link = BOND_LINK_UP;
@@ -2858,7 +2860,7 @@ void bond_activebackup_arp_mon(struct work_struct *work)
write_lock_bh(&bond->curr_slave_lock);
if ((!bond->curr_active_slave) &&
- ((jiffies - slave->dev->trans_start) <= delta_in_ticks)) {
+ time_before_eq(jiffies, slave->dev->trans_start + delta_in_ticks)) {
bond_change_active_slave(bond, slave);
bond->current_arp_slave = NULL;
} else if (bond->curr_active_slave != slave) {
@@ -2897,7 +2899,7 @@ void bond_activebackup_arp_mon(struct work_struct *work)
if ((slave != bond->curr_active_slave) &&
(!bond->current_arp_slave) &&
- (((jiffies - slave_last_rx(bond, slave)) >= 3*delta_in_ticks) &&
+ (time_after_eq(jiffies, slave_last_rx(bond, slave) + 3*delta_in_ticks) &&
bond_has_ip(bond))) {
/* a backup slave has gone down; three times
* the delta allows the current slave to be
@@ -2943,10 +2945,10 @@ void bond_activebackup_arp_mon(struct work_struct *work)
* before being taken out. if a primary is being used, check
* if it is up and needs to take over as the curr_active_slave
*/
- if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) ||
- (((jiffies - slave_last_rx(bond, slave)) >= (2*delta_in_ticks)) &&
- bond_has_ip(bond))) &&
- ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) {
+ if ((time_after_eq(jiffies, slave->dev->trans_start + 2*delta_in_ticks) ||
+ (time_after_eq(jiffies, slave_last_rx(bond, slave) + 2*delta_in_ticks) &&
+ bond_has_ip(bond))) &&
+ time_after_eq(jiffies, slave->jiffies + 2*delta_in_ticks)) {
slave->link = BOND_LINK_DOWN;
@@ -3604,6 +3606,24 @@ void bond_unregister_arp(struct bonding *bond)
/*---------------------------- Hashing Policies -----------------------------*/
/*
+ * Hash for the output device based upon layer 2 and layer 3 data. If
+ * the packet is not IP mimic bond_xmit_hash_policy_l2()
+ */
+static int bond_xmit_hash_policy_l23(struct sk_buff *skb,
+ struct net_device *bond_dev, int count)
+{
+ struct ethhdr *data = (struct ethhdr *)skb->data;
+ struct iphdr *iph = ip_hdr(skb);
+
+ if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^
+ (data->h_dest[5] ^ bond_dev->dev_addr[5])) % count;
+ }
+
+ return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
+}
+
+/*
* Hash for the output device based upon layer 3 and layer 4 data. If
* the packet is a frag or not TCP or UDP, just use layer 3 data. If it is
* altogether not IP, mimic bond_xmit_hash_policy_l2()
@@ -4305,6 +4325,22 @@ out:
/*------------------------- Device initialization ---------------------------*/
+static void bond_set_xmit_hash_policy(struct bonding *bond)
+{
+ switch (bond->params.xmit_policy) {
+ case BOND_XMIT_POLICY_LAYER23:
+ bond->xmit_hash_policy = bond_xmit_hash_policy_l23;
+ break;
+ case BOND_XMIT_POLICY_LAYER34:
+ bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
+ break;
+ case BOND_XMIT_POLICY_LAYER2:
+ default:
+ bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
+ break;
+ }
+}
+
/*
* set bond mode specific net device operations
*/
@@ -4321,10 +4357,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
break;
case BOND_MODE_XOR:
bond_dev->hard_start_xmit = bond_xmit_xor;
- if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34)
- bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
- else
- bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
+ bond_set_xmit_hash_policy(bond);
break;
case BOND_MODE_BROADCAST:
bond_dev->hard_start_xmit = bond_xmit_broadcast;
@@ -4332,10 +4365,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
case BOND_MODE_8023AD:
bond_set_master_3ad_flags(bond);
bond_dev->hard_start_xmit = bond_3ad_xmit_xor;
- if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34)
- bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
- else
- bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
+ bond_set_xmit_hash_policy(bond);
break;
case BOND_MODE_ALB:
bond_set_master_alb_flags(bond);
@@ -4462,6 +4492,27 @@ static void bond_deinit(struct net_device *bond_dev)
#endif
}
+static void bond_work_cancel_all(struct bonding *bond)
+{
+ write_lock_bh(&bond->lock);
+ bond->kill_timers = 1;
+ write_unlock_bh(&bond->lock);
+
+ if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
+ cancel_delayed_work(&bond->mii_work);
+
+ if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
+ cancel_delayed_work(&bond->arp_work);
+
+ if (bond->params.mode == BOND_MODE_ALB &&
+ delayed_work_pending(&bond->alb_work))
+ cancel_delayed_work(&bond->alb_work);
+
+ if (bond->params.mode == BOND_MODE_8023AD &&
+ delayed_work_pending(&bond->ad_work))
+ cancel_delayed_work(&bond->ad_work);
+}
+
/* Unregister and free all bond devices.
* Caller must hold rtnl_lock.
*/
@@ -4472,6 +4523,7 @@ static void bond_free_all(void)
list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
struct net_device *bond_dev = bond->dev;
+ bond_work_cancel_all(bond);
bond_mc_list_destroy(bond);
/* Release the bonded slaves */
bond_release_all(bond_dev);
@@ -4497,8 +4549,7 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
for (i = 0; tbl[i].modename; i++) {
if ((isdigit(*mode_arg) &&
tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) ||
- (strncmp(mode_arg, tbl[i].modename,
- strlen(tbl[i].modename)) == 0)) {
+ (strcmp(mode_arg, tbl[i].modename) == 0)) {
return tbl[i].mode;
}
}
@@ -4873,27 +4924,6 @@ out_rtnl:
return res;
}
-static void bond_work_cancel_all(struct bonding *bond)
-{
- write_lock_bh(&bond->lock);
- bond->kill_timers = 1;
- write_unlock_bh(&bond->lock);
-
- if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
- cancel_delayed_work(&bond->mii_work);
-
- if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
- cancel_delayed_work(&bond->arp_work);
-
- if (bond->params.mode == BOND_MODE_ALB &&
- delayed_work_pending(&bond->alb_work))
- cancel_delayed_work(&bond->alb_work);
-
- if (bond->params.mode == BOND_MODE_8023AD &&
- delayed_work_pending(&bond->ad_work))
- cancel_delayed_work(&bond->ad_work);
-}
-
static int __init bonding_init(void)
{
int i;
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index b29330d..11b76b3 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -74,7 +74,7 @@ struct rw_semaphore bonding_rwsem;
* "show" function for the bond_masters attribute.
* The class parameter is ignored.
*/
-static ssize_t bonding_show_bonds(struct class *cls, char *buffer)
+static ssize_t bonding_show_bonds(struct class *cls, char *buf)
{
int res = 0;
struct bonding *bond;
@@ -86,14 +86,13 @@ static ssize_t bonding_show_bonds(struct class *cls, char *buffer)
/* not enough space for another interface name */
if ((PAGE_SIZE - res) > 10)
res = PAGE_SIZE - 10;
- res += sprintf(buffer + res, "++more++");
+ res += sprintf(buf + res, "++more++ ");
break;
}
- res += sprintf(buffer + res, "%s ",
- bond->dev->name);
+ res += sprintf(buf + res, "%s ", bond->dev->name);
}
- res += sprintf(buffer + res, "\n");
- res++;
+ if (res)
+ buf[res-1] = '\n'; /* eat the leftover space */
up_read(&(bonding_rwsem));
return res;
}
@@ -235,14 +234,14 @@ static ssize_t bonding_show_slaves(struct device *d,
/* not enough space for another interface name */
if ((PAGE_SIZE - res) > 10)
res = PAGE_SIZE - 10;
- res += sprintf(buf + res, "++more++");
+ res += sprintf(buf + res, "++more++ ");
break;
}
res += sprintf(buf + res, "%s ", slave->dev->name);
}
read_unlock(&bond->lock);
- res += sprintf(buf + res, "\n");
- res++;
+ if (res)
+ buf[res-1] = '\n'; /* eat the leftover space */
return res;
}
@@ -406,7 +405,7 @@ static ssize_t bonding_show_mode(struct device *d,
return sprintf(buf, "%s %d\n",
bond_mode_tbl[bond->params.mode].modename,
- bond->params.mode) + 1;
+ bond->params.mode);
}
static ssize_t bonding_store_mode(struct device *d,
@@ -457,20 +456,11 @@ static ssize_t bonding_show_xmit_hash(struct device *d,
struct device_attribute *attr,
char *buf)
{
- int count;
struct bonding *bond = to_bond(d);
- if ((bond->params.mode != BOND_MODE_XOR) &&
- (bond->params.mode != BOND_MODE_8023AD)) {
- // Not Applicable
- count = sprintf(buf, "NA\n") + 1;
- } else {
- count = sprintf(buf, "%s %d\n",
- xmit_hashtype_tbl[bond->params.xmit_policy].modename,
- bond->params.xmit_policy) + 1;
- }
-
- return count;
+ return sprintf(buf, "%s %d\n",
+ xmit_hashtype_tbl[bond->params.xmit_policy].modename,
+ bond->params.xmit_policy);
}
static ssize_t bonding_store_xmit_hash(struct device *d,
@@ -488,15 +478,6 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
goto out;
}
- if ((bond->params.mode != BOND_MODE_XOR) &&
- (bond->params.mode != BOND_MODE_8023AD)) {
- printk(KERN_ERR DRV_NAME
- "%s: Transmit hash policy is irrelevant in this mode.\n",
- bond->dev->name);
- ret = -EPERM;
- goto out;
- }
-
new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl);
if (new_value < 0) {
printk(KERN_ERR DRV_NAME
@@ -527,7 +508,7 @@ static ssize_t bonding_show_arp_validate(struct device *d,
return sprintf(buf, "%s %d\n",
arp_validate_tbl[bond->params.arp_validate].modename,
- bond->params.arp_validate) + 1;
+ bond->params.arp_validate);
}
static ssize_t bonding_store_arp_validate(struct device *d,
@@ -627,7 +608,7 @@ static ssize_t bonding_show_arp_interval(struct device *d,
{
struct bonding *bond = to_bond(d);
- return sprintf(buf, "%d\n", bond->params.arp_interval) + 1;
+ return sprintf(buf, "%d\n", bond->params.arp_interval);
}
static ssize_t bonding_store_arp_interval(struct device *d,
@@ -712,9 +693,7 @@ static ssize_t bonding_show_arp_targets(struct device *d,
NIPQUAD(bond->params.arp_targets[i]));
}
if (res)
- res--; /* eat the leftover space */
- res += sprintf(buf + res, "\n");
- res++;
+ buf[res-1] = '\n'; /* eat the leftover space */
return res;
}
@@ -815,7 +794,7 @@ static ssize_t bonding_show_downdelay(struct device *d,
{
struct bonding *bond = to_bond(d);
- return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon) + 1;
+ return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon);
}
static ssize_t bonding_store_downdelay(struct device *d,
@@ -872,7 +851,7 @@ static ssize_t bonding_show_updelay(struct device *d,
{
struct bonding *bond = to_bond(d);
- return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon) + 1;
+ return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon);
}
@@ -936,7 +915,7 @@ static ssize_t bonding_show_lacp(struct device *d,
return sprintf(buf, "%s %d\n",
bond_lacp_tbl[bond->params.lacp_fast].modename,
- bond->params.lacp_fast) + 1;
+ bond->params.lacp_fast);
}
static ssize_t bonding_store_lacp(struct device *d,
@@ -992,7 +971,7 @@ static ssize_t bonding_show_miimon(struct device *d,
{
struct bonding *bond = to_bond(d);
- return sprintf(buf, "%d\n", bond->params.miimon) + 1;
+ return sprintf(buf, "%d\n", bond->params.miimon);
}
static ssize_t bonding_store_miimon(struct device *d,
@@ -1083,9 +1062,7 @@ static ssize_t bonding_show_primary(struct device *d,
struct bonding *bond = to_bond(d);
if (bond->primary_slave)
- count = sprintf(buf, "%s\n", bond->primary_slave->dev->name) + 1;
- else
- count = sprintf(buf, "\n") + 1;
+ count = sprintf(buf, "%s\n", bond->primary_slave->dev->name);
return count;
}
@@ -1149,7 +1126,7 @@ static ssize_t bonding_show_carrier(struct device *d,
{
struct bonding *bond = to_bond(d);
- return sprintf(buf, "%d\n", bond->params.use_carrier) + 1;
+ return sprintf(buf, "%d\n", bond->params.use_carrier);
}
static ssize_t bonding_store_carrier(struct device *d,
@@ -1191,16 +1168,14 @@ static ssize_t bonding_show_active_slave(struct device *d,
{
struct slave *curr;
struct bonding *bond = to_bond(d);
- int count;
+ int count = 0;
read_lock(&bond->curr_slave_lock);
curr = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
if (USES_PRIMARY(bond->params.mode) && curr)
- count = sprintf(buf, "%s\n", curr->dev->name) + 1;
- else
- count = sprintf(buf, "\n") + 1;
+ count = sprintf(buf, "%s\n", curr->dev->name);
return count;
}
@@ -1295,7 +1270,7 @@ static ssize_t bonding_show_mii_status(struct device *d,
curr = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
- return sprintf(buf, "%s\n", (curr) ? "up" : "down") + 1;
+ return sprintf(buf, "%s\n", (curr) ? "up" : "down");
}
static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
@@ -1312,10 +1287,8 @@ static ssize_t bonding_show_ad_aggregator(struct device *d,
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
- count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.aggregator_id) + 1;
+ count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.aggregator_id);
}
- else
- count = sprintf(buf, "\n") + 1;
return count;
}
@@ -1334,10 +1307,8 @@ static ssize_t bonding_show_ad_num_ports(struct device *d,
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
- count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0: ad_info.ports) + 1;
+ count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0: ad_info.ports);
}
- else
- count = sprintf(buf, "\n") + 1;
return count;
}
@@ -1356,10 +1327,8 @@ static ssize_t bonding_show_ad_actor_key(struct device *d,
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
- count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.actor_key) + 1;
+ count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.actor_key);
}
- else
- count = sprintf(buf, "\n") + 1;
return count;
}
@@ -1378,10 +1347,8 @@ static ssize_t bonding_show_ad_partner_key(struct device *d,
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
- count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.partner_key) + 1;
+ count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.partner_key);
}
- else
- count = sprintf(buf, "\n") + 1;
return count;
}
@@ -1403,12 +1370,9 @@ static ssize_t bonding_show_ad_partner_mac(struct device *d,
struct ad_info ad_info;
if (!bond_3ad_get_active_agg_info(bond, &ad_info)) {
count = sprintf(buf,"%s\n",
- print_mac(mac, ad_info.partner_system))
- + 1;
+ print_mac(mac, ad_info.partner_system));
}
}
- else
- count = sprintf(buf, "\n") + 1;
return count;
}
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 61c1b45..e1e4734 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -22,8 +22,8 @@
#include "bond_3ad.h"
#include "bond_alb.h"
-#define DRV_VERSION "3.2.1"
-#define DRV_RELDATE "October 15, 2007"
+#define DRV_VERSION "3.2.3"
+#define DRV_RELDATE "December 6, 2007"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index 5e1bc0d..6e12bf4 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -1937,6 +1937,10 @@
#define A_XGM_RXFIFO_CFG 0x884
+#define S_RXFIFO_EMPTY 31
+#define V_RXFIFO_EMPTY(x) ((x) << S_RXFIFO_EMPTY)
+#define F_RXFIFO_EMPTY V_RXFIFO_EMPTY(1U)
+
#define S_RXFIFOPAUSEHWM 17
#define M_RXFIFOPAUSEHWM 0xfff
@@ -1961,6 +1965,10 @@
#define A_XGM_TXFIFO_CFG 0x888
+#define S_UNDERUNFIX 22
+#define V_UNDERUNFIX(x) ((x) << S_UNDERUNFIX)
+#define F_UNDERUNFIX V_UNDERUNFIX(1U)
+
#define S_TXIPG 13
#define M_TXIPG 0xff
#define V_TXIPG(x) ((x) << S_TXIPG)
@@ -2034,10 +2042,27 @@
#define V_XAUIIMP(x) ((x) << S_XAUIIMP)
#define A_XGM_RX_MAX_PKT_SIZE 0x8a8
-#define A_XGM_RX_MAX_PKT_SIZE_ERR_CNT 0x9a4
+
+#define S_RXMAXFRAMERSIZE 17
+#define M_RXMAXFRAMERSIZE 0x3fff
+#define V_RXMAXFRAMERSIZE(x) ((x) << S_RXMAXFRAMERSIZE)
+#define G_RXMAXFRAMERSIZE(x) (((x) >> S_RXMAXFRAMERSIZE) & M_RXMAXFRAMERSIZE)
+
+#define S_RXENFRAMER 14
+#define V_RXENFRAMER(x) ((x) << S_RXENFRAMER)
+#define F_RXENFRAMER V_RXENFRAMER(1U)
+
+#define S_RXMAXPKTSIZE 0
+#define M_RXMAXPKTSIZE 0x3fff
+#define V_RXMAXPKTSIZE(x) ((x) << S_RXMAXPKTSIZE)
+#define G_RXMAXPKTSIZE(x) (((x) >> S_RXMAXPKTSIZE) & M_RXMAXPKTSIZE)
#define A_XGM_RESET_CTRL 0x8ac
+#define S_XGMAC_STOP_EN 4
+#define V_XGMAC_STOP_EN(x) ((x) << S_XGMAC_STOP_EN)
+#define F_XGMAC_STOP_EN V_XGMAC_STOP_EN(1U)
+
#define S_XG2G_RESET_ 3
#define V_XG2G_RESET_(x) ((x) << S_XG2G_RESET_)
#define F_XG2G_RESET_ V_XG2G_RESET_(1U)
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index d4ee00d..522834c 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -447,8 +447,8 @@ static const struct adapter_info t3_adap_info[] = {
&mi1_mdio_ops, "Chelsio T302"},
{1, 0, 0, 0,
F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN |
- F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0,
- SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
+ F_GPIO11_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
+ 0, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
&mi1_mdio_ext_ops, "Chelsio T310"},
{2, 0, 0, 0,
F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN |
@@ -2613,7 +2613,7 @@ static void __devinit init_mtus(unsigned short mtus[])
* it can accomodate max size TCP/IP headers when SACK and timestamps
* are enabled and still have at least 8 bytes of payload.
*/
- mtus[1] = 88;
+ mtus[0] = 88;
mtus[1] = 88;
mtus[2] = 256;
mtus[3] = 512;
diff --git a/drivers/net/cxgb3/xgmac.c b/drivers/net/cxgb3/xgmac.c
index eeb766a..efcf09a 100644
--- a/drivers/net/cxgb3/xgmac.c
+++ b/drivers/net/cxgb3/xgmac.c
@@ -106,6 +106,7 @@ int t3_mac_reset(struct cmac *mac)
t3_set_reg_field(adap, A_XGM_RXFIFO_CFG + oft,
F_RXSTRFRWRD | F_DISERRFRAMES,
uses_xaui(adap) ? 0 : F_RXSTRFRWRD);
+ t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + oft, 0, F_UNDERUNFIX);
if (uses_xaui(adap)) {
if (adap->params.rev == 0) {
@@ -124,7 +125,11 @@ int t3_mac_reset(struct cmac *mac)
xaui_serdes_reset(mac);
}
- val = F_MAC_RESET_;
+ t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + oft,
+ V_RXMAXFRAMERSIZE(M_RXMAXFRAMERSIZE),
+ V_RXMAXFRAMERSIZE(MAX_FRAME_SIZE) | F_RXENFRAMER);
+ val = F_MAC_RESET_ | F_XGMAC_STOP_EN;
+
if (is_10G(adap))
val |= F_PCS_RESET_;
else if (uses_xaui(adap))
@@ -313,8 +318,9 @@ static int rx_fifo_hwm(int mtu)
int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
{
- int hwm, lwm;
- unsigned int thres, v;
+ int hwm, lwm, divisor;
+ int ipg;
+ unsigned int thres, v, reg;
struct adapter *adap = mac->adapter;
/*
@@ -335,27 +341,32 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
hwm = min(hwm, MAC_RXFIFO_SIZE - 8192);
lwm = min(3 * (int)mtu, MAC_RXFIFO_SIZE / 4);
- if (adap->params.rev == T3_REV_B2 &&
+ if (adap->params.rev >= T3_REV_B2 &&
(t3_read_reg(adap, A_XGM_RX_CTRL + mac->offset) & F_RXEN)) {
disable_exact_filters(mac);
v = t3_read_reg(adap, A_XGM_RX_CFG + mac->offset);
t3_set_reg_field(adap, A_XGM_RX_CFG + mac->offset,
F_ENHASHMCAST | F_COPYALLFRAMES, F_DISBCAST);
- /* drain rx FIFO */
- if (t3_wait_op_done(adap,
- A_XGM_RX_MAX_PKT_SIZE_ERR_CNT +
- mac->offset,
- 1 << 31, 1, 20, 5)) {
+ reg = adap->params.rev == T3_REV_B2 ?
+ A_XGM_RX_MAX_PKT_SIZE_ERR_CNT : A_XGM_RXFIFO_CFG;
+
+ /* drain RX FIFO */
+ if (t3_wait_op_done(adap, reg + mac->offset,
+ F_RXFIFO_EMPTY, 1, 20, 5)) {
t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
enable_exact_filters(mac);
return -EIO;
}
- t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu);
+ t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
+ V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
+ V_RXMAXPKTSIZE(mtu));
t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
enable_exact_filters(mac);
} else
- t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu);
+ t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
+ V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
+ V_RXMAXPKTSIZE(mtu));
/*
* Adjust the PAUSE frame watermarks. We always set the LWM, and the
@@ -379,13 +390,16 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
thres /= 10;
thres = mtu > thres ? (mtu - thres + 7) / 8 : 0;
thres = max(thres, 8U); /* need at least 8 */
+ ipg = (adap->params.rev == T3_REV_C) ? 0 : 1;
t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + mac->offset,
V_TXFIFOTHRESH(M_TXFIFOTHRESH) | V_TXIPG(M_TXIPG),
- V_TXFIFOTHRESH(thres) | V_TXIPG(1));
+ V_TXFIFOTHRESH(thres) | V_TXIPG(ipg));
- if (adap->params.rev > 0)
+ if (adap->params.rev > 0) {
+ divisor = (adap->params.rev == T3_REV_C) ? 64 : 8;
t3_write_reg(adap, A_XGM_PAUSE_TIMER + mac->offset,
- (hwm - lwm) * 4 / 8);
+ (hwm - lwm) * 4 / divisor);
+ }
t3_write_reg(adap, A_XGM_TX_PAUSE_QUANTA + mac->offset,
MAC_RXFIFO_SIZE * 4 * 8 / 512);
return 0;
@@ -522,7 +536,7 @@ int t3b2_mac_watchdog_task(struct cmac *mac)
goto rxcheck;
}
- if ((tx_tcnt != mac->tx_tcnt) && (mac->tx_xcnt == 0)) {
+ if ((tx_tcnt != mac->tx_tcnt) && (mac->tx_xcnt == 0)) {
if (mac->toggle_cnt > 4) {
status = 2;
goto out;
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 3dbaec6..e1c8a0d 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -2214,13 +2214,11 @@ static void e100_get_drvinfo(struct net_device *netdev,
strcpy(info->bus_info, pci_name(nic->pdev));
}
+#define E100_PHY_REGS 0x1C
static int e100_get_regs_len(struct net_device *netdev)
{
struct nic *nic = netdev_priv(netdev);
-#define E100_PHY_REGS 0x1C
-#define E100_REGS_LEN 1 + E100_PHY_REGS + \
- sizeof(nic->mem->dump_buf) / sizeof(u32)
- return E100_REGS_LEN * sizeof(u32);
+ return 1 + E100_PHY_REGS + sizeof(nic->mem->dump_buf);
}
static void e100_get_regs(struct net_device *netdev,
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 667f18b..b83ccce 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1923,7 +1923,7 @@ e1000_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
switch (stringset) {
case ETH_SS_TEST:
memcpy(data, *e1000_gstrings_test,
- E1000_TEST_LEN*ETH_GSTRING_LEN);
+ sizeof(e1000_gstrings_test));
break;
case ETH_SS_STATS:
for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 6a39784..87f9da1 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -1739,7 +1739,7 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset,
switch (stringset) {
case ETH_SS_TEST:
memcpy(data, *e1000_gstrings_test,
- E1000_TEST_LEN*ETH_GSTRING_LEN);
+ sizeof(e1000_gstrings_test));
break;
case ETH_SS_STATS:
for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index eb0718b..cb06280 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -3,6 +3,11 @@
*
* Driver for PowerPC 4xx on-chip ethernet controller.
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Copyright (c) 2004, 2005 Zultys Technologies.
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
@@ -402,7 +407,7 @@ static u32 __emac_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_s
static u32 __emac4_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_size)
{
u32 ret = EMAC_MR1_VLE | EMAC_MR1_IST | EMAC4_MR1_TR |
- EMAC4_MR1_OBCI(dev->opb_bus_freq);
+ EMAC4_MR1_OBCI(dev->opb_bus_freq / 1000000);
DBG2(dev, "__emac4_calc_base_mr1" NL);
@@ -464,26 +469,34 @@ static int emac_configure(struct emac_instance *dev)
{
struct emac_regs __iomem *p = dev->emacp;
struct net_device *ndev = dev->ndev;
- int tx_size, rx_size;
+ int tx_size, rx_size, link = netif_carrier_ok(dev->ndev);
u32 r, mr1 = 0;
DBG(dev, "configure" NL);
- if (emac_reset(dev) < 0)
+ if (!link) {
+ out_be32(&p->mr1, in_be32(&p->mr1)
+ | EMAC_MR1_FDE | EMAC_MR1_ILE);
+ udelay(100);
+ } else if (emac_reset(dev) < 0)
return -ETIMEDOUT;
if (emac_has_feature(dev, EMAC_FTR_HAS_TAH))
tah_reset(dev->tah_dev);
- DBG(dev, " duplex = %d, pause = %d, asym_pause = %d\n",
- dev->phy.duplex, dev->phy.pause, dev->phy.asym_pause);
+ DBG(dev, " link = %d duplex = %d, pause = %d, asym_pause = %d\n",
+ link, dev->phy.duplex, dev->phy.pause, dev->phy.asym_pause);
/* Default fifo sizes */
tx_size = dev->tx_fifo_size;
rx_size = dev->rx_fifo_size;
+ /* No link, force loopback */
+ if (!link)
+ mr1 = EMAC_MR1_FDE | EMAC_MR1_ILE;
+
/* Check for full duplex */
- if (dev->phy.duplex == DUPLEX_FULL)
+ else if (dev->phy.duplex == DUPLEX_FULL)
mr1 |= EMAC_MR1_FDE | EMAC_MR1_MWSW_001;
/* Adjust fifo sizes, mr1 and timeouts based on link speed */
@@ -703,7 +716,7 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 id, u8 reg)
r = EMAC_STACR_BASE(dev->opb_bus_freq);
if (emac_has_feature(dev, EMAC_FTR_STACR_OC_INVERT))
r |= EMAC_STACR_OC;
- if (emac_has_feature(dev, EMAC_FTR_HAS_AXON_STACR))
+ if (emac_has_feature(dev, EMAC_FTR_HAS_NEW_STACR))
r |= EMACX_STACR_STAC_READ;
else
r |= EMAC_STACR_STAC_READ;
@@ -775,7 +788,7 @@ static void __emac_mdio_write(struct emac_instance *dev, u8 id, u8 reg,
r = EMAC_STACR_BASE(dev->opb_bus_freq);
if (emac_has_feature(dev, EMAC_FTR_STACR_OC_INVERT))
r |= EMAC_STACR_OC;
- if (emac_has_feature(dev, EMAC_FTR_HAS_AXON_STACR))
+ if (emac_has_feature(dev, EMAC_FTR_HAS_NEW_STACR))
r |= EMACX_STACR_STAC_WRITE;
else
r |= EMAC_STACR_STAC_WRITE;
@@ -1165,9 +1178,9 @@ static void emac_link_timer(struct work_struct *work)
link_poll_interval = PHY_POLL_LINK_ON;
} else {
if (netif_carrier_ok(dev->ndev)) {
- emac_reinitialize(dev);
netif_carrier_off(dev->ndev);
netif_tx_disable(dev->ndev);
+ emac_reinitialize(dev);
emac_print_link_status(dev);
}
link_poll_interval = PHY_POLL_LINK_OFF;
@@ -2434,7 +2447,7 @@ static int __devinit emac_init_config(struct emac_instance *dev)
if (emac_read_uint_prop(np, "tah-device", &dev->tah_ph, 0))
dev->tah_ph = 0;
if (emac_read_uint_prop(np, "tah-channel", &dev->tah_port, 0))
- dev->tah_ph = 0;
+ dev->tah_port = 0;
if (emac_read_uint_prop(np, "mdio-device", &dev->mdio_ph, 0))
dev->mdio_ph = 0;
if (emac_read_uint_prop(np, "zmii-device", &dev->zmii_ph, 0))
@@ -2472,16 +2485,19 @@ static int __devinit emac_init_config(struct emac_instance *dev)
/* Check EMAC version */
if (of_device_is_compatible(np, "ibm,emac4"))
dev->features |= EMAC_FTR_EMAC4;
- if (of_device_is_compatible(np, "ibm,emac-axon")
- || of_device_is_compatible(np, "ibm,emac-440epx"))
- dev->features |= EMAC_FTR_HAS_AXON_STACR
- | EMAC_FTR_STACR_OC_INVERT;
- if (of_device_is_compatible(np, "ibm,emac-440spe"))
+
+ /* Fixup some feature bits based on the device tree */
+ if (of_get_property(np, "has-inverted-stacr-oc", NULL))
dev->features |= EMAC_FTR_STACR_OC_INVERT;
+ if (of_get_property(np, "has-new-stacr-staopc", NULL))
+ dev->features |= EMAC_FTR_HAS_NEW_STACR;
- /* Fixup some feature bits based on the device tree and verify
- * we have support for them compiled in
- */
+ /* CAB lacks the appropriate properties */
+ if (of_device_is_compatible(np, "ibm,emac-axon"))
+ dev->features |= EMAC_FTR_HAS_NEW_STACR |
+ EMAC_FTR_STACR_OC_INVERT;
+
+ /* Enable TAH/ZMII/RGMII features as found */
if (dev->tah_ph != 0) {
#ifdef CONFIG_IBM_NEW_EMAC_TAH
dev->features |= EMAC_FTR_HAS_TAH;
@@ -2539,6 +2555,10 @@ static int __devinit emac_probe(struct of_device *ofdev,
struct device_node **blist = NULL;
int err, i;
+ /* Skip unused/unwired EMACS */
+ if (of_get_property(np, "unused", NULL))
+ return -ENODEV;
+
/* Find ourselves in the bootlist if we are there */
for (i = 0; i < EMAC_BOOT_LIST_SIZE; i++)
if (emac_boot_list[i] == np)
diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h
index a010b24..4e74d82 100644
--- a/drivers/net/ibm_newemac/core.h
+++ b/drivers/net/ibm_newemac/core.h
@@ -3,6 +3,11 @@
*
* Driver for PowerPC 4xx on-chip ethernet controller.
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Copyright (c) 2004, 2005 Zultys Technologies.
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
@@ -293,9 +298,9 @@ struct emac_instance {
*/
#define EMAC_FTR_HAS_RGMII 0x00000020
/*
- * Set if we have axon-type STACR
+ * Set if we have new type STACR with STAOPC
*/
-#define EMAC_FTR_HAS_AXON_STACR 0x00000040
+#define EMAC_FTR_HAS_NEW_STACR 0x00000040
/* Right now, we don't quite handle the always/possible masks on the
@@ -307,7 +312,7 @@ enum {
EMAC_FTRS_POSSIBLE =
#ifdef CONFIG_IBM_NEW_EMAC_EMAC4
- EMAC_FTR_EMAC4 | EMAC_FTR_HAS_AXON_STACR |
+ EMAC_FTR_EMAC4 | EMAC_FTR_HAS_NEW_STACR |
EMAC_FTR_STACR_OC_INVERT |
#endif
#ifdef CONFIG_IBM_NEW_EMAC_TAH
diff --git a/drivers/net/ibm_newemac/debug.c b/drivers/net/ibm_newemac/debug.c
index 170524e..a2fc660 100644
--- a/drivers/net/ibm_newemac/debug.c
+++ b/drivers/net/ibm_newemac/debug.c
@@ -3,6 +3,11 @@
*
* Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Copyright (c) 2004, 2005 Zultys Technologies
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
diff --git a/drivers/net/ibm_newemac/debug.h b/drivers/net/ibm_newemac/debug.h
index 1dd2dcb..b631842 100644
--- a/drivers/net/ibm_newemac/debug.h
+++ b/drivers/net/ibm_newemac/debug.h
@@ -3,6 +3,11 @@
*
* Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Copyright (c) 2004, 2005 Zultys Technologies
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h
index bef92ef..91cb096 100644
--- a/drivers/net/ibm_newemac/emac.h
+++ b/drivers/net/ibm_newemac/emac.h
@@ -3,6 +3,11 @@
*
* Register definitions for PowerPC 4xx on-chip ethernet contoller
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Copyright (c) 2004, 2005 Zultys Technologies.
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c
index 9a88f71..6869f08 100644
--- a/drivers/net/ibm_newemac/mal.c
+++ b/drivers/net/ibm_newemac/mal.c
@@ -3,6 +3,11 @@
*
* Memory Access Layer (MAL) support
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Copyright (c) 2004, 2005 Zultys Technologies.
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
diff --git a/drivers/net/ibm_newemac/mal.h b/drivers/net/ibm_newemac/mal.h
index 784edb8..eaa7262 100644
--- a/drivers/net/ibm_newemac/mal.h
+++ b/drivers/net/ibm_newemac/mal.h
@@ -3,6 +3,11 @@
*
* Memory Access Layer (MAL) support
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Copyright (c) 2004, 2005 Zultys Technologies.
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
diff --git a/drivers/net/ibm_newemac/phy.c b/drivers/net/ibm_newemac/phy.c
index aa1f0dd..37bfeea 100644
--- a/drivers/net/ibm_newemac/phy.c
+++ b/drivers/net/ibm_newemac/phy.c
@@ -8,6 +8,11 @@
* This file should be shared with other drivers or eventually
* merged as the "low level" part of miilib
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
* (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net>
*
@@ -306,8 +311,84 @@ static struct mii_phy_def cis8201_phy_def = {
.ops = &cis8201_phy_ops
};
+static struct mii_phy_def bcm5248_phy_def = {
+
+ .phy_id = 0x0143bc00,
+ .phy_id_mask = 0x0ffffff0,
+ .name = "BCM5248 10/100 SMII Ethernet",
+ .ops = &generic_phy_ops
+};
+
+static int m88e1111_init(struct mii_phy *phy)
+{
+ pr_debug("%s: Marvell 88E1111 Ethernet\n", __FUNCTION__);
+ phy_write(phy, 0x14, 0x0ce3);
+ phy_write(phy, 0x18, 0x4101);
+ phy_write(phy, 0x09, 0x0e00);
+ phy_write(phy, 0x04, 0x01e1);
+ phy_write(phy, 0x00, 0x9140);
+ phy_write(phy, 0x00, 0x1140);
+
+ return 0;
+}
+
+static int et1011c_init(struct mii_phy *phy)
+{
+ u16 reg_short;
+
+ reg_short = (u16)(phy_read(phy, 0x16));
+ reg_short &= ~(0x7);
+ reg_short |= 0x6; /* RGMII Trace Delay*/
+ phy_write(phy, 0x16, reg_short);
+
+ reg_short = (u16)(phy_read(phy, 0x17));
+ reg_short &= ~(0x40);
+ phy_write(phy, 0x17, reg_short);
+
+ phy_write(phy, 0x1c, 0x74f0);
+ return 0;
+}
+
+static struct mii_phy_ops et1011c_phy_ops = {
+ .init = et1011c_init,
+ .setup_aneg = genmii_setup_aneg,
+ .setup_forced = genmii_setup_forced,
+ .poll_link = genmii_poll_link,
+ .read_link = genmii_read_link
+};
+
+static struct mii_phy_def et1011c_phy_def = {
+ .phy_id = 0x0282f000,
+ .phy_id_mask = 0x0fffff00,
+ .name = "ET1011C Gigabit Ethernet",
+ .ops = &et1011c_phy_ops
+};
+
+
+
+
+
+static struct mii_phy_ops m88e1111_phy_ops = {
+ .init = m88e1111_init,
+ .setup_aneg = genmii_setup_aneg,
+ .setup_forced = genmii_setup_forced,
+ .poll_link = genmii_poll_link,
+ .read_link = genmii_read_link
+};
+
+static struct mii_phy_def m88e1111_phy_def = {
+
+ .phy_id = 0x01410CC0,
+ .phy_id_mask = 0x0ffffff0,
+ .name = "Marvell 88E1111 Ethernet",
+ .ops = &m88e1111_phy_ops,
+};
+
static struct mii_phy_def *mii_phy_table[] = {
+ &et1011c_phy_def,
&cis8201_phy_def,
+ &bcm5248_phy_def,
+ &m88e1111_phy_def,
&genmii_phy_def,
NULL
};
diff --git a/drivers/net/ibm_newemac/phy.h b/drivers/net/ibm_newemac/phy.h
index 6feca26..1b65c81 100644
--- a/drivers/net/ibm_newemac/phy.h
+++ b/drivers/net/ibm_newemac/phy.h
@@ -3,6 +3,11 @@
*
* Driver for PowerPC 4xx on-chip ethernet controller, PHY support
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Benjamin Herrenschmidt <benh@kernel.crashing.org>
* February 2003
*
diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c
index de41695..9bc1132 100644
--- a/drivers/net/ibm_newemac/rgmii.c
+++ b/drivers/net/ibm_newemac/rgmii.c
@@ -3,6 +3,11 @@
*
* Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Copyright (c) 2004, 2005 Zultys Technologies.
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
@@ -140,7 +145,7 @@ void rgmii_get_mdio(struct of_device *ofdev, int input)
RGMII_DBG2(dev, "get_mdio(%d)" NL, input);
- if (dev->type != RGMII_AXON)
+ if (!(dev->flags & EMAC_RGMII_FLAG_HAS_MDIO))
return;
mutex_lock(&dev->lock);
@@ -161,7 +166,7 @@ void rgmii_put_mdio(struct of_device *ofdev, int input)
RGMII_DBG2(dev, "put_mdio(%d)" NL, input);
- if (dev->type != RGMII_AXON)
+ if (!(dev->flags & EMAC_RGMII_FLAG_HAS_MDIO))
return;
fer = in_be32(&p->fer);
@@ -250,11 +255,13 @@ static int __devinit rgmii_probe(struct of_device *ofdev,
goto err_free;
}
- /* Check for RGMII type */
+ /* Check for RGMII flags */
+ if (of_get_property(ofdev->node, "has-mdio", NULL))
+ dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO;
+
+ /* CAB lacks the right properties, fix this up */
if (of_device_is_compatible(ofdev->node, "ibm,rgmii-axon"))
- dev->type = RGMII_AXON;
- else
- dev->type = RGMII_STANDARD;
+ dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO;
DBG2(dev, " Boot FER = 0x%08x, SSR = 0x%08x\n",
in_be32(&dev->base->fer), in_be32(&dev->base->ssr));
@@ -263,9 +270,9 @@ static int __devinit rgmii_probe(struct of_device *ofdev,
out_be32(&dev->base->fer, 0);
printk(KERN_INFO
- "RGMII %s %s initialized\n",
- dev->type == RGMII_STANDARD ? "standard" : "axon",
- ofdev->node->full_name);
+ "RGMII %s initialized with%s MDIO support\n",
+ ofdev->node->full_name,
+ (dev->flags & EMAC_RGMII_FLAG_HAS_MDIO) ? "" : "out");
wmb();
dev_set_drvdata(&ofdev->dev, dev);
diff --git a/drivers/net/ibm_newemac/rgmii.h b/drivers/net/ibm_newemac/rgmii.h
index 5780683..c4a4b35 100644
--- a/drivers/net/ibm_newemac/rgmii.h
+++ b/drivers/net/ibm_newemac/rgmii.h
@@ -3,6 +3,11 @@
*
* Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Based on ocp_zmii.h/ibm_emac_zmii.h
* Armin Kuster akuster@mvista.com
*
@@ -35,8 +40,9 @@ struct rgmii_regs {
struct rgmii_instance {
struct rgmii_regs __iomem *base;
- /* Type of RGMII bridge */
- int type;
+ /* RGMII bridge flags */
+ int flags;
+#define EMAC_RGMII_FLAG_HAS_MDIO 0x00000001
/* Only one EMAC whacks us at a time */
struct mutex lock;
diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c
index f161fb1..96417ad 100644
--- a/drivers/net/ibm_newemac/tah.c
+++ b/drivers/net/ibm_newemac/tah.c
@@ -3,6 +3,11 @@
*
* Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Copyright 2004 MontaVista Software, Inc.
* Matt Porter <mporter@kernel.crashing.org>
*
@@ -116,13 +121,14 @@ static int __devinit tah_probe(struct of_device *ofdev,
goto err_free;
}
+ dev_set_drvdata(&ofdev->dev, dev);
+
/* Initialize TAH and enable IPv4 checksum verification, no TSO yet */
tah_reset(ofdev);
printk(KERN_INFO
"TAH %s initialized\n", ofdev->node->full_name);
wmb();
- dev_set_drvdata(&ofdev->dev, dev);
return 0;
diff --git a/drivers/net/ibm_newemac/tah.h b/drivers/net/ibm_newemac/tah.h
index bc41853..a068b56 100644
--- a/drivers/net/ibm_newemac/tah.h
+++ b/drivers/net/ibm_newemac/tah.h
@@ -3,6 +3,11 @@
*
* Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Copyright 2004 MontaVista Software, Inc.
* Matt Porter <mporter@kernel.crashing.org>
*
diff --git a/drivers/net/ibm_newemac/zmii.c b/drivers/net/ibm_newemac/zmii.c
index 2219ec2..2ea472a 100644
--- a/drivers/net/ibm_newemac/zmii.c
+++ b/drivers/net/ibm_newemac/zmii.c
@@ -3,6 +3,11 @@
*
* Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Copyright (c) 2004, 2005 Zultys Technologies.
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
@@ -83,12 +88,14 @@ int __devinit zmii_attach(struct of_device *ofdev, int input, int *mode)
ZMII_DBG(dev, "init(%d, %d)" NL, input, *mode);
- if (!zmii_valid_mode(*mode))
+ if (!zmii_valid_mode(*mode)) {
/* Probably an EMAC connected to RGMII,
* but it still may need ZMII for MDIO so
* we don't fail here.
*/
+ dev->users++;
return 0;
+ }
mutex_lock(&dev->lock);
diff --git a/drivers/net/ibm_newemac/zmii.h b/drivers/net/ibm_newemac/zmii.h
index 82a9968..6c9beba 100644
--- a/drivers/net/ibm_newemac/zmii.h
+++ b/drivers/net/ibm_newemac/zmii.h
@@ -3,6 +3,11 @@
*
* Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
*
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
* Copyright (c) 2004, 2005 Zultys Technologies.
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
index 01f08d7..f25264f 100644
--- a/drivers/net/s2io-regs.h
+++ b/drivers/net/s2io-regs.h
@@ -66,6 +66,7 @@ struct XENA_dev_config {
#define ADAPTER_STATUS_RC_PRC_QUIESCENT vBIT(0xFF,16,8)
#define ADAPTER_STATUS_MC_DRAM_READY s2BIT(24)
#define ADAPTER_STATUS_MC_QUEUES_READY s2BIT(25)
+#define ADAPTER_STATUS_RIC_RUNNING s2BIT(26)
#define ADAPTER_STATUS_M_PLL_LOCK s2BIT(30)
#define ADAPTER_STATUS_P_PLL_LOCK s2BIT(31)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index d5113dd..121cb10 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -84,7 +84,7 @@
#include "s2io.h"
#include "s2io-regs.h"
-#define DRV_VERSION "2.0.26.6"
+#define DRV_VERSION "2.0.26.10"
/* S2io Driver name & version. */
static char s2io_driver_name[] = "Neterion";
@@ -1100,6 +1100,20 @@ static int init_nic(struct s2io_nic *nic)
msleep(500);
val64 = readq(&bar0->sw_reset);
+ /* Ensure that it's safe to access registers by checking
+ * RIC_RUNNING bit is reset. Check is valid only for XframeII.
+ */
+ if (nic->device_type == XFRAME_II_DEVICE) {
+ for (i = 0; i < 50; i++) {
+ val64 = readq(&bar0->adapter_status);
+ if (!(val64 & ADAPTER_STATUS_RIC_RUNNING))
+ break;
+ msleep(10);
+ }
+ if (i == 50)
+ return -ENODEV;
+ }
+
/* Enable Receiving broadcasts */
add = &bar0->mac_cfg;
val64 = readq(&bar0->mac_cfg);
diff --git a/include/linux/if_bonding.h b/include/linux/if_bonding.h
index 84598fa..65c2d24 100644
--- a/include/linux/if_bonding.h
+++ b/include/linux/if_bonding.h
@@ -85,7 +85,8 @@
/* hashing types */
#define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */
-#define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ MAC) */
+#define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */
+#define BOND_XMIT_POLICY_LAYER23 2 /* layer 2+3 (IP ^ MAC) */
typedef struct ifbond {
__s32 bond_mode;
^ permalink raw reply related
* Re: [PATCH 2.6.24 1/1]S2io: Check for register initialization completion before accesing device registers
From: Jeff Garzik @ 2007-12-07 20:09 UTC (permalink / raw)
To: Sreenivasa Honnur; +Cc: netdev, support
In-Reply-To: <Pine.GSO.4.10.10712052356570.27705-100000@guinness>
Sreenivasa Honnur wrote:
> - Making sure register initialisation is complete before proceeding further.
> The driver must wait until initialization is complete before attempting to
> access any other device registers.
>
> Signed-off-by: Surjit Reang <surjit.reang@neterion.com>
> Signed-off-by: Sreenivasa Honnur <sreenivasa.honnur@neterion.com>
applied #upstream-fixes
^ permalink raw reply
* Re: [PATCH 1/11] ibm_newemac: Add BCM5248 and Marvell 88E1111 PHY support
From: Jeff Garzik @ 2007-12-07 20:09 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: netdev, linuxppc-dev, Josh Boyer
In-Reply-To: <20071205001534.D681ADDF2D@ozlabs.org>
Benjamin Herrenschmidt wrote:
> From: Stefan Roese <sr@denx.de>
>
> This patch adds BCM5248 and Marvell 88E1111 PHY support to NEW EMAC driver.
> These PHY chips are used on PowerPC 440EPx boards.
> The PHY code is based on the previous work by Stefan Roese <sr@denx.de>
>
> Signed-off-by: Stefan Roese <sr@denx.de>
> Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>
> drivers/net/ibm_newemac/phy.c | 39 +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 39 insertions(+)
applied 1-11 #upstream-fixes
^ permalink raw reply
* Re: [PATCH 1/2] e1000: fix memcpy in e1000_get_strings
From: Jeff Garzik @ 2007-12-07 20:03 UTC (permalink / raw)
To: Auke Kok; +Cc: netdev, 12o3l
In-Reply-To: <20071205195729.6859.97796.stgit@localhost.localdomain>
Auke Kok wrote:
> From: Roel Kluin <12o3l@tiscali.nl>
>
> drivers/net/e1000/e1000_ethtool.c:113:
> #define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN
>
> drivers/net/e1000e/ethtool.c:106:
> #define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN
>
> E1000_TEST_LEN*ETH_GSTRING_LEN will expand to
> sizeof(e1000_gstrings_test) / (ETH_GSTRING_LEN * ETH_GSTRING_LEN)
>
> A lack of parentheses around defines causes unexpected results due to
> operator precedences.
>
> Signed-off-by: Roel Kluin <12o3l@tiscali.nl>
> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
> ---
>
> drivers/net/e1000/e1000_ethtool.c | 2 +-
> drivers/net/e1000e/ethtool.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
applied 1-2 to #upstream-fixes
^ permalink raw reply
* Re: [patch resend build-breakage] make bnx2x select ZLIB_INFLATE
From: Jeff Garzik @ 2007-12-07 20:03 UTC (permalink / raw)
To: Eliezer Tamir
Cc: netdev@vger.kernel.org, davem@davemloft.net, Lee Schermerhorn
In-Reply-To: <1196863959.5204.25.camel@lb-tlvb-eliezer.il.broadcom.com>
Eliezer Tamir wrote:
> The bnx2x module depends on the zlib_inflate functions. The
> build will fail if ZLIB_INFLATE has not been selected manually
> or by building another module that automatically selects it.
>
> Modify BNX2X config option to 'select ZLIB_INFLATE' like BNX2
> and others. This seems to fix it.
>
>
> Signed-off-by: Lee Schermerhorn <lee.schermerhorn@hp.com>
> Acked-by: Eliezer Tamir <eliezert@broadcom.com>
> ---
> drivers/net/Kconfig | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 5bafb30..b9d7f5b 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -2594,6 +2594,7 @@ config TEHUTI
> config BNX2X
> tristate "Broadcom NetXtremeII 10Gb support"
> depends on PCI
> + select ZLIB_INFLATE
> help
applied #upstream-fixes
^ permalink raw reply
* Re: [PATCH 2/2] cxgb3 - Parity initialization for T3C adapters
From: Jeff Garzik @ 2007-12-07 20:02 UTC (permalink / raw)
To: Divy Le Ray; +Cc: netdev, linux-kernel, swise, wenxiong
In-Reply-To: <20071205181527.22106.73134.stgit@speedy5>
Divy Le Ray wrote:
> From: Divy Le Ray <divy@chelsio.com>
>
> Add parity initialization for T3C adapters.
>
> Signed-off-by: Divy Le Ray <divy@chelsio.com>
> ---
>
> drivers/net/cxgb3/adapter.h | 1
> drivers/net/cxgb3/cxgb3_main.c | 82 ++++++++++++
> drivers/net/cxgb3/cxgb3_offload.c | 15 ++
> drivers/net/cxgb3/regs.h | 248 +++++++++++++++++++++++++++++++++++++
> drivers/net/cxgb3/sge.c | 24 +++-
> drivers/net/cxgb3/t3_hw.c | 131 +++++++++++++++++---
> 6 files changed, 472 insertions(+), 29 deletions(-)
dropped patches 2-3, did not apply
^ permalink raw reply
* Re: [PATCH 1/2] cxgb3 - T3C support update
From: Jeff Garzik @ 2007-12-07 20:02 UTC (permalink / raw)
To: Divy Le Ray; +Cc: netdev, linux-kernel, swise, wenxiong
In-Reply-To: <20071205181501.22081.97696.stgit@speedy5>
Divy Le Ray wrote:
> From: Divy Le Ray <divy@chelsio.com>
>
> Update GPIO mapping for T3C.
> Update xgmac for T3C support.
> Fix typo in mtu table.
>
> Signed-off-by: Divy Le Ray <divy@chelsio.com>
applied #upstream-fixes
^ permalink raw reply
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