* [v2 PATCH 1/2] NETFILTER module xt_hmark new target for HASH based fw
From: Hans Schillstrom @ 2011-10-03 17:46 UTC (permalink / raw)
To: kaber, pablo, jengelh, netfilter-devel, netdev; +Cc: hans, Hans Schillstrom
In-Reply-To: <1317664003-28189-1-git-send-email-hans.schillstrom@ericsson.com>
The target allows you to create rules in the "raw" and "mangle" tables
which alter the netfilter mark (nfmark) field within a given range.
First a 32 bit hash value is generated then modulus by <limit> and
finally an offset is added before it's written to nfmark.
Prior to routing, the nfmark can influence the routing method (see
"Use netfilter MARK value as routing key") and can also be used by
other subsystems to change their behavior.
man page
HMARK
This module does the same as MARK, i.e. set an fwmark,
but the mark is based on a hash value. The hash is based on
saddr, daddr, sport, dport and proto. The same mark will be produced
independet of direction if no masks is set or the same masks is used for
src and dest. The hash mark could be adjusted by modulus and finaly an
offset could be added, i.e the final mark will be within a range.
ICMP errors will have hash calc based on the original message.
Note: None of the parameters effect the packet it self
only the calculated hash value.
Parameters: For all masks default is all "1:s", to disable a field
use mask 0. For IPv6 it's just the last 32 bits that
is included in the hash.
--hmark-smask value
The value to AND the source address with (saddr & value).
--hmark-dmask value
The value to AND the dest. address with (daddr & value).
--hmark-sp-mask value
A 16 bit value to AND the src port with (sport & value).
--hmark-dp-mask value
A 16 bit value to AND the dest port with (dport & value).
--hmark-sp-set value
A 16 bit value to OR the src port with (sport | value).
--hmark-dp-set value
A 16 bit value to OR the dest port with (dport | value).
--hmark-spi-mask value
Value to AND the spi field with (spi & value) valid for proto esp or ah.
--hmark-spi-set value
Value to OR the spi field with (spi | value) valid for proto esp or ah.
--hmark-proto-mask value
A 16 bit value to AND the L4 proto field with (proto & value).
--hmark-rnd value
A 32 bit intitial value for hash calc, default is 0xc175a3b8.
--hmark-dnat
Replace src addr/port with original dst addr/port before calc, hash
--hmark-snat
Replace dst addr/port with original src addr/port before calc, hash
Final processing of the mark in order of execution.
--hmark-mod value (must be > 0)
The easiest way to describe this is: hash = hash mod <value>
--hmark-offs alue (must be > 0)
The easiest way to describe this is: hash = hash + <value>
Examples:
Default rule handles all TCP, UDP, SCTP, ESP & AH
Rev 2
IPv6 header scan changed to follow RFC 2640
IPv4 icmp echo fragmented does now use proto as ipv6
IPv6 pskb_may_pull() check is done in every time in header loop.
IPv4 nat support added.
default added in IPv6 loop and null check of hp
Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
---
include/linux/netfilter/xt_hmark.h | 48 ++++++
net/netfilter/Kconfig | 17 ++
net/netfilter/Makefile | 1 +
net/netfilter/xt_hmark.c | 320 ++++++++++++++++++++++++++++++++++++
4 files changed, 386 insertions(+), 0 deletions(-)
create mode 100644 include/linux/netfilter/xt_hmark.h
create mode 100644 net/netfilter/xt_hmark.c
diff --git a/include/linux/netfilter/xt_hmark.h b/include/linux/netfilter/xt_hmark.h
new file mode 100644
index 0000000..6c1436a
--- /dev/null
+++ b/include/linux/netfilter/xt_hmark.h
@@ -0,0 +1,48 @@
+#ifndef XT_HMARK_H_
+#define XT_HMARK_H_
+
+#include <linux/types.h>
+
+/*
+ * Flags must not start at 0, since it's used as none.
+ */
+enum {
+ XT_HMARK_SADR_AND = 1, /* SNAT & DNAT are used by the kernel module */
+ XT_HMARK_DADR_AND,
+ XT_HMARK_SPI_AND,
+ XT_HMARK_SPI_OR,
+ XT_HMARK_SPORT_AND,
+ XT_HMARK_DPORT_AND,
+ XT_HMARK_SPORT_OR,
+ XT_HMARK_DPORT_OR,
+ XT_HMARK_PROTO_AND,
+ XT_HMARK_RND,
+ XT_HMARK_MODULUS,
+ XT_HMARK_OFFSET,
+ XT_HMARK_USE_SNAT,
+ XT_HMARK_USE_DNAT,
+};
+
+union ports {
+ struct {
+ __u16 src;
+ __u16 dst;
+ } p16;
+ __u32 v32;
+};
+
+struct xt_hmark_info {
+ __u32 smask; /* Source address mask */
+ __u32 dmask; /* Dest address mask */
+ union ports pmask;
+ union ports pset;
+ __u32 spimask;
+ __u32 spiset;
+ __u16 flags; /* Print out only */
+ __u16 prmask; /* L4 Proto mask */
+ __u32 hashrnd;
+ __u32 hmod; /* Modulus */
+ __u32 hoffs; /* Offset */
+};
+
+#endif /* XT_HMARK_H_ */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 32bff6d..3abd3a4 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -483,6 +483,23 @@ config NETFILTER_XT_TARGET_IDLETIMER
To compile it as a module, choose M here. If unsure, say N.
+config NETFILTER_XT_TARGET_HMARK
+ tristate '"HMARK" target support'
+ depends on NETFILTER_ADVANCED
+ ---help---
+ This option adds the "HMARK" target.
+
+ The target allows you to create rules in the "raw" and "mangle" tables
+ which alter the netfilter mark (nfmark) field within a given range.
+ First a 32 bit hash value is generated then modulus by <limit> and
+ finally an offset is added before it's written to nfmark.
+
+ Prior to routing, the nfmark can influence the routing method (see
+ "Use netfilter MARK value as routing key") and can also be used by
+ other subsystems to change their behavior.
+
+ The mark match can also be used to match nfmark produced by this module.
+
config NETFILTER_XT_TARGET_LED
tristate '"LED" target support'
depends on LEDS_CLASS && LEDS_TRIGGERS
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 1a02853..359eeb6 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_hmark.o
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
diff --git a/net/netfilter/xt_hmark.c b/net/netfilter/xt_hmark.c
new file mode 100644
index 0000000..2f0aa93
--- /dev/null
+++ b/net/netfilter/xt_hmark.c
@@ -0,0 +1,320 @@
+/*
+ * xt_hmark - Netfilter module to set mark as hash value
+ *
+ * (C) 2010 Hans Schillstrom <hans.schillstrom@ericsson.com>
+ *
+ * Description:
+ * This module calculates a hash value that can be modified by modulus
+ * and an offset. The hash value is based on a direction independent
+ * five tuple: src & dst addr src & dst ports and protocol.
+ * However src & dst port can be masked and are not used for fragmented
+ * packets, ESP and AH don't have ports so SPI will be used instead.
+ * For ICMP error messages the hash mark values will be calculated on
+ * the source packet i.e. the packet caused the error (If sufficient
+ * amount of data exists).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <net/ip.h>
+#include <linux/icmp.h>
+
+#include <linux/netfilter/xt_hmark.h>
+#include <linux/netfilter/x_tables.h>
+#include <net/netfilter/nf_nat.h>
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+# define WITH_IPV6 1
+#include <net/ipv6.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#endif
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Hans Schillstrom <hans.schillstrom@ericsson.com>");
+MODULE_DESCRIPTION("Xtables: packet range mark operations by hash value");
+MODULE_ALIAS("ipt_HMARK");
+MODULE_ALIAS("ip6t_HMARK");
+
+/*
+ * ICMP, get inner header so calc can be made on the source message
+ * not the icmp header, i.e. same hash mark must be produced
+ * on an icmp error message.
+ */
+static int get_inner_hdr(struct sk_buff *skb, int iphsz, int nhoff)
+{
+ const struct icmphdr *icmph;
+ struct icmphdr _ih;
+ struct iphdr *iph = NULL;
+
+ /* Not enough header? */
+ icmph = skb_header_pointer(skb, nhoff + iphsz, sizeof(_ih), &_ih);
+ if (icmph == NULL)
+ goto out;
+
+ if (icmph->type > NR_ICMP_TYPES)
+ goto out;
+
+
+ /* Error message? */
+ if (icmph->type != ICMP_DEST_UNREACH &&
+ icmph->type != ICMP_SOURCE_QUENCH &&
+ icmph->type != ICMP_TIME_EXCEEDED &&
+ icmph->type != ICMP_PARAMETERPROB &&
+ icmph->type != ICMP_REDIRECT)
+ goto out;
+ /* Checkin full IP header plus 8 bytes of protocol to
+ * avoid additional coding at protocol handlers.
+ */
+ if (!pskb_may_pull(skb, nhoff + iphsz + sizeof(_ih) + 8))
+ goto out;
+
+ iph = (struct iphdr *)(skb->data + nhoff + iphsz + sizeof(_ih));
+ return nhoff + iphsz + sizeof(_ih);
+out:
+ return nhoff;
+}
+/*
+ * ICMPv6
+ * Input nhoff Offset into network header
+ * offset where ICMPv6 header starts
+ * Returns true if it's a icmp error and updates nhoff
+ */
+#ifdef WITH_IPV6
+static int get_inner6_hdr(struct sk_buff *skb, int *offset, int hdrlen)
+{
+ struct icmp6hdr *icmp6h;
+ struct icmp6hdr _ih6;
+
+ icmp6h = skb_header_pointer(skb, *offset + hdrlen, sizeof(_ih6), &_ih6);
+ if (icmp6h == NULL)
+ goto out;
+
+ if (icmp6h->icmp6_type && icmp6h->icmp6_type < 128) {
+ *offset += hdrlen + sizeof(_ih6);
+ return 1;
+ }
+out:
+ return 0;
+}
+#endif
+
+/*
+ * Calc hash value, special casre is taken on icmp and fragmented messages
+ * i.e. fragmented messages don't use ports.
+ */
+static __u32 get_hash(struct sk_buff *skb, struct xt_hmark_info *info)
+{
+ int nhoff, hash = 0, poff, proto, frag = 0;
+ struct iphdr *ip;
+ u8 ip_proto;
+ u32 addr1, addr2, ihl;
+ u16 snatport = 0, dnatport = 0;
+ union {
+ u32 v32;
+ u16 v16[2];
+ } ports;
+
+ nhoff = skb_network_offset(skb);
+ proto = skb->protocol;
+
+ if (!proto && skb->sk) {
+ if (skb->sk->sk_family == AF_INET)
+ proto = __constant_htons(ETH_P_IP);
+ else if (skb->sk->sk_family == AF_INET6)
+ proto = __constant_htons(ETH_P_IPV6);
+ }
+
+ switch (proto) {
+ case __constant_htons(ETH_P_IP):
+ {
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo);
+ struct nf_conntrack_tuple *otuple, *rtuple;
+
+ if (!pskb_may_pull(skb, sizeof(*ip) + nhoff))
+ goto done;
+
+ ip = (struct iphdr *) (skb->data + nhoff);
+ if (ip->protocol == IPPROTO_ICMP) {
+ /* Switch hash calc to inner header ? */
+ nhoff = get_inner_hdr(skb, ip->ihl * 4, nhoff);
+ ip = (struct iphdr *) (skb->data + nhoff);
+ }
+
+ if (ip->frag_off & htons(IP_MF | IP_OFFSET))
+ frag = 1;
+
+ ip_proto = ip->protocol;
+ ihl = ip->ihl;
+ addr1 = (__force u32) ip->saddr & info->smask;
+ addr2 = (__force u32) ip->daddr & info->dmask;
+
+ if (!ct || !nf_ct_is_confirmed(ct))
+ break;
+ otuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
+ /* On the "return flow", to get the original address
+ * i,e, replace the source address.
+ */
+ if (ct->status & IPS_DST_NAT &&
+ info->flags & XT_HMARK_USE_DNAT) {
+ rtuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+ addr1 = (__force u32) otuple->dst.u3.in.s_addr;
+ dnatport = otuple->dst.u.udp.port;
+ }
+ /* On the "return flow", to get the original address
+ * i,e, replace the destination address.
+ */
+ if (ct->status & IPS_SRC_NAT &&
+ info->flags & XT_HMARK_USE_SNAT) {
+ rtuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+ addr2 = (__force u32) otuple->src.u3.in.s_addr;
+ snatport = otuple->src.u.udp.port;
+ }
+ break;
+ }
+#ifdef WITH_IPV6
+ case __constant_htons(ETH_P_IPV6):
+ {
+ struct ipv6hdr *ip6; /* ip hdr */
+ int hdrlen = 0; /* In ip header */
+ u8 nexthdr;
+ int ip6hdrlvl = 0; /* Header level */
+ struct ipv6_opt_hdr _hdr, *hp;
+
+hdr_new:
+ if (!pskb_may_pull(skb, sizeof(*ip6) + nhoff))
+ goto done;
+
+ /* ip header */
+ ip6 = (struct ipv6hdr *) (skb->data + nhoff);
+ nexthdr = ip6->nexthdr;
+ /* nhoff += sizeof(struct ipv6hdr); Where hdr starts */
+ hdrlen = sizeof(struct ipv6hdr);
+ hp = skb_header_pointer(skb, nhoff + hdrlen, sizeof(_hdr),
+ &_hdr);
+ while (nexthdr) {
+ switch (nexthdr) {
+ case IPPROTO_ICMPV6:
+ /* ICMP Error then move ptr to inner header */
+ if (get_inner6_hdr(skb, &nhoff, hdrlen)) {
+ ip6hdrlvl++;
+ goto hdr_new;
+ }
+ nhoff += hdrlen;
+ goto hdr_rdy;
+
+ case NEXTHDR_FRAGMENT:
+ if (!ip6hdrlvl)
+ frag = 1;
+ break;
+ /* End of hdr traversing */
+ case NEXTHDR_IPV6: /* Do not process tunnels */
+ case NEXTHDR_TCP:
+ case NEXTHDR_UDP:
+ case NEXTHDR_ESP:
+ case NEXTHDR_AUTH:
+ case NEXTHDR_NONE:
+ nhoff += hdrlen;
+ goto hdr_rdy;
+ default:
+ goto done;
+ }
+ if (!hp)
+ goto done;
+ nhoff += hdrlen; /* eat current header */
+ nexthdr = hp->nexthdr; /* Next header */
+ hdrlen = ipv6_optlen(hp);
+ hp = skb_header_pointer(skb, nhoff + hdrlen,
+ sizeof(_hdr), &_hdr);
+
+ if (!pskb_may_pull(skb, nhoff))
+ goto done;
+ }
+hdr_rdy:
+ ip_proto = nexthdr;
+
+ addr1 = (__force u32) ip6->saddr.s6_addr32[3];
+ addr2 = (__force u32) ip6->daddr.s6_addr32[3];
+ ihl = 0; /* (40 >> 2); */
+ break;
+ }
+#endif
+ default:
+ goto done;
+ }
+
+ ports.v32 = 0;
+ poff = proto_ports_offset(ip_proto);
+ nhoff += ihl * 4 + poff;
+ if (!frag && poff >= 0 && pskb_may_pull(skb, nhoff + 4)) {
+ ports.v32 = * (__force u32 *) (skb->data + nhoff);
+ if (ip_proto == IPPROTO_ESP || ip_proto == IPPROTO_AH) {
+ ports.v32 = (ports.v32 & info->spimask) | info->spiset;
+ } else { /* Handle endian */
+ if (snatport) /* Replace snated dst port (ret flow) */
+ ports.v16[1] = snatport;
+ if (dnatport)
+ ports.v16[0] = dnatport;
+ ports.v32 = (ports.v32 & info->pmask.v32) |
+ info->pset.v32;
+ if (ports.v16[1] < ports.v16[0])
+ swap(ports.v16[0], ports.v16[1]);
+ }
+ }
+ ip_proto &= info->prmask;
+ /* get a consistent hash (same value on both flow directions) */
+ if (addr2 < addr1)
+ swap(addr1, addr2);
+
+ hash = jhash_3words(addr1, addr2, ports.v32, info->hashrnd) ^ ip_proto;
+ if (!hash)
+ hash = 1;
+
+ return hash;
+
+done:
+ return 0;
+}
+
+static unsigned int
+hmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
+{
+ struct xt_hmark_info *info = (struct xt_hmark_info *)par->targinfo;
+ __u32 hash = get_hash(skb, info);
+
+ if (info->hmod && hash)
+ skb->mark = (hash % info->hmod) + info->hoffs;
+ return XT_CONTINUE;
+}
+
+static struct xt_target hmark_tg_reg __read_mostly = {
+ .name = "HMARK",
+ .revision = 0,
+ .family = NFPROTO_UNSPEC,
+ .target = hmark_tg,
+ .targetsize = sizeof(struct xt_hmark_info),
+ .me = THIS_MODULE,
+};
+
+static int __init hmark_mt_init(void)
+{
+ int ret;
+
+ ret = xt_register_target(&hmark_tg_reg);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static void __exit hmark_mt_exit(void)
+{
+ xt_unregister_target(&hmark_tg_reg);
+}
+
+module_init(hmark_mt_init);
+module_exit(hmark_mt_exit);
--
1.7.4.4
^ permalink raw reply related
* [v2 PATCH 2/2] NETFILTER userspace part for target HMARK
From: Hans Schillstrom @ 2011-10-03 17:46 UTC (permalink / raw)
To: kaber, pablo, jengelh, netfilter-devel, netdev; +Cc: hans, Hans Schillstrom
In-Reply-To: <1317664003-28189-1-git-send-email-hans.schillstrom@ericsson.com>
The target allows you to create rules in the "raw" and "mangle" tables
which alter the netfilter mark (nfmark) field within a given range.
First a 32 bit hash value is generated then modulus by <limit> and
finally an offset is added before it's written to nfmark.
Prior to routing, the nfmark can influence the routing method (see
"Use netfilter MARK value as routing key") and can also be used by
other subsystems to change their behaviour.
The mark match can also be used to match nfmark produced by this module.
Ver 2
IPv4 NAT added
iptables ver 1.4.12.1 adaptions.
Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
---
extensions/libxt_HMARK.c | 381 ++++++++++++++++++++++++++++++++++++
extensions/libxt_HMARK.man | 66 ++++++
include/linux/netfilter/xt_hmark.h | 48 +++++
3 files changed, 495 insertions(+), 0 deletions(-)
create mode 100644 extensions/libxt_HMARK.c
create mode 100644 extensions/libxt_HMARK.man
create mode 100644 include/linux/netfilter/xt_hmark.h
diff --git a/extensions/libxt_HMARK.c b/extensions/libxt_HMARK.c
new file mode 100644
index 0000000..0def034
--- /dev/null
+++ b/extensions/libxt_HMARK.c
@@ -0,0 +1,381 @@
+/*
+ * Shared library add-on to iptables to add HMARK target support.
+ *
+ * The kernel module calculates a hash value that can be modified by modulus
+ * and an offset. The hash value is based on a direction independent
+ * five tuple: src & dst addr src & dst ports and protocol.
+ * However src & dst port can be masked and are not used for fragmented
+ * packets, ESP and AH don't have ports so SPI will be used instead.
+ * For ICMP error messages the hash mark values will be calculated on
+ * the source packet i.e. the packet caused the error (If sufficient
+ * amount of data exists).
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <xtables.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_hmark.h>
+
+
+#define DEF_HRAND 0xc175a3b8 /* Default "random" value to jhash */
+
+static void HMARK_help(void)
+{
+ printf(
+"HMARK target options, i.e. modify hash calculation by:\n"
+" --hmark-smask value Mask source address with value\n"
+" --hmark-dmask value Mask Dest. address with value\n"
+" --hmark-sp-mask value Mask src port with value\n"
+" --hmark-dp-mask value Mask dst port with value\n"
+" --hmark-spi-mask value For esp and ah AND spi with value\n"
+" --hmark-sp-set value OR src port with value\n"
+" --hmark-dp-set value OR dst port with value\n"
+" --hmark-spi-set value For esp and ah OR spi with value\n"
+" --hmark-proto-mask value Mask Protocol with value\n"
+" --hmark-rnd Random value to hash cacl.\n"
+" Limit/modify the calculated hash mark by:\n"
+" --hmark-mod value nfmark modulus value\n"
+" --hmark-offs value Last action add value to nfmark\n"
+" For NAT in IPv4 the original address can be used in the return path.\n"
+" Make sure to qualify the statement in a proper way when using nat flags\n"
+" --hmark-dnat Replace src addr/port with original dst addr/port\n"
+" --hmark-snat Replace dst addr/port with original src addr/port\n"
+" In many cases hmark can be omitted i.e. --smask can be used\n");
+}
+
+static const struct option HMARK_opts[] = {
+ { "hmark-smask", 1, NULL, XT_HMARK_SADR_AND },
+ { "hmark-dmask", 1, NULL, XT_HMARK_DADR_AND },
+ { "hmark-sp-mask", 1, NULL, XT_HMARK_SPORT_AND },
+ { "hmark-dp-mask", 1, NULL, XT_HMARK_DPORT_AND },
+ { "hmark-spi-mask", 1, NULL, XT_HMARK_SPI_AND },
+ { "hmark-sp-set", 1, NULL, XT_HMARK_SPORT_OR },
+ { "hmark-dp-set", 1, NULL, XT_HMARK_DPORT_OR },
+ { "hmark-spi-set", 1, NULL, XT_HMARK_SPI_OR },
+ { "hmark-proto-mask", 1, NULL, XT_HMARK_PROTO_AND },
+ { "hmark-rnd", 1, NULL, XT_HMARK_RND },
+ { "hmark-mod", 1, NULL, XT_HMARK_MODULUS },
+ { "hmark-offs", 1, NULL, XT_HMARK_OFFSET },
+ { "hmark-dnat", 1, NULL, XT_HMARK_USE_DNAT },
+ { "hmark-snat", 1, NULL, XT_HMARK_USE_SNAT },
+ { "smask", 1, NULL, XT_HMARK_SADR_AND },
+ { "dmask", 1, NULL, XT_HMARK_DADR_AND },
+ { "sp-mask", 1, NULL, XT_HMARK_SPORT_AND },
+ { "dp-mask", 1, NULL, XT_HMARK_DPORT_AND },
+ { "spi-mask", 1, NULL, XT_HMARK_SPI_AND },
+ { "sp-set", 1, NULL, XT_HMARK_SPORT_OR },
+ { "dp-set", 1, NULL, XT_HMARK_DPORT_OR },
+ { "spi-set", 1, NULL, XT_HMARK_SPI_OR },
+ { "proto-mask", 1, NULL, XT_HMARK_PROTO_AND },
+ { "rnd", 1, NULL, XT_HMARK_RND },
+ { "mod", 1, NULL, XT_HMARK_MODULUS },
+ { "offs", 1, NULL, XT_HMARK_OFFSET },
+ { "dnat", 1, NULL, XT_HMARK_USE_DNAT },
+ { "snat", 1, NULL, XT_HMARK_USE_SNAT },
+ { .name = NULL }
+};
+
+static int
+HMARK_parse(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_target **target)
+{
+ struct xt_hmark_info *hmarkinfo
+ = (struct xt_hmark_info *)(*target)->data;
+ unsigned int value = 0xffffffff;
+ unsigned int maxint = UINT32_MAX;
+
+ if ((c < XT_HMARK_SADR_AND) || (c > XT_HMARK_OFFSET)) {
+ xtables_error(PARAMETER_PROBLEM, "Bad HMARK option \"%s\"",
+ optarg);
+ return 0;
+ }
+
+ if (c >= XT_HMARK_SPORT_AND && c <= XT_HMARK_DPORT_OR)
+ maxint = UINT16_MAX;
+ else if (c == XT_HMARK_PROTO_AND)
+ maxint = UINT8_MAX;
+
+ if (!xtables_strtoui(optarg, NULL, &value, 0, maxint))
+ xtables_error(PARAMETER_PROBLEM, "Bad HMARK value \"%s\"",
+ optarg);
+
+ if (*flags == 0) {
+ memset(hmarkinfo, 0xff, sizeof(struct xt_hmark_info));
+ hmarkinfo->pset.v32 = 0;
+ hmarkinfo->flags = 0;
+ hmarkinfo->spiset = 0;
+ hmarkinfo->hoffs = 0;
+ hmarkinfo->hashrnd = DEF_HRAND;
+ }
+ switch (c) {
+ case XT_HMARK_SADR_AND:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify "
+ "`--hmark-smask' once");
+ }
+ hmarkinfo->smask = htonl(value);
+ if (value == maxint)
+ c = 0;
+ break;
+
+ case XT_HMARK_DADR_AND:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify "
+ "`--hmark-dmask' once");
+ }
+ hmarkinfo->dmask = htonl(value);
+ if (value == maxint)
+ c = 0;
+ break;
+
+ case XT_HMARK_MODULUS:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify "
+ "`--hmark-mod' once");
+ }
+ if (value == 0) {
+ xtables_error(PARAMETER_PROBLEM,
+ "xxx modulus 0 ? "
+ "thats a div by 0");
+ value = 0xffffffff;
+ }
+ hmarkinfo->hmod = value;
+ if (value == maxint)
+ c = 0;
+ break;
+
+ case XT_HMARK_OFFSET:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify "
+ "`--hmark-offs' once");
+ }
+ hmarkinfo->hoffs = value;
+ if (value == 0)
+ c = 0;
+ break;
+
+ case XT_HMARK_SPORT_AND:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify "
+ "`--hmark-sp-mask' once");
+ }
+ hmarkinfo->pmask.p16.src = htons(value);
+ if (value == maxint)
+ c = 0;
+ break;
+
+ case XT_HMARK_DPORT_AND:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify "
+ "`--hmark-dp-mask' once");
+ }
+ hmarkinfo->pmask.p16.dst = htons(value);
+ if (value == maxint)
+ c = 0;
+ break;
+
+ case XT_HMARK_SPI_AND:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify "
+ "`--hmark-spi-mask' once");
+ }
+ hmarkinfo->spimask = htonl(value);
+ if (value == maxint)
+ c = 0;
+ break;
+
+ case XT_HMARK_SPORT_OR:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify "
+ "`--hmark-sp-set' once");
+ }
+ hmarkinfo->pset.p16.src = htons(value);
+ if (!value)
+ c = 0;
+ break;
+
+ case XT_HMARK_DPORT_OR:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify "
+ "`--hmark-dp-set' once");
+ }
+ hmarkinfo->pset.p16.dst = htons(value);
+ if (!value)
+ c = 0;
+ break;
+
+ case XT_HMARK_SPI_OR:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify "
+ "`--hmark-spi-set' once");
+ }
+ hmarkinfo->spiset = htonl(value);
+ if (!value)
+ c = 0;
+ break;
+
+ case XT_HMARK_PROTO_AND:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify "
+ "`--hmark-proto-mask' once");
+ }
+ hmarkinfo->prmask = value;
+ if (value == maxint)
+ c = 0;
+ break;
+
+ case XT_HMARK_RND:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify `--hmark-rnd' once");
+ }
+ hmarkinfo->hashrnd = value;
+ if (value == DEF_HRAND)
+ c = 0;
+ break;
+
+ case XT_HMARK_USE_DNAT:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify `--hmark-rnd' once");
+ }
+ break;
+
+ case XT_HMARK_USE_SNAT:
+ if (*flags & (1 << c)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Can only specify `--hmark-rnd' once");
+ }
+ break;
+
+ default:
+ return 0;
+ }
+ *flags |= 1 << c;
+ hmarkinfo->flags = *flags;
+
+ return 1;
+}
+
+static void HMARK_check(unsigned int flags)
+{
+ if (!(flags & (1 << XT_HMARK_MODULUS)))
+ xtables_error(PARAMETER_PROBLEM, "HMARK: the --hmark-mod, "
+ "is not set, that means the nfmark will be in range"
+ " 0 - 0xffffffff");
+}
+
+static void HMARK_print(const void *ip, const struct xt_entry_target *target,
+ int numeric)
+{
+ const struct xt_hmark_info *info =
+ (const struct xt_hmark_info *)target->data;
+
+ printf(" HMARK ");
+ if (info->flags & (1 << XT_HMARK_USE_SNAT))
+ printf("snat, ");
+ if (info->flags & (1 << XT_HMARK_SADR_AND))
+ printf("smask 0x%x ", htonl(info->smask));
+
+ if (info->flags & (1 << XT_HMARK_USE_DNAT))
+ printf("dnat, ");
+ if (info->flags & (1 << XT_HMARK_DADR_AND))
+ printf("dmask 0x%x ", htonl(info->dmask));
+
+ if (info->flags & (1 << XT_HMARK_SPORT_AND))
+ printf("sp-mask 0x%x ", htons(info->pmask.p16.src));
+ if (info->flags & (1 << XT_HMARK_DPORT_AND))
+ printf("dp-mask 0x%x ", htons(info->pmask.p16.dst));
+ if (info->flags & (1 << XT_HMARK_SPI_AND))
+ printf("spi-mask 0x%x ", htonl(info->spimask));
+ if (info->flags & (1 << XT_HMARK_SPORT_OR))
+ printf("sp-set 0x%x ", htons(info->pset.p16.src));
+ if (info->flags & (1 << XT_HMARK_DPORT_OR))
+ printf("dp-set 0x%x ", htons(info->pset.p16.dst));
+ if (info->flags & (1 << XT_HMARK_SPI_OR))
+ printf("spi-set 0x%x ", htonl(info->spiset));
+ if (info->flags & (1 << XT_HMARK_PROTO_AND))
+ printf("proto-mask 0x%x ", info->prmask);
+ if (info->flags & (1 << XT_HMARK_RND))
+ printf("rnd 0x%x ", info->hashrnd);
+ if (info->flags & (1 << XT_HMARK_MODULUS))
+ printf("mark=hv %% 0x%x ", info->hmod);
+ if (info->flags & (1 << XT_HMARK_OFFSET))
+ printf("+ 0x%x ", info->hoffs);
+}
+
+static void HMARK_save(const void *ip, const struct xt_entry_target *target)
+{
+ const struct xt_hmark_info *info =
+ (const struct xt_hmark_info *)target->data;
+
+ if (info->flags & (1 << XT_HMARK_SADR_AND))
+ printf("--hmark-smask 0x%x ", htonl(info->smask));
+ if (info->flags & (1 << XT_HMARK_DADR_AND))
+ printf("--hmark-dmask 0x%x ", htonl(info->dmask));
+ if (info->flags & (1 << XT_HMARK_SPORT_AND))
+ printf("--hmark-sp-mask 0x%x ", htons(info->pmask.p16.src));
+ if (info->flags & (1 << XT_HMARK_DPORT_AND))
+ printf("--hmark-dp-mask 0x%x ", htons(info->pmask.p16.dst));
+ if (info->flags & (1 << XT_HMARK_SPI_AND))
+ printf("--hmark-spi-mask 0x%x ", htonl(info->spimask));
+ if (info->flags & (1 << XT_HMARK_SPORT_OR))
+ printf("--hmark-sp-set 0x%x ", htons(info->pset.p16.src));
+ if (info->flags & (1 << XT_HMARK_DPORT_OR))
+ printf("--hmark-dp-set 0x%x ", htons(info->pset.p16.dst));
+ if (info->flags & (1 << XT_HMARK_SPI_OR))
+ printf("--hmark-spi-set 0x%x ", htonl(info->spiset));
+ if (info->flags & (1 << XT_HMARK_PROTO_AND))
+ printf("--hmark-proto-mask 0x%x ", info->prmask);
+ if (info->flags & (1 << XT_HMARK_RND))
+ printf("--hmark-rnd 0x%x ", info->hashrnd);
+ if (info->flags & (1 << XT_HMARK_MODULUS))
+ printf("--hmark-mod 0x%x ", info->hmod);
+ if (info->flags & (1 << XT_HMARK_OFFSET))
+ printf("--hmark-offs 0x%x ", info->hoffs);
+ if (info->flags & (1 << XT_HMARK_USE_DNAT))
+ printf("--hmark-dnat ");
+ if (info->flags & (1 << XT_HMARK_USE_SNAT))
+ printf("--hmark-snat ");
+}
+
+static struct xtables_target mark_tg_reg[] = {
+ {
+ .family = NFPROTO_UNSPEC,
+ .name = "HMARK",
+ .version = XTABLES_VERSION,
+ .revision = 0,
+ .size = XT_ALIGN(sizeof(struct xt_hmark_info)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_hmark_info)),
+ .help = HMARK_help,
+ .parse = HMARK_parse,
+ .final_check = HMARK_check,
+ .print = HMARK_print,
+ .save = HMARK_save,
+ .extra_opts = HMARK_opts,
+ },
+};
+
+void _init(void)
+{
+ xtables_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
+}
+
diff --git a/extensions/libxt_HMARK.man b/extensions/libxt_HMARK.man
new file mode 100644
index 0000000..8f44676
--- /dev/null
+++ b/extensions/libxt_HMARK.man
@@ -0,0 +1,66 @@
+This module does the same as MARK, i.e. set an fwmark, but the mark is based on a hash value.
+The hash is based on saddr, daddr, sport, dport and proto. The same mark will be produced independet of direction if no masks is set or the same masks is used for src and dest.
+The hash mark could be adjusted by modulus and finally an offset could be added, i.e the final mark will be within a range. If state RELATED is used icmp will be handled also, i.e. hash will be calculated on the original message not the icmp it self.
+Note: None of the parameters effect the packet it self only the calculated hash value.
+.PP
+Parameters:
+For all masks default is all "1:s", to disable a field use mask 0
+For IPv6 it's just the last 32 bits that is included in the hash
+.TP
+\fB\-\-hmark\-smask\fP \fIvalue\fP
+The value to AND the source address with (saddr & value).
+.TP
+\fB\-\-hmark\-dmask\fP \fIvalue\fP
+The value to AND the dest. address with (daddr & value).
+.TP
+\fB\-\-hmark\-sp\-mask\fP \fIvalue\fP
+A 16 bit value to AND the src port with (sport & value).
+.TP
+\fB\-\-hmark\-dp\-mask\fP \fIvalue\fP
+A 16 bit value to AND the dest port with (dport & value).
+.TP
+\fB\-\-hmark\-sp\-set\fP \fIvalue\fP
+A 16 bit value to OR the src port with (sport | value).
+.TP
+\fB\-\-hmark\-dp\-set\fP \fIvalue\fP
+A 16 bit value to OR the dest port with (dport | value).
+.TP
+\fB\-\-hmark\-spi\-mask\fP \fIvalue\fP
+Value to AND the spi field with (spi & value) valid for proto esp or ah.
+.TP
+\fB\-\-hmark\-spi\-set\fP \fIvalue\fP
+Value to OR the spi field with (spi | value) valid for proto esp or ah.
+.TP
+\fB\-\-hmark\-proto\-mask\fP \fIvalue\fP
+An 8 bit value to AND the L4 proto field with (proto & value).
+.TP
+\fB\-\-hmark\-rnd\fP \fIvalue\fP
+A 32 bit initial value for hash calc, default is 0xc175a3b8.
+.TP
+\fB\-\-hmark\-dnat\fP
+Replace src addr/port with original dst addr/port before calc, hash
+.TP
+\fB\-\-hmark\-dnat\fP
+Replace dst addr/port with original src addr/port before calc, hash
+.PP
+Final processing of the mark in order of execution.
+.TP
+\fB\-\-hmark\-mod\fP \fvalue (must be > 0)\fP
+The easiest way to describe this is: hash = hash mod <value>
+.TP
+\fB\-\-hmark\-offs\fP \fvalue\fP
+The easiest way to describe this is: hash = hash + <value>
+.PP
+\fIExamples:\fP
+.PP
+Default rule handles all TCP, UDP, SCTP, ESP & AH
+.IP
+iptables \-t mangle \-A PREROUTING \-m state \-\-state NEW,ESTABLISHED,RELATED
+ \-j HMARK \-\-hmark-offs 10000 \-\-hmark-mod 10
+.PP
+Handle SCTP and hash dest port only and produce a nfmark between 100-119.
+.IP
+iptables \-t mangle \-A PREROUTING -p SCTP \-j HMARK \-\-smask 0 \-\-dmask 0
+ \-\-sp\-mask 0 \-\-offs 100 \-\-mod 20
+.PP
+
diff --git a/include/linux/netfilter/xt_hmark.h b/include/linux/netfilter/xt_hmark.h
new file mode 100644
index 0000000..7b3ee5d
--- /dev/null
+++ b/include/linux/netfilter/xt_hmark.h
@@ -0,0 +1,48 @@
+#ifndef XT_HMARK_H_
+#define XT_HMARK_H_
+
+#include <linux/types.h>
+
+/*
+ * Flags must not start at 0, since it's used as none.
+ */
+enum {
+ XT_HMARK_USE_SNAT = 1, /* SNAT & DNAT are used by the kernel module */
+ XT_HMARK_USE_DNAT,
+ XT_HMARK_SADR_AND,
+ XT_HMARK_DADR_AND,
+ XT_HMARK_SPI_AND,
+ XT_HMARK_SPI_OR,
+ XT_HMARK_SPORT_AND,
+ XT_HMARK_DPORT_AND,
+ XT_HMARK_SPORT_OR,
+ XT_HMARK_DPORT_OR,
+ XT_HMARK_PROTO_AND,
+ XT_HMARK_RND,
+ XT_HMARK_MODULUS,
+ XT_HMARK_OFFSET,
+};
+
+union ports {
+ struct {
+ __u16 src;
+ __u16 dst;
+ } p16;
+ __u32 v32;
+};
+
+struct xt_hmark_info {
+ __u32 smask; /* Source address mask */
+ __u32 dmask; /* Dest address mask */
+ union ports pmask;
+ union ports pset;
+ __u32 spimask;
+ __u32 spiset;
+ __u16 flags; /* Print out only */
+ __u16 prmask; /* L4 Proto mask */
+ __u32 hashrnd;
+ __u32 hmod; /* Modulus */
+ __u32 hoffs; /* Offset */
+};
+
+#endif /* XT_HMARK_H_ */
--
1.7.4.4
^ permalink raw reply related
* Re: [PATCH net] bonding: properly stop queuing work when requested
From: David Miller @ 2011-10-03 17:48 UTC (permalink / raw)
To: andy; +Cc: netdev
In-Reply-To: <1316811214-15002-1-git-send-email-andy@greyhouse.net>
From: Andy Gospodarek <andy@greyhouse.net>
Date: Fri, 23 Sep 2011 16:53:34 -0400
> During a test where a pair of bonding interfaces using ARP monitoring
> were both brought up and torn down (with an rmmod) repeatedly, a panic
> in the timer code was noticed. I tracked this down and determined that
> any of the bonding functions that ran as workqueue handlers and requeued
> more work might not properly exit when the module was removed.
>
> There was a flag protected by the bond lock called kill_timers that is
> set when the interface goes down or the module is removed, but many of
> the functions that monitor link status now unlock the bond lock to take
> rtnl first. There is a chance that another CPU running the rmmod could
> get the lock and set kill_timers after the first check has passed.
>
> This patch does not allow any function to queue work that will make
> itself run unless kill_timers is not set. I also noticed while doing
> this work that bond_resend_igmp_join_requests did not have a check for
> kill_timers, so I added the needed call there as well.
>
> Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
> Reported-by: Liang Zheng <lzheng@redhat.com>
Applied, thanks Andy.
^ permalink raw reply
* Re: [PATCH] net: sh_eth: fix build failure
From: David Miller @ 2011-10-03 18:00 UTC (permalink / raw)
To: yoshihiro.shimoda.uh; +Cc: sfr, netdev, linux-sh
In-Reply-To: <4E8534A9.3050002@renesas.com>
From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Date: Fri, 30 Sep 2011 12:16:57 +0900
> The following commit removed some including headers:
> "net: sh_eth: move the asm/sh_eth.h to include/linux/"
> (commit id: d4fa0e35fdbd54acf791fa3793d6d17f7795f7ae)
>
> Then, the build failure happened on the linux-next:
...
> This patch fixes the issue. This patch also get back include/kernel.h
> and linux/spinlock.h.
>
> Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next] tcp: report ECN_SEEN in tcp_info
From: David Miller @ 2011-10-03 18:01 UTC (permalink / raw)
To: eric.dumazet; +Cc: shemminger, netdev
In-Reply-To: <1317357897.3274.11.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 30 Sep 2011 06:44:57 +0200
> Allows ss command (iproute2) to display "ecnseen" if at least one packet
> with ECT(0) or ECT(1) or ECN was received by this socket.
>
> "ecn" means ECN was negociated at session establishment (TCP level)
>
> "ecnseen" means we received at least one packet with ECT fields set (IP
> level)
>
> ss -i
> ...
> ESTAB 0 0 192.168.20.110:22 192.168.20.144:38016
> ino:5950 sk:f178e400
> mem:(r0,w0,f0,t0) ts sack ecn ecnseen bic wscale:7,8 rto:210
> rtt:12.5/7.5 cwnd:10 send 9.3Mbps rcv_space:14480
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied, thanks Eric.
^ permalink raw reply
* Re: big picture UDP/IP performance question re 2.6.18 -> 2.6.32
From: starlight @ 2011-10-03 18:02 UTC (permalink / raw)
To: Eric Dumazet
Cc: linux-kernel, netdev, Willy Tarreau, Peter Zijlstra,
Stephen Hemminger
At 06:16 PM 10/3/2011 +0200, Eric Dumazet wrote:
>
>It seems you use 4096 2MB hugepages, and your
>machine has 1GB pages availabe, you could
>try to use them.
>
>(boot cmd : hugepagesz=1GB hugepages=8 )
Tried it and got errno 12 on the segment
allocations. None were allocated, though
the count is six and the largest is exactly
1GB. Don't have time to dig into it.
^ permalink raw reply
* Re: [patch net-next-2.6] Repair wrong named definition aligned_u64
From: David Miller @ 2011-10-03 18:04 UTC (permalink / raw)
To: jzupka; +Cc: netdev, loke.chetan, jpirko
In-Reply-To: <1317384594-17014-1-git-send-email-jzupka@redhat.com>
From: Jiří Župka <jzupka@redhat.com>
Date: Fri, 30 Sep 2011 14:09:54 +0200
> This repairs problem with compile library in userspace (libnl).
>
> Signed-off-by: Jiří Župka <jzupka@redhat.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH next 1/7] bnx2: don't request firmware when there's no userspace.
From: David Miller @ 2011-10-03 18:09 UTC (permalink / raw)
To: romieu; +Cc: netdev, mchan
In-Reply-To: <20110930103652.GB26727@electric-eye.fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri, 30 Sep 2011 12:36:52 +0200
> The firmware is cached during the first successful call to open() and
> released once the network device is unregistered. The driver uses the
> cached firmware between open() and unregister_netdev().
>
> It's similar to 953a12cc2889d1be92e80a2d0bab5ffef4942300 but the
> firmware is mandatory.
>
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Reviewed-by: Michael Chan <mchan@broadcom.com>
Applied.
^ permalink raw reply
* Re: [PATCH next 3/7] atm/iphase : removal of PCI space dereferences.
From: David Miller @ 2011-10-03 18:09 UTC (permalink / raw)
To: romieu; +Cc: netdev
In-Reply-To: <20110930103743.GD26727@electric-eye.fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri, 30 Sep 2011 12:37:43 +0200
> Mostly PHY access and a few (ugly) debug statements for DMA control.
>
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Applied.
^ permalink raw reply
* Re: [PATCH next 4/7] sc92031: use standard #defines from mii.h.
From: David Miller @ 2011-10-03 18:09 UTC (permalink / raw)
To: romieu; +Cc: netdev
In-Reply-To: <20110930103802.GE26727@electric-eye.fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri, 30 Sep 2011 12:38:02 +0200
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Applied.
^ permalink raw reply
* Re: [PATCH next 5/7] rtl8150: removal of forward declarations.
From: David Miller @ 2011-10-03 18:09 UTC (permalink / raw)
To: romieu; +Cc: netdev
In-Reply-To: <20110930103829.GF26727@electric-eye.fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri, 30 Sep 2011 12:38:29 +0200
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Applied.
^ permalink raw reply
* Re: [PATCH next 6/7] drivers/net/ethernet: remove unused #define.
From: David Miller @ 2011-10-03 18:09 UTC (permalink / raw)
To: romieu; +Cc: netdev
In-Reply-To: <20110930103849.GG26727@electric-eye.fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri, 30 Sep 2011 12:38:49 +0200
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Applied.
^ permalink raw reply
* Re: [PATCH next 7/7] tehuti: shorten PCI device table.
From: David Miller @ 2011-10-03 18:10 UTC (permalink / raw)
To: romieu; +Cc: netdev
In-Reply-To: <20110930103923.GH26727@electric-eye.fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri, 30 Sep 2011 12:39:23 +0200
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Applied.
^ permalink raw reply
* Re: [PATCH] ipv4: NET_IPV4_ROUTE_GC_INTERVAL removal
From: David Miller @ 2011-10-03 18:13 UTC (permalink / raw)
To: vvs; +Cc: netdev, vvs
In-Reply-To: <1317381070-19564-1-git-send-email-vvs@parallels.com>
From: Vasily Averin <vvs@parallels.com>
Date: Fri, 30 Sep 2011 15:11:10 +0400
> From: Vasily Averin <vvs@sw.ru>
>
> removing obsoleted sysctl,
> ip_rt_gc_interval variable no longer used since 2.6.38
>
> Signed-off-by: Vasily Averin <vvs@sw.ru>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] net: xen-netback: correctly restart Tx after a VM restore/migrate
From: David Miller @ 2011-10-03 18:16 UTC (permalink / raw)
To: Ian.Campbell; +Cc: david.vrabel, netdev, xen-devel
In-Reply-To: <1317401105.26672.319.camel@zakaz.uk.xensource.com>
From: Ian Campbell <Ian.Campbell@eu.citrix.com>
Date: Fri, 30 Sep 2011 17:45:05 +0100
> On Fri, 2011-09-30 at 17:37 +0100, David Vrabel wrote:
>> If a VM is saved and restored (or migrated) the netback driver will no
>> longer process any Tx packets from the frontend. xenvif_up() does not
>> schedule the processing of any pending Tx requests from the front end
>> because the carrier is off. Without this initial kick the frontend
>> just adds Tx requests to the ring without raising an event (until the
>> ring is full).
>>
>> This was caused by 47103041e91794acdbc6165da0ae288d844c820b (net:
>> xen-netback: convert to hw_features) which reordered the calls to
>> xenvif_up() and netif_carrier_on() in xenvif_connect().
>
> Ah, so the bit of that patch which moved "netif_carrier_on(vif->dev);"
> should have actually moved the entire block
> netif_carrier_on(vif->dev);
> if (netif_running(vif->dev))
> xenvif_up(vif);
>
> Since it it is logically a single thing. Make sense. Thanks!
>
>> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
>
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
Applied, thanks.
^ permalink raw reply
* Re: [patch] make PACKET_STATISTICS getsockopt report consistently between ring and non-ring
From: David Miller @ 2011-10-03 18:18 UTC (permalink / raw)
To: willemb; +Cc: netdev
In-Reply-To: <4E8628C4.2070504@google.com>
From: Willem de Bruijn <willemb@google.com>
Date: Fri, 30 Sep 2011 16:38:28 -0400
> This is a minor change.
>
> Up until kernel 2.6.32, getsockopt(fd, SOL_PACKET, PACKET_STATISTICS,
> ...) would return total and dropped packets since its last invocation. The
> introduction of socket queue overflow reporting [1] changed drop
> rate calculation in the normal packet socket path, but not when using a
> packet ring. As a result, the getsockopt now returns different statistics
> depending on the reception method used. With a ring, it still returns the
> count since the last call, as counts are incremented in tpacket_rcv and
> reset in getsockopt. Without a ring, it returns 0 if no drops occurred
> since the last getsockopt and the total drops over the lifespan of
> the socket otherwise. The culprit is this line in packet_rcv, executed
> on a drop:
>
> drop_n_acct:
> po->stats.tp_drops = atomic_inc_return(&sk->sk_drops);
>
> As it shows, the new drop number it taken from the socket drop counter,
> which is not reset at getsockopt. I put together a small example
> that demonstrates the issue [2]. It runs for 10 seconds and overflows
> the queue/ring on every odd second. The reported drop rates are:
> ring: 16, 0, 16, 0, 16, ...
> non-ring: 0, 15, 0, 30, 0, 46, 0, 60, 0 , 74.
>
> Note how the even ring counts monotonically increase. Because the
> getsockopt adds tp_drops to tp_packets, total counts are similarly
> reported cumulatively. Long story short, reinstating the original code, as
> the below patch does, fixes the issue at the cost of additional per-packet
> cycles. Another solution that does not introduce per-packet overhead
> is be to keep the current data path, record the value of sk_drops at
> getsockopt() at call N in a new field in struct packetsock and subtract
> that when reporting at call N+1. I'll be happy to code that, instead,
> it's just more messy.
>
> [1] http://patchwork.ozlabs.org/patch/35665/
> [2] http://kernel.googlecode.com/files/test-packetsock-getstatistics.c
>
> Signed-off-by: Willem de Bruijn <willemb@google.com>
Applied, thanks a lot for fixing this bug.
^ permalink raw reply
* Re: [PATCH v2 1/2] virtio-net: Verify page list size before fitting into skb
From: David Miller @ 2011-10-03 18:19 UTC (permalink / raw)
To: levinsasha928; +Cc: linux-kernel, rusty, mst, virtualization, netdev, kvm
In-Reply-To: <1317220855-9352-1-git-send-email-levinsasha928@gmail.com>
From: Sasha Levin <levinsasha928@gmail.com>
Date: Wed, 28 Sep 2011 17:40:54 +0300
> This patch verifies that the length of a buffer stored in a linked list
> of pages is small enough to fit into a skb.
>
> If the size is larger than a max size of a skb, it means that we shouldn't
> go ahead building skbs anyway since we won't be able to send the buffer as
> the user requested.
>
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: virtualization@lists.linux-foundation.org
> Cc: netdev@vger.kernel.org
> Cc: kvm@vger.kernel.org
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
Michael, tell me what's happening with these two virtio-net bug fixes.
Thanks.
^ permalink raw reply
* Re: [PATCH 2/2] pch_gbe: Fixed the issue on which a network freezes
From: David Miller @ 2011-10-03 18:25 UTC (permalink / raw)
To: toshiharu-linux
Cc: netdev, linux-kernel, eric.dumazet, qi.wang, yong.y.wang,
joel.clark, kok.howg.ewe, tomoya-linux
In-Reply-To: <1317022063-12143-2-git-send-email-toshiharu-linux@dsn.okisemi.com>
From: Toshiharu Okada <toshiharu-linux@dsn.okisemi.com>
Date: Mon, 26 Sep 2011 16:27:43 +0900
> The pch_gbe driver has an issue which a network stops,
> when receiving traffic is high.
> In the case, The link down and up are necessary to return a network.
>
> This patch fixed this issue.
>
> Signed-off-by: Toshiharu Okada <toshiharu-linux@dsn.okisemi.com>
Applied.
^ permalink raw reply
* Re: [PATCH 1/2] pch_gbe: Fixed the issue on which PC was frozen when link was downed.
From: David Miller @ 2011-10-03 18:25 UTC (permalink / raw)
To: toshiharu-linux
Cc: netdev, linux-kernel, eric.dumazet, qi.wang, yong.y.wang,
joel.clark, kok.howg.ewe, tomoya-linux
In-Reply-To: <1317022063-12143-1-git-send-email-toshiharu-linux@dsn.okisemi.com>
From: Toshiharu Okada <toshiharu-linux@dsn.okisemi.com>
Date: Mon, 26 Sep 2011 16:27:42 +0900
> When a link was downed during network use,
> there is an issue on which PC freezes.
>
> This patch fixed this issue.
>
> Signed-off-by: Toshiharu Okada <toshiharu-linux@dsn.okisemi.com>
Applied.
^ permalink raw reply
* Re: [PATCH v2 2/2] virtio-net: Prevent NULL dereference
From: Michael S. Tsirkin @ 2011-10-03 18:40 UTC (permalink / raw)
To: Sasha Levin; +Cc: linux-kernel, Rusty Russell, virtualization, netdev, kvm
In-Reply-To: <1317220855-9352-2-git-send-email-levinsasha928@gmail.com>
On Wed, Sep 28, 2011 at 05:40:55PM +0300, Sasha Levin wrote:
> This patch prevents a NULL dereference when the user has passed a length
> longer than an actual buffer to virtio-net.
>
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: virtualization@lists.linux-foundation.org
> Cc: netdev@vger.kernel.org
> Cc: kvm@vger.kernel.org
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> ---
> drivers/net/virtio_net.c | 12 +++++++++++-
> 1 files changed, 11 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index bde0dec..4a53d2a 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -208,12 +208,22 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
> return NULL;
> }
>
> - while (len) {
> + while (len && page) {
> set_skb_frag(skb, page, offset, &len);
> page = (struct page *)page->private;
> offset = 0;
> }
>
> + /*
> + * This is the case where we ran out of pages in our linked list, but
> + * supposedly have more data to read.
Again, let's clarify that this only happens with broken devices.
> + */
> + if (len > 0) {
> + pr_debug("%s: missing data to assemble skb\n", skb->dev->name);
> + dev_kfree_skb(skb);
> + return NULL;
> + }
> +
> if (page)
> give_pages(vi, page);
>
> --
> 1.7.6.1
^ permalink raw reply
* Re: [PATCH v2 1/2] virtio-net: Verify page list size before fitting into skb
From: Michael S. Tsirkin @ 2011-10-03 18:42 UTC (permalink / raw)
To: David Miller
Cc: levinsasha928, linux-kernel, rusty, virtualization, netdev, kvm
In-Reply-To: <20111003.141951.1122469843900651595.davem@davemloft.net>
On Mon, Oct 03, 2011 at 02:19:51PM -0400, David Miller wrote:
> From: Sasha Levin <levinsasha928@gmail.com>
> Date: Wed, 28 Sep 2011 17:40:54 +0300
>
> > This patch verifies that the length of a buffer stored in a linked list
> > of pages is small enough to fit into a skb.
> >
> > If the size is larger than a max size of a skb, it means that we shouldn't
> > go ahead building skbs anyway since we won't be able to send the buffer as
> > the user requested.
> >
> > Cc: Rusty Russell <rusty@rustcorp.com.au>
> > Cc: "Michael S. Tsirkin" <mst@redhat.com>
> > Cc: virtualization@lists.linux-foundation.org
> > Cc: netdev@vger.kernel.org
> > Cc: kvm@vger.kernel.org
> > Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
>
> Michael, tell me what's happening with these two virtio-net bug fixes.
>
> Thanks.
Thanks for the reminder.
They are more enhancements than bugfixes, in that both help debug buggy
hypervisors. So net-next material.
Patch 1 is ok patch 2 would benefit from a slightly clearer comment.
--
MST
^ permalink raw reply
* Re: [PATCH v2 1/2] virtio-net: Verify page list size before fitting into skb
From: Michael S. Tsirkin @ 2011-10-03 19:04 UTC (permalink / raw)
To: Sasha Levin; +Cc: linux-kernel, Rusty Russell, virtualization, netdev, kvm
In-Reply-To: <1317220855-9352-1-git-send-email-levinsasha928@gmail.com>
On Wed, Sep 28, 2011 at 05:40:54PM +0300, Sasha Levin wrote:
> This patch verifies that the length of a buffer stored in a linked list
> of pages is small enough to fit into a skb.
>
> If the size is larger than a max size of a skb, it means that we shouldn't
> go ahead building skbs anyway since we won't be able to send the buffer as
> the user requested.
>
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: virtualization@lists.linux-foundation.org
> Cc: netdev@vger.kernel.org
> Cc: kvm@vger.kernel.org
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> ---
> drivers/net/virtio_net.c | 13 +++++++++++++
> 1 files changed, 13 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 0c7321c..bde0dec 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -195,6 +195,19 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
> len -= copy;
> offset += copy;
>
> + /*
> + * Verify that we can indeed put this data into a skb.
> + * This is here to handle cases when the device erroneously
> + * tries to receive more than is possible. This is usually
> + * the case of a broken device.
> + */
> + if (unlikely(len > MAX_SKB_FRAGS * PAGE_SIZE)) {
> + if (net_ratelimit())
> + pr_debug("%s: too much data\n", skb->dev->name);
> + dev_kfree_skb(skb);
> + return NULL;
> + }
> +
BTW, receive_mergeable does
pr_debug("%s: packet too long\n", skb->dev->name);
skb->dev->stats.rx_length_errors++;
which makes sense.
> while (len) {
> set_skb_frag(skb, page, offset, &len);
> page = (struct page *)page->private;
> --
> 1.7.6.1
^ permalink raw reply
* Re: [PATCH v2 2/2] virtio-net: Prevent NULL dereference
From: Michael S. Tsirkin @ 2011-10-03 19:05 UTC (permalink / raw)
To: Sasha Levin; +Cc: linux-kernel, Rusty Russell, virtualization, netdev, kvm
In-Reply-To: <1317220855-9352-2-git-send-email-levinsasha928@gmail.com>
On Wed, Sep 28, 2011 at 05:40:55PM +0300, Sasha Levin wrote:
> This patch prevents a NULL dereference when the user has passed a length
> longer than an actual buffer to virtio-net.
>
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: virtualization@lists.linux-foundation.org
> Cc: netdev@vger.kernel.org
> Cc: kvm@vger.kernel.org
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> ---
> drivers/net/virtio_net.c | 12 +++++++++++-
> 1 files changed, 11 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index bde0dec..4a53d2a 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -208,12 +208,22 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
> return NULL;
> }
>
> - while (len) {
> + while (len && page) {
I think if (unlikely(!page))
goto err_page;
would make the logic clearer. But see below
> set_skb_frag(skb, page, offset, &len);
> page = (struct page *)page->private;
> offset = 0;
> }
>
> + /*
> + * This is the case where we ran out of pages in our linked list, but
> + * supposedly have more data to read.
> + */
> + if (len > 0) {
> + pr_debug("%s: missing data to assemble skb\n", skb->dev->name);
> + dev_kfree_skb(skb);
> + return NULL;
> + }
> +
> if (page)
> give_pages(vi, page);
>
I thought about this some more. If length was too large host is
right now writing into pages that we have freed.
That is very bad, and I don't know what do do with it,
really not worth prettifying that IMO, NULL pointer is the least of our
worries.
But, with mergeable buffers at least, and that is the main mode anyway,
there is always a single page per buf, right?
So I think we should change the code,
and for mergeable buffers we shall only verify that
length <= PAGE_SIZE.
IOW copy a bit of code from page_to_skb(vi, page, len)
to receive_mergeable, maybe add a common function
if we need to avoid duplication.
> --
> 1.7.6.1
^ permalink raw reply
* cloning net-next tree (from git-hub ?)
From: Kevin Wilson @ 2011-10-03 19:52 UTC (permalink / raw)
To: netdev
Hi,
According to:
http://lwn.net/Articles/459795/#Comments
There are some github reps for some kernel subsystems because of the
kernel.org outage.
Though this is from 21.9.11, and it could be that since than the
problem was solved, still my question is this:
I do not see in taht link net-next (or any other net) tree.
I want to download the git tree of net-next.
what URL should I use for git clone ?
rgs,
Kevin
^ permalink raw reply
* Re: [PATCH 01/15] add Documentation/namespaces/user_namespace.txt (v3)
From: Eric W. Biederman @ 2011-10-03 19:53 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: Vasiliy Kulikov, Serge Hallyn, akpm, linux-kernel, netdev,
containers, dhowells, rdunlap, kernel-hardening
In-Reply-To: <m1aa9i4zkx.fsf@fess.ebiederm.org>
ebiederm@xmission.com (Eric W. Biederman) writes:
> "Serge E. Hallyn" <serge.hallyn@canonical.com> writes:
>
>> Quoting Vasiliy Kulikov (segoon@openwall.com):
>>> On Tue, Sep 27, 2011 at 08:21 -0500, Serge E. Hallyn wrote:
>>> > > First, the patches by design expose much kernel code to unprivileged
>>> > > userspace processes. This code doesn't expect malformed data (e.g. VFS,
>>> > > specific filesystems, block layer, char drivers, sysadmin part of LSMs,
>>> > > etc. etc.). By relaxing permission rules you greatly increase attack
>>> > > surface of the kernel from unprivileged users. Are you (or somebody
>>> > > else) planning to audit this code?
>
> Well in theory this codes does expose this code to unprivileged user
> space in a way that increases the attack surface. However right now
> there are a lot of cases where because the kernel lacks a sufficient
> mechanism people are just given root provileges so that can get things
> done. Network manager controlling the network stack as an unprivileged
> user. Random filesystems on usb sticks being mounted and unmounted
> automatically when the usb sticks are inserted and removed.
>
> I completely agree that auditing and looking at the code is necessary I
> think most of what will happen is that we will start directly supporting
> how the kernel is actually used in the real world. Which should
> actually reduce our level of vulnerability, because we give up the
> delusion that large classes of operations don't need careful
> attention because only root can perform them. Operations which the
> user space authors turn around and write a suid binary for and
> unprivileged user space performs those operations all day long.
>
>>> > I had wanted to (but didn't) propose a discussion at ksummit about how
>>> > best to approach the filesystem code. That's not even just for user
>>> > namespaces - patches have been floated in the past to make mount an
>>> > unprivileged operation depending on the FS and the user's permission
>>> > over the device and target.
>>>
>>> This is a dangerous operation by itself.
>>
>> Of course it is :) And it's been a while since it has been brought up,
>> but it *was* quite well thought through and throrougly discussed - see
>> i.e. https://lkml.org/lkml/2008/1/8/131
>>
>> Oh, that's right. In the end the reason it didn't go in had to do with
>> the ability for an unprivileged user to prevent a privileged user from
>> unmounting trees by leaving a busy mount in a hidden namespace.
>>
>> Eric, in the past we didn't know what to do about that, but I wonder
>> if setns could be used in some clever way to solve it from userspace.
>
> Oh. That is a good objection. I had not realized that unprivileged
> mounts had that problem.
I just re-read the discussion you are referring to and that wasn't
it. Fuse already has something like a revoke in it's umount -f
implementation.
Eric
^ 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