* [PATCH 2/3] netdev: ARRAY_SIZE() cleanups
From: Alejandro Martinez Ruiz @ 2007-10-18 9:50 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
In-Reply-To: <20071018094706.GA23058@inspiron>
From: Alejandro Martinez Ruiz <alex@flawedcode.org>
Date: Thu, 18 Oct 2007 10:16:33 +0200
Subject: [PATCH] netdev: ARRAY_SIZE() cleanups
Convert array size calculations to use ARRAY_SIZE().
Signed-off-by: Alejandro Martinez Ruiz <alex@flawedcode.org>
---
drivers/net/e1000e/ethtool.c | 3 +--
drivers/net/e1000e/phy.c | 3 +--
drivers/net/ixgbe/ixgbe_ethtool.c | 3 +--
drivers/net/tehuti.c | 2 +-
drivers/net/tulip/de4x5.c | 2 +-
drivers/net/wireless/ipw2100.c | 3 +--
drivers/net/wireless/libertas/11d.c | 24 +++++++-----------------
drivers/net/wireless/libertas/wext.c | 11 +++--------
drivers/net/wireless/wavelan.c | 2 +-
drivers/net/wireless/wavelan_cs.c | 4 ++--
10 files changed, 19 insertions(+), 38 deletions(-)
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 61c84c0..85297cd 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -95,8 +95,7 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
{ "tx_dma_failed", E1000_STAT(tx_dma_failed) },
};
-#define E1000_GLOBAL_STATS_LEN \
- sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
+#define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats)
#define E1000_STATS_LEN (E1000_GLOBAL_STATS_LEN)
static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
"Register test (offline)", "Eeprom test (offline)",
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 7932318..fc6fee1 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -49,8 +49,7 @@ static const u16 e1000_igp_2_cable_length_table[] =
100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121,
124};
#define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
- (sizeof(e1000_igp_2_cable_length_table) / \
- sizeof(e1000_igp_2_cable_length_table[0]))
+ ARRAY_SIZE(e1000_igp_2_cable_length_table)
/**
* e1000e_check_reset_block_generic - Check if PHY reset is blocked
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index a4e576a..3635344 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -96,8 +96,7 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
((((struct ixgbe_adapter *)netdev->priv)->num_tx_queues + \
((struct ixgbe_adapter *)netdev->priv)->num_rx_queues) * \
(sizeof(struct ixgbe_queue_stats) / sizeof(u64)))
-#define IXGBE_GLOBAL_STATS_LEN \
- sizeof(ixgbe_gstrings_stats) / sizeof(struct ixgbe_stats)
+#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats)
#define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN)
static int ixgbe_get_settings(struct net_device *netdev,
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 7334d09..db59c48 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -621,7 +621,7 @@ err:
static void __init bdx_firmware_endianess(void)
{
int i;
- for (i = 0; i < sizeof(s_firmLoad) / sizeof(u32); i++)
+ for (i = 0; i < ARRAY_SIZE(s_firmLoad); i++)
s_firmLoad[i] = CPU_CHIP_SWAP32(s_firmLoad[i]);
}
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index 41f34bb..c5ebf00 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -4175,7 +4175,7 @@ de4x5_bad_srom(struct de4x5_private *lp)
{
int i, status = 0;
- for (i=0; i<sizeof(enet_det)/ETH_ALEN; i++) {
+ for (i=0; i < ARRAY_SIZE(enet_det); i++) {
if (!de4x5_strncmp((char *)&lp->srom, (char *)&enet_det[i], 3) &&
!de4x5_strncmp((char *)&lp->srom+0x10, (char *)&enet_det[i], 3)) {
if (i == 0) {
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 2d46a16..8f5497b 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -6582,8 +6582,7 @@ static const long ipw2100_frequencies[] = {
2472, 2484
};
-#define FREQ_COUNT (sizeof(ipw2100_frequencies) / \
- sizeof(ipw2100_frequencies[0]))
+#define FREQ_COUNT ARRAY_SIZE(ipw2100_frequencies)
static const long ipw2100_rates_11b[] = {
1000000,
diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c
index 9cf0211..8bbd322 100644
--- a/drivers/net/wireless/libertas/11d.c
+++ b/drivers/net/wireless/libertas/11d.c
@@ -46,13 +46,11 @@ static struct chan_freq_power channel_freq_power_UN_BG[] = {
static u8 wlan_region_2_code(u8 * region)
{
u8 i;
- u8 size = sizeof(region_code_mapping)/
- sizeof(struct region_code_mapping);
for (i = 0; region[i] && i < COUNTRY_CODE_LEN; i++)
region[i] = toupper(region[i]);
- for (i = 0; i < size; i++) {
+ for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) {
if (!memcmp(region, region_code_mapping[i].region,
COUNTRY_CODE_LEN))
return (region_code_mapping[i].code);
@@ -65,9 +63,8 @@ static u8 wlan_region_2_code(u8 * region)
static u8 *wlan_code_2_region(u8 code)
{
u8 i;
- u8 size = sizeof(region_code_mapping)
- / sizeof(struct region_code_mapping);
- for (i = 0; i < size; i++) {
+
+ for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) {
if (region_code_mapping[i].code == code)
return (region_code_mapping[i].region);
}
@@ -90,8 +87,7 @@ static u8 wlan_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 * chan)
u8 cfp_no;
cfp = channel_freq_power_UN_BG;
- cfp_no = sizeof(channel_freq_power_UN_BG) /
- sizeof(struct chan_freq_power);
+ cfp_no = ARRAY_SIZE(channel_freq_power_UN_BG);
for (i = 0; i < cfp_no; i++) {
if ((cfp + i)->channel == firstchan) {
@@ -141,16 +137,12 @@ static u8 wlan_channel_known_11d(u8 chan,
u32 libertas_chan_2_freq(u8 chan, u8 band)
{
struct chan_freq_power *cf;
- u16 cnt;
u16 i;
u32 freq = 0;
cf = channel_freq_power_UN_BG;
- cnt =
- sizeof(channel_freq_power_UN_BG) /
- sizeof(struct chan_freq_power);
- for (i = 0; i < cnt; i++) {
+ for (i = 0; i < ARRAY_SIZE(channel_freq_power_UN_BG); i++) {
if (chan == cf[i].channel)
freq = cf[i].freq;
}
@@ -664,8 +656,7 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
if (priv->adapter->enable11d) {
/* update parsed_region_chan_11; dnld domaininf to FW */
- for (j = 0; j < sizeof(adapter->region_channel) /
- sizeof(adapter->region_channel[0]); j++) {
+ for (j = 0; j < ARRAY_SIZE(adapter->region_channel); j++) {
region_chan = &adapter->region_channel[j];
lbs_deb_11d("%d region_chan->band %d\n", j,
@@ -679,8 +670,7 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
break;
}
- if (j >= sizeof(adapter->region_channel) /
- sizeof(adapter->region_channel[0])) {
+ if (j >= ARRAY_SIZE(adapter->region_channel)) {
lbs_deb_11d("region_chan not found, band %d\n",
adapter->curbssparams.band);
ret = -1;
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index c6f5aa3..37b1777 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -34,11 +34,9 @@ struct chan_freq_power *libertas_find_cfp_by_band_and_channel(wlan_adapter * ada
{
struct chan_freq_power *cfp = NULL;
struct region_channel *rc;
- int count = sizeof(adapter->region_channel) /
- sizeof(adapter->region_channel[0]);
int i, j;
- for (j = 0; !cfp && (j < count); j++) {
+ for (j = 0; !cfp && (j < ARRAY_SIZE(adapter->region_channel)); j++) {
rc = &adapter->region_channel[j];
if (adapter->enable11d)
@@ -75,11 +73,9 @@ static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter,
{
struct chan_freq_power *cfp = NULL;
struct region_channel *rc;
- int count = sizeof(adapter->region_channel) /
- sizeof(adapter->region_channel[0]);
int i, j;
- for (j = 0; !cfp && (j < count); j++) {
+ for (j = 0; !cfp && (j < ARRAY_SIZE(adapter->region_channel)); j++) {
rc = &adapter->region_channel[j];
if (adapter->enable11d)
@@ -606,8 +602,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
}
if (!flag) {
for (j = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
- && (j < sizeof(adapter->region_channel)
- / sizeof(adapter->region_channel[0])); j++) {
+ && (j < ARRAY_SIZE(adapter->region_channel)); j++) {
cfp = adapter->region_channel[j].CFP;
for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
&& adapter->region_channel[j].valid
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index a1f8a16..b343ce2 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -3740,7 +3740,7 @@ static int wv_check_ioaddr(unsigned long ioaddr, u8 * mac)
* non-NCR/AT&T/Lucent ISA card. See wavelan.p.h for detail on
* how to configure your card.
*/
- for (i = 0; i < (sizeof(MAC_ADDRESSES) / sizeof(char) / 3); i++)
+ for (i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++)
if ((mac[0] == MAC_ADDRESSES[i][0]) &&
(mac[1] == MAC_ADDRESSES[i][1]) &&
(mac[2] == MAC_ADDRESSES[i][2]))
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 577c647..f5b38de 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -3223,14 +3223,14 @@ wv_mmc_init(struct net_device * dev)
* non-NCR/AT&T/Lucent PCMCIA cards, see wavelan_cs.h for detail on
* how to configure your card...
*/
- for(i = 0; i < (sizeof(MAC_ADDRESSES) / sizeof(char) / 3); i++)
+ for(i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++)
if((psa.psa_univ_mac_addr[0] == MAC_ADDRESSES[i][0]) &&
(psa.psa_univ_mac_addr[1] == MAC_ADDRESSES[i][1]) &&
(psa.psa_univ_mac_addr[2] == MAC_ADDRESSES[i][2]))
break;
/* If we have not found it... */
- if(i == (sizeof(MAC_ADDRESSES) / sizeof(char) / 3))
+ if(i == ARRAY_SIZE(MAC_ADDRESSES))
{
#ifdef DEBUG_CONFIG_ERRORS
printk(KERN_WARNING "%s: wv_mmc_init(): Invalid MAC address: %02X:%02X:%02X:...\n",
--
1.5.3.4
^ permalink raw reply related
* [PATCH 3/3] sk98lin: kill bogus check and convert to use ARRAY_SIZE()
From: Alejandro Martinez Ruiz @ 2007-10-18 9:51 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
In-Reply-To: <20071018094706.GA23058@inspiron>
From: Alejandro Martinez Ruiz <alex@flawedcode.org>
Date: Thu, 18 Oct 2007 10:22:02 +0200
Subject: [PATCH] sk98lin: kill bogus check and convert to use ARRAY_SIZE()
This converts uses of ARRAY_SIZE(), and while at it also kills
unreachable code as far as I can say. I can't tell what was the author
trying to do with the following check. First we have:
PNMI_STATIC const SK_PNMI_STATADDR
StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES];
and then a check goes like this:
if (SK_PNMI_MAX_IDX !=
(sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)))
with the second line being just ARRAY_SIZE(StatAddr), which will always
return SK_PNMI_MAX_IDX, rendering the check useless.
Signed-off-by: Alejandro Martinez Ruiz <alex@flawedcode.org>
---
drivers/net/sk98lin/skgemib.c | 2 +-
drivers/net/sk98lin/skgepnmi.c | 12 ------------
drivers/net/sk98lin/skgesirq.c | 2 +-
3 files changed, 2 insertions(+), 14 deletions(-)
diff --git a/drivers/net/sk98lin/skgemib.c b/drivers/net/sk98lin/skgemib.c
index 0a6f67a..fde4508 100644
--- a/drivers/net/sk98lin/skgemib.c
+++ b/drivers/net/sk98lin/skgemib.c
@@ -82,7 +82,7 @@ PNMI_STATIC int DiagActions(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
/* defines *******************************************************************/
-#define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0]))
+#define ID_TABLE_SIZE ARRAY_SIZE(IdTable)
/* global variables **********************************************************/
diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c
index b36dd9a..3c19d98 100644
--- a/drivers/net/sk98lin/skgepnmi.c
+++ b/drivers/net/sk98lin/skgepnmi.c
@@ -388,18 +388,6 @@ int Level) /* Initialization level */
SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
}
- if (SK_PNMI_MAX_IDX !=
- (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
- ("StatAddr table size (%d) differs from "
- "SK_PNMI_MAX_IDX (%d)\n",
- (sizeof(StatAddr) /
- (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
- SK_PNMI_MAX_IDX));
- }
#endif /* SK_PNMI_CHECK */
break;
diff --git a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c
index 3e7aa49..e5ee6d6 100644
--- a/drivers/net/sk98lin/skgesirq.c
+++ b/drivers/net/sk98lin/skgesirq.c
@@ -892,7 +892,7 @@ int Port) /* Which port should be checked */
*/
RxCts = 0;
- for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(SkGeRxRegs); i++) {
(void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
--
1.5.3.4
^ permalink raw reply related
* Re: [Bugme-new] [Bug 9174] New: linux-2.6.23-git11 kernel panic
From: Patrick McHardy @ 2007-10-18 9:53 UTC (permalink / raw)
To: plamen.petrov; +Cc: Andrew Morton, bugme-daemon, netdev
In-Reply-To: <20071017130131.365f9fb6.akpm@linux-foundation.org>
Andrew Morton wrote:
> On Wed, 17 Oct 2007 07:36:16 -0700 (PDT)
> bugme-daemon@bugzilla.kernel.org wrote:
>
>> http://bugzilla.kernel.org/show_bug.cgi?id=9174
>>
>> Summary: linux-2.6.23-git11 kernel panic
>>
>> EIP is at packet_rcv_0x1a2/0x360
Please find out on which device the packet socket is opened by
looking at /proc/net/packet and comparing the Iface shown there
to the ifindexes listed in "ip link list".
^ permalink raw reply
* [PATCH 0/2] Interface groups, round two
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth
Hello,
Here is the new version of ifgroup patches.
The interface group value is u_int32_t in net_device which should be enough.
Previously it was an int.
Usage:
ip link set eth0 group 4
but currently it cannot be unset, only changed to another value.
In /etc/iproute2/rt_ifgroup each value may have a symbolic name.
Netfilter part: xt_ifgroup module for both IPv4 and IPv6. Iptables usage:
iptables -A INPUT -m ifgroup --in-ifgroup 4/0xf -j ACCEPT
iptables -A FORWARD -m ifgroup --in-ifgroup 4 --out-ifgroup 5 -j ACCEPT
...
in the FORWARD chain both input and output interface group value should be matched
(with optional masks).
The following patches are:
kernel: core part
kernel: netfilter module, ifgroup match
iproute2: showing and set ifgroup value
iptables: ifgroup match
--
Laszlo Attila Toth
^ permalink raw reply
* [PATCH 1/2] Interface group: core (netlink) part
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth
In-Reply-To: <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
Interface groups let handle different interfaces together
especially in netfilter modules.
Modified net device structure and netlink interface.
Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
include/linux/if_link.h | 2 ++
include/linux/netdevice.h | 2 ++
net/core/rtnetlink.c | 10 ++++++++++
3 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 422084d..d9f1726 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -78,6 +78,8 @@ enum
IFLA_LINKMODE,
IFLA_LINKINFO,
#define IFLA_LINKINFO IFLA_LINKINFO
+ IFLA_IFGROUP,
+#define IFLA_IFGROUP IFLA_IFGROUP
__IFLA_MAX
};
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e679b27..c489a20 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -365,6 +365,8 @@ struct net_device
/* Interface index. Unique device identifier */
int ifindex;
int iflink;
+ /* interface group this interface belongs to */
+ u_int32_t ifgroup;
struct net_device_stats* (*get_stats)(struct net_device *dev);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4756d58..bbe4a98 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -608,6 +608,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
+ nla_total_size(4) /* IFLA_MTU */
+ nla_total_size(4) /* IFLA_LINK */
+ nla_total_size(4) /* IFLA_MASTER */
+ + nla_total_size(4) /* IFLA_IFGROUP */
+ nla_total_size(1) /* IFLA_OPERSTATE */
+ nla_total_size(1) /* IFLA_LINKMODE */
+ rtnl_link_get_size(dev); /* IFLA_LINKINFO */
@@ -646,6 +647,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
if (dev->master)
NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex);
+ if (dev->ifgroup)
+ NLA_PUT_U32(skb, IFLA_IFGROUP, dev->ifgroup);
+
if (dev->qdisc_sleeping)
NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc_sleeping->ops->id);
@@ -846,6 +850,12 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
write_unlock_bh(&dev_base_lock);
}
+ if (tb[IFLA_IFGROUP]) {
+ write_lock_bh(&dev_base_lock);
+ dev->ifgroup = nla_get_u32(tb[IFLA_IFGROUP]);
+ write_unlock_bh(&dev_base_lock);
+ }
+
err = 0;
errout:
--
1.5.2.5
^ permalink raw reply related
* [PATCH 2/2] Interface group match
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth
In-Reply-To: <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
Interface group values can be checked on both input and output interfaces.
Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
include/linux/netfilter/xt_ifgroup.h | 18 ++++++
net/netfilter/Kconfig | 16 +++++
net/netfilter/Makefile | 1 +
net/netfilter/xt_ifgroup.c | 108 ++++++++++++++++++++++++++++++++++
4 files changed, 143 insertions(+), 0 deletions(-)
diff --git a/include/linux/netfilter/xt_ifgroup.h b/include/linux/netfilter/xt_ifgroup.h
new file mode 100644
index 0000000..9ac75de
--- /dev/null
+++ b/include/linux/netfilter/xt_ifgroup.h
@@ -0,0 +1,18 @@
+#ifndef _XT_IFGROUP_H
+#define _XT_IFGROUP_H
+
+#define XT_IFGROUP_INVERT_IN 0x01
+#define XT_IFGROUP_INVERT_OUT 0x02
+#define XT_IFGROUP_MATCH_IN 0x04
+#define XT_IFGROUP_MATCH_OUT 0x08
+
+struct xt_ifgroup_info {
+ u_int32_t in_group;
+ u_int32_t in_mask;
+ u_int32_t out_group;
+ u_int32_t out_mask;
+ u_int8_t flags;
+};
+
+#endif /*_XT_IFGROUP_H*/
+
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 3599770..0864e19 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -597,6 +597,22 @@ config NETFILTER_XT_MATCH_QUOTA
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
+config NETFILTER_XT_MATCH_IFGROUP
+ tristate '"ifgroup" interface group match support'
+ depends on NETFILTER_XTABLES
+ help
+ Interface group matching allows you to match a packet by
+ its incoming interface "group", settable using ip link set
+ group
+
+ Typical usage is to assign dynamic interfaces to a group
+ when they come up using "ip link set group" and then match
+ incoming packets with a rule like this:
+
+ iptables -A INPUT -m ifgroup --if-group openvpn-rw1 -j LOG
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config NETFILTER_XT_MATCH_REALM
tristate '"realm" match support'
depends on NETFILTER_XTABLES
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 0c054bf..da9ab07 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -77,3 +77,4 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_IFGROUP) += xt_ifgroup.o
diff --git a/net/netfilter/xt_ifgroup.c b/net/netfilter/xt_ifgroup.c
new file mode 100644
index 0000000..07c3acc
--- /dev/null
+++ b/net/netfilter/xt_ifgroup.c
@@ -0,0 +1,108 @@
+/*
+ * An x_tables match module to match interface groups
+ *
+ * (C) 2006,2007 Balazs Scheidler <bazsi@balabit.hu>,
+ * Laszlo Attila Toth <panther@balabit.hu>
+ *
+ * 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 <linux/if_ether.h>
+#include <linux/if_packet.h>
+
+#include <linux/netfilter/xt_ifgroup.h>
+#include <linux/netfilter/x_tables.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Laszlo Attila Toth <panther@balabit.hu>");
+MODULE_DESCRIPTION("Xtables interface group matching module");
+MODULE_ALIAS("ipt_ifgroup");
+MODULE_ALIAS("ip6t_ifgroup");
+
+static bool ifgroup_match(const struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ const struct xt_match *match,
+ const void *matchinfo,
+ int offset,
+ unsigned int protoff,
+ bool *hotdrop)
+{
+#define FLAG_IS_SET(a,b) ((a & b) == b)
+#define MATCH_IN (((in->ifgroup & info->in_mask) == info->in_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_IN))
+#define MATCH_OUT (((out->ifgroup & info->out_mask) == info->out_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_OUT))
+
+ const struct xt_ifgroup_info *info = matchinfo;
+ bool verdict = false;
+
+ if ((info->flags & XT_IFGROUP_MATCH_IN) && (info->flags & XT_IFGROUP_MATCH_OUT))
+ verdict = MATCH_IN && MATCH_OUT;
+ else if (info->flags & XT_IFGROUP_MATCH_IN)
+ verdict = MATCH_IN;
+ else if (info->flags & XT_IFGROUP_MATCH_OUT)
+ verdict = MATCH_OUT;
+ return verdict;
+}
+
+static bool ifgroup_checkentry(const char *tablename, const void *ip_void,
+ const struct xt_match *match,
+ void *matchinfo, unsigned int hook_mask)
+{
+ struct xt_ifgroup_info *info = matchinfo;
+
+ if (!(info->flags & (XT_IFGROUP_MATCH_IN|XT_IFGROUP_MATCH_OUT))) {
+ printk(KERN_ERR "xt_ifgroup: neither incoming nor "
+ "outgoing device selected\n");
+ return false;
+ }
+ if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
+ && info->flags & XT_IFGROUP_MATCH_OUT) {
+ printk(KERN_ERR "xt_ifgroup: output device not valid in "
+ "PRE_ROUTING and INPUT\n");
+ return false;
+ }
+ if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
+ && info->flags & XT_IFGROUP_MATCH_IN) {
+ printk(KERN_ERR "xt_ifgroup: input device not valid in "
+ "POST_ROUTING and OUTPUT\n");
+ return false;
+ }
+ return true;
+}
+
+static struct xt_match xt_ifgroup_match[] __read_mostly = {
+ {
+ .name = "ifgroup",
+ .match = ifgroup_match,
+ .checkentry = ifgroup_checkentry,
+ .matchsize = sizeof(struct xt_ifgroup_info),
+ .family = AF_INET,
+ .me = THIS_MODULE,
+
+ },
+ {
+ .name = "ifgroup",
+ .match = ifgroup_match,
+ .checkentry = ifgroup_checkentry,
+ .matchsize = sizeof(struct xt_ifgroup_info),
+ .family = AF_INET6,
+ .me = THIS_MODULE,
+ },
+};
+
+static int __init xt_ifgroup_init(void)
+{
+ return xt_register_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));
+}
+
+static void __exit xt_ifgroup_fini(void)
+{
+ xt_unregister_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));
+}
+
+module_init(xt_ifgroup_init);
+module_exit(xt_ifgroup_fini);
--
1.5.2.5
^ permalink raw reply related
* [IPROUTE PATCH] Interface group as new ip link option
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth
In-Reply-To: <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
Interfaces can be grouped and each group has an unique positive integer ID.
It can be set via ip link. Symbolic names can be specified in
/etc/iproute2/rt_ifgroup.
Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
include/linux/if_link.h | 2 +
include/rt_names.h | 2 +
ip/ipaddress.c | 4 +++
ip/iplink.c | 11 ++++++++
lib/rt_names.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++
man/man8/ip.8 | 5 ++++
6 files changed, 86 insertions(+), 0 deletions(-)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 23b3a8e..2dfb0b7 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -78,6 +78,8 @@ enum
IFLA_LINKMODE,
IFLA_LINKINFO,
#define IFLA_LINKINFO IFLA_LINKINFO
+ IFLA_IFGROUP,
+#define IFLA_IFGROUP IFLA_IFGROUP
__IFLA_MAX
};
diff --git a/include/rt_names.h b/include/rt_names.h
index 07a10e0..72c5247 100644
--- a/include/rt_names.h
+++ b/include/rt_names.h
@@ -8,11 +8,13 @@ char* rtnl_rtscope_n2a(int id, char *buf, int len);
char* rtnl_rttable_n2a(__u32 id, char *buf, int len);
char* rtnl_rtrealm_n2a(int id, char *buf, int len);
char* rtnl_dsfield_n2a(int id, char *buf, int len);
+char* rtnl_ifgroup_n2a(int id, char *buf, int len);
int rtnl_rtprot_a2n(__u32 *id, char *arg);
int rtnl_rtscope_a2n(__u32 *id, char *arg);
int rtnl_rttable_a2n(__u32 *id, char *arg);
int rtnl_rtrealm_a2n(__u32 *id, char *arg);
int rtnl_dsfield_a2n(__u32 *id, char *arg);
+int rtnl_ifgroup_a2n(__u32 *id, char *arg);
const char *inet_proto_n2a(int proto, char *buf, int len);
int inet_proto_a2n(char *buf);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 518d8cd..405e85c 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -227,6 +227,10 @@ int print_linkinfo(const struct sockaddr_nl *who,
fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
if (tb[IFLA_QDISC])
fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC]));
+ if (tb[IFLA_IFGROUP]) {
+ SPRINT_BUF(b1);
+ fprintf(fp, "group %s ", rtnl_ifgroup_n2a(*(int*)RTA_DATA(tb[IFLA_IFGROUP]), b1, sizeof(b1)));
+ }
#ifdef IFLA_MASTER
if (tb[IFLA_MASTER]) {
SPRINT_BUF(b1);
diff --git a/ip/iplink.c b/ip/iplink.c
index 4060845..bebb2fe 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -27,6 +27,7 @@
#include <string.h>
#include <sys/ioctl.h>
#include <linux/sockios.h>
+#include <linux/rtnetlink.h>
#include "rt_names.h"
#include "utils.h"
@@ -46,6 +47,7 @@ void iplink_usage(void)
fprintf(stderr, " promisc { on | off } |\n");
fprintf(stderr, " trailers { on | off } |\n");
fprintf(stderr, " txqueuelen PACKETS |\n");
+ fprintf(stderr, " group GROUP |\n");
fprintf(stderr, " name NEWNAME |\n");
fprintf(stderr, " address LLADDR | broadcast LLADDR |\n");
fprintf(stderr, " mtu MTU }\n");
@@ -145,6 +147,7 @@ static int iplink_have_newlink(void)
static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
{
int qlen = -1;
+ __u32 group = 0;
int mtu = -1;
int len;
char abuf[32];
@@ -197,6 +200,14 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
if (get_integer(&qlen, *argv, 0))
invarg("Invalid \"txqueuelen\" value\n", *argv);
addattr_l(&req.n, sizeof(req), IFLA_TXQLEN, &qlen, 4);
+ } else if (matches(*argv, "group") == 0) {
+ NEXT_ARG();
+ if (group != 0)
+ duparg("group", *argv);
+
+ if (rtnl_ifgroup_a2n(&group, *argv) || group == 0)
+ invarg("\"group\" value is invalid\n", *argv);
+ addattr_l(&req.n, sizeof(req), IFLA_IFGROUP, &group, sizeof(group));
} else if (strcmp(*argv, "mtu") == 0) {
NEXT_ARG();
if (mtu != -1)
diff --git a/lib/rt_names.c b/lib/rt_names.c
index 8d019a0..a067e74 100644
--- a/lib/rt_names.c
+++ b/lib/rt_names.c
@@ -446,3 +446,65 @@ int rtnl_dsfield_a2n(__u32 *id, char *arg)
return 0;
}
+static char * rtnl_rtifgroup_tab[256] = {
+ "0",
+};
+
+static int rtnl_rtifgroup_init;
+
+static void rtnl_rtifgroup_initialize(void)
+{
+ rtnl_rtifgroup_init = 1;
+ rtnl_tab_initialize("/etc/iproute2/rt_ifgroup",
+ rtnl_rtifgroup_tab, 256);
+}
+
+char * rtnl_ifgroup_n2a(int id, char *buf, int len)
+{
+ if (id<0 || id>=256) {
+ snprintf(buf, len, "%d", id);
+ return buf;
+ }
+ if (!rtnl_rtifgroup_tab[id]) {
+ if (!rtnl_rtifgroup_init)
+ rtnl_rtifgroup_initialize();
+ }
+ if (rtnl_rtifgroup_tab[id])
+ return rtnl_rtifgroup_tab[id];
+ snprintf(buf, len, "0x%02x", id);
+ return buf;
+}
+
+
+int rtnl_ifgroup_a2n(__u32 *id, char *arg)
+{
+ static char *cache = NULL;
+ static unsigned long res;
+ char *end;
+ int i;
+
+ if (cache && strcmp(cache, arg) == 0) {
+ *id = res;
+ return 0;
+ }
+
+ if (!rtnl_rtifgroup_init)
+ rtnl_rtifgroup_initialize();
+
+ for (i=0; i<256; i++) {
+ if (rtnl_rtifgroup_tab[i] &&
+ strcmp(rtnl_rtifgroup_tab[i], arg) == 0) {
+ cache = rtnl_rtifgroup_tab[i];
+ res = i;
+ *id = res;
+ return 0;
+ }
+ }
+
+ res = strtoul(arg, &end, 16);
+ if (!end || end == arg || *end || res > 255)
+ return -1;
+ *id = res;
+ return 0;
+}
+
diff --git a/man/man8/ip.8 b/man/man8/ip.8
index a9132da..92bc59e 100644
--- a/man/man8/ip.8
+++ b/man/man8/ip.8
@@ -506,6 +506,11 @@ already configured.
change the transmit queue length of the device.
.TP
+.BI group " GROUP"
+.TP
+change the interface group identifier of the device.
+
+.TP
.BI mtu " NUMBER"
change the
.I MTU
--
1.5.2.5
^ permalink raw reply related
* [IPTABLES PATCH] Interface group match
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth
In-Reply-To: <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
Matching ifgroup value of incoming and/or outgoing interface.
Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
extensions/Makefile | 2 +-
extensions/libip6t_ifgroup.man | 36 +++++++
extensions/libipt_ifgroup.man | 36 +++++++
extensions/libxt_ifgroup.c | 178 ++++++++++++++++++++++++++++++++++
include/linux/netfilter/xt_ifgroup.h | 18 ++++
5 files changed, 269 insertions(+), 1 deletions(-)
diff --git a/extensions/Makefile b/extensions/Makefile
index 5af234e..938cf0b 100644
--- a/extensions/Makefile
+++ b/extensions/Makefile
@@ -7,7 +7,7 @@
#
PF_EXT_SLIB:=ah addrtype conntrack ecn icmp iprange owner policy realm recent tos ttl unclean CLUSTERIP DNAT ECN LOG MASQUERADE MIRROR NETMAP REDIRECT REJECT SAME SNAT TOS TTL ULOG
PF6_EXT_SLIB:=ah dst eui64 frag hbh hl icmp6 ipv6header mh owner policy rt HL LOG REJECT
-PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
+PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper ifgroup length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
PF_EXT_SELINUX_SLIB:=
PF6_EXT_SELINUX_SLIB:=
diff --git a/extensions/libip6t_ifgroup.man b/extensions/libip6t_ifgroup.man
new file mode 100644
index 0000000..a96ec91
--- /dev/null
+++ b/extensions/libip6t_ifgroup.man
@@ -0,0 +1,36 @@
+Maches packets on an interface if it is in the same interface group
+as specified by the
+.B "--in-ifgroup"
+or
+.B "--out-ifgroup"
+parameter. If a mask is also specified, the masked value of
+the inteface's group must be equal to the given value of the
+.B "--in-ifgroup"
+or
+.B "--out-ifgroup"
+parameter to match. This match is available in all tables.
+.TP
+.BR "--in-ifgroup \fIgroup[/mask]\fR"
+This specifies the interface group of input interface and the optional mask.
+Valid only in the in the
+.B PREROUTING
+and
+.B INPUT
+and
+.B FORWARD
+chains, and user-defined chains which are only called from those
+chains.
+.TP
+.BR "--out-ifgroup \fIgroup[/mask]\fR"
+This specifies the interface group of out interface and the optional mask.
+Valid only in the in the
+.B FORWARD
+and
+.B OUTPUT
+and
+.B POSTROUTING
+chains, and user-defined chains which are only called from those
+chains.
+.RS
+.PP
+
diff --git a/extensions/libipt_ifgroup.man b/extensions/libipt_ifgroup.man
new file mode 100644
index 0000000..a96ec91
--- /dev/null
+++ b/extensions/libipt_ifgroup.man
@@ -0,0 +1,36 @@
+Maches packets on an interface if it is in the same interface group
+as specified by the
+.B "--in-ifgroup"
+or
+.B "--out-ifgroup"
+parameter. If a mask is also specified, the masked value of
+the inteface's group must be equal to the given value of the
+.B "--in-ifgroup"
+or
+.B "--out-ifgroup"
+parameter to match. This match is available in all tables.
+.TP
+.BR "--in-ifgroup \fIgroup[/mask]\fR"
+This specifies the interface group of input interface and the optional mask.
+Valid only in the in the
+.B PREROUTING
+and
+.B INPUT
+and
+.B FORWARD
+chains, and user-defined chains which are only called from those
+chains.
+.TP
+.BR "--out-ifgroup \fIgroup[/mask]\fR"
+This specifies the interface group of out interface and the optional mask.
+Valid only in the in the
+.B FORWARD
+and
+.B OUTPUT
+and
+.B POSTROUTING
+chains, and user-defined chains which are only called from those
+chains.
+.RS
+.PP
+
diff --git a/extensions/libxt_ifgroup.c b/extensions/libxt_ifgroup.c
new file mode 100644
index 0000000..d7f982c
--- /dev/null
+++ b/extensions/libxt_ifgroup.c
@@ -0,0 +1,178 @@
+/*
+ * Shared library add-on to iptables to match
+ * packets by the incoming interface group.
+ *
+ * Balazs Scheidler <bazsi@balabit.hu>
+ */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <xtables.h>
+#include <linux/netfilter/xt_ifgroup.h>
+
+static void
+ifgroup_help(void)
+{
+ printf(
+"ifgroup v%s options:\n"
+" --in-ifgroup [!] group[/mask] incoming interface group and its mask\n"
+" --out-ifgroup [!] group[/mask] outgoing interface group and its mask\n"
+"\n", IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+ {"in-ifgroup", 1, 0, '1'},
+ {"out-ifgroup", 1, 0, '2'},
+ { }
+};
+
+#define PARAM_MATCH_IN 0x01
+#define PARAM_MATCH_OUT 0x02
+
+static int
+ifgroup_parse(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_match **match)
+{
+ struct xt_ifgroup_info *info = (struct xt_ifgroup_info *) (*match)->data;
+ char *end;
+
+ switch (c)
+ {
+ case '1':
+ if (*flags & PARAM_MATCH_IN)
+ exit_error(PARAMETER_PROBLEM,
+ "ifgroup match: Can't specify --in-ifgroup twice");
+
+ check_inverse(optarg, &invert, &optind, 0);
+
+ info->in_group = strtoul(optarg, &end, 0);
+ info->in_mask = 0xffffffffUL;
+
+ if (*end == '/')
+ info->in_mask = strtoul(end+1, &end, 0);
+
+ if (*end != '\0' || end == optarg)
+ exit_error(PARAMETER_PROBLEM, "ifgroup match: Bad ifgroup value `%s'", optarg);
+
+ if (invert)
+ info->flags |= XT_IFGROUP_INVERT_IN;
+
+ *flags |= PARAM_MATCH_IN;
+ info->flags |= XT_IFGROUP_MATCH_IN;
+ break;
+ case '2':
+ if (*flags & PARAM_MATCH_OUT)
+ exit_error(PARAMETER_PROBLEM,
+ "ifgroup match: Can't specify --out-ifgroup twice");
+
+ check_inverse(optarg, &invert, &optind, 0);
+
+ info->out_group = strtoul(optarg, &end, 0);
+ info->out_mask = 0xffffffffUL;
+
+ if (*end == '/')
+ info->out_mask = strtoul(end+1, &end, 0);
+
+ if (*end != '\0' || end == optarg)
+ exit_error(PARAMETER_PROBLEM, "ifgroup match: Bad ifgroup value `%s'", optarg);
+
+ if (invert)
+ info->flags |= XT_IFGROUP_INVERT_OUT;
+
+ *flags |= PARAM_MATCH_OUT;
+ info->flags |= XT_IFGROUP_MATCH_OUT;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+static void
+ifgroup_final_check(unsigned int flags)
+{
+ if (!flags)
+ exit_error(PARAMETER_PROBLEM, "You must specify `--in-ifgroup' or `--out-ifgroup'");
+}
+
+static void
+ifgroup_print_value_in(struct xt_ifgroup_info *info)
+{
+ printf("0x%x/0x%x ", info->in_group, info->in_mask);
+}
+
+static void
+ifgroup_print_value_out(struct xt_ifgroup_info *info)
+{
+ printf("0x%x/0x%x ", info->out_group, info->out_mask);
+}
+
+static void
+ifgroup_print(const void *ip, const struct xt_entry_match *match, int numeric)
+{
+ struct xt_ifgroup_info *info = (struct xt_ifgroup_info *) match->data;
+
+ printf("ifgroup ");
+
+ if (info->flags & XT_IFGROUP_MATCH_IN) {
+ printf("in %s", info->flags & XT_IFGROUP_INVERT_IN ? "! " : "");
+ ifgroup_print_value_in(info);
+ }
+ if (info->flags & XT_IFGROUP_MATCH_OUT) {
+ printf("out %s", info->flags & XT_IFGROUP_INVERT_OUT ? "! " : "");
+ ifgroup_print_value_out(info);
+ }
+}
+
+static void
+ifgroup_save(const void *ip, const struct xt_entry_match *match)
+{
+ struct xt_ifgroup_info *info = (struct xt_ifgroup_info *) match->data;
+
+ if (info->flags & XT_IFGROUP_MATCH_IN) {
+ printf("--in-ifgroup %s", info->flags & XT_IFGROUP_INVERT_IN ? "! " : "");
+ ifgroup_print_value_in(info);
+ }
+ if (info->flags & XT_IFGROUP_MATCH_OUT) {
+ printf("--out-ifgroup %s", info->flags & XT_IFGROUP_INVERT_OUT ? "! " : "");
+ ifgroup_print_value_out(info);
+ }
+}
+
+static struct xtables_match ifgroup_match = {
+ .family = AF_INET,
+ .name = "ifgroup",
+ .version = IPTABLES_VERSION,
+ .size = XT_ALIGN(sizeof(struct xt_ifgroup_info)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_ifgroup_info)),
+ .help = ifgroup_help,
+ .parse = ifgroup_parse,
+ .final_check = ifgroup_final_check,
+ .print = ifgroup_print,
+ .save = ifgroup_save,
+ .extra_opts = opts
+};
+
+static struct xtables_match ifgroup_match6 = {
+ .family = AF_INET6,
+ .name = "ifgroup",
+ .version = IPTABLES_VERSION,
+ .size = XT_ALIGN(sizeof(struct xt_ifgroup_info)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_ifgroup_info)),
+ .help = ifgroup_help,
+ .parse = ifgroup_parse,
+ .final_check = ifgroup_final_check,
+ .print = ifgroup_print,
+ .save = ifgroup_save,
+ .extra_opts = opts
+};
+
+void _init(void)
+{
+ xtables_register_match(&ifgroup_match);
+ xtables_register_match(&ifgroup_match6);
+}
+
diff --git a/include/linux/netfilter/xt_ifgroup.h b/include/linux/netfilter/xt_ifgroup.h
new file mode 100644
index 0000000..9ac75de
--- /dev/null
+++ b/include/linux/netfilter/xt_ifgroup.h
@@ -0,0 +1,18 @@
+#ifndef _XT_IFGROUP_H
+#define _XT_IFGROUP_H
+
+#define XT_IFGROUP_INVERT_IN 0x01
+#define XT_IFGROUP_INVERT_OUT 0x02
+#define XT_IFGROUP_MATCH_IN 0x04
+#define XT_IFGROUP_MATCH_OUT 0x08
+
+struct xt_ifgroup_info {
+ u_int32_t in_group;
+ u_int32_t in_mask;
+ u_int32_t out_group;
+ u_int32_t out_mask;
+ u_int8_t flags;
+};
+
+#endif /*_XT_IFGROUP_H*/
+
--
1.5.2.5
^ permalink raw reply related
* [PATCH 1/2] Interface group: core (netlink) part
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth
In-Reply-To: <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
Interface groups let handle different interfaces together
especially in netfilter modules.
Modified net device structure and netlink interface.
Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
include/linux/if_link.h | 2 ++
include/linux/netdevice.h | 2 ++
net/core/rtnetlink.c | 10 ++++++++++
3 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 422084d..d9f1726 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -78,6 +78,8 @@ enum
IFLA_LINKMODE,
IFLA_LINKINFO,
#define IFLA_LINKINFO IFLA_LINKINFO
+ IFLA_IFGROUP,
+#define IFLA_IFGROUP IFLA_IFGROUP
__IFLA_MAX
};
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e679b27..c489a20 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -365,6 +365,8 @@ struct net_device
/* Interface index. Unique device identifier */
int ifindex;
int iflink;
+ /* interface group this interface belongs to */
+ u_int32_t ifgroup;
struct net_device_stats* (*get_stats)(struct net_device *dev);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4756d58..bbe4a98 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -608,6 +608,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
+ nla_total_size(4) /* IFLA_MTU */
+ nla_total_size(4) /* IFLA_LINK */
+ nla_total_size(4) /* IFLA_MASTER */
+ + nla_total_size(4) /* IFLA_IFGROUP */
+ nla_total_size(1) /* IFLA_OPERSTATE */
+ nla_total_size(1) /* IFLA_LINKMODE */
+ rtnl_link_get_size(dev); /* IFLA_LINKINFO */
@@ -646,6 +647,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
if (dev->master)
NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex);
+ if (dev->ifgroup)
+ NLA_PUT_U32(skb, IFLA_IFGROUP, dev->ifgroup);
+
if (dev->qdisc_sleeping)
NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc_sleeping->ops->id);
@@ -846,6 +850,12 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
write_unlock_bh(&dev_base_lock);
}
+ if (tb[IFLA_IFGROUP]) {
+ write_lock_bh(&dev_base_lock);
+ dev->ifgroup = nla_get_u32(tb[IFLA_IFGROUP]);
+ write_unlock_bh(&dev_base_lock);
+ }
+
err = 0;
errout:
--
1.5.2.5
^ permalink raw reply related
* [PATCH 0/2] Interface groups, round two
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth
Hello,
Here is the new version of ifgroup patches.
The interface group value is u_int32_t in net_device which should be enough.
Previously it was an int.
Usage:
ip link set eth0 group 4
but currently it cannot be unset, only changed to another value.
In /etc/iproute2/rt_ifgroup each value may have a symbolic name.
Netfilter part: xt_ifgroup module for both IPv4 and IPv6. Iptables usage:
iptables -A INPUT -m ifgroup --in-ifgroup 4/0xf -j ACCEPT
iptables -A FORWARD -m ifgroup --in-ifgroup 4 --out-ifgroup 5 -j ACCEPT
...
in the FORWARD chain both input and output interface group value should be matched
(with optional masks).
The following patches are:
kernel: core part
kernel: netfilter module, ifgroup match
iproute2: showing and set ifgroup value
iptables: ifgroup match
--
Laszlo Attila Toth
^ permalink raw reply
* [PATCH 2/2] Interface group match
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth
In-Reply-To: <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
Interface group values can be checked on both input and output interfaces.
Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
include/linux/netfilter/xt_ifgroup.h | 18 ++++++
net/netfilter/Kconfig | 16 +++++
net/netfilter/Makefile | 1 +
net/netfilter/xt_ifgroup.c | 108 ++++++++++++++++++++++++++++++++++
4 files changed, 143 insertions(+), 0 deletions(-)
diff --git a/include/linux/netfilter/xt_ifgroup.h b/include/linux/netfilter/xt_ifgroup.h
new file mode 100644
index 0000000..9ac75de
--- /dev/null
+++ b/include/linux/netfilter/xt_ifgroup.h
@@ -0,0 +1,18 @@
+#ifndef _XT_IFGROUP_H
+#define _XT_IFGROUP_H
+
+#define XT_IFGROUP_INVERT_IN 0x01
+#define XT_IFGROUP_INVERT_OUT 0x02
+#define XT_IFGROUP_MATCH_IN 0x04
+#define XT_IFGROUP_MATCH_OUT 0x08
+
+struct xt_ifgroup_info {
+ u_int32_t in_group;
+ u_int32_t in_mask;
+ u_int32_t out_group;
+ u_int32_t out_mask;
+ u_int8_t flags;
+};
+
+#endif /*_XT_IFGROUP_H*/
+
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 3599770..0864e19 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -597,6 +597,22 @@ config NETFILTER_XT_MATCH_QUOTA
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
+config NETFILTER_XT_MATCH_IFGROUP
+ tristate '"ifgroup" interface group match support'
+ depends on NETFILTER_XTABLES
+ help
+ Interface group matching allows you to match a packet by
+ its incoming interface "group", settable using ip link set
+ group
+
+ Typical usage is to assign dynamic interfaces to a group
+ when they come up using "ip link set group" and then match
+ incoming packets with a rule like this:
+
+ iptables -A INPUT -m ifgroup --if-group openvpn-rw1 -j LOG
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config NETFILTER_XT_MATCH_REALM
tristate '"realm" match support'
depends on NETFILTER_XTABLES
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 0c054bf..da9ab07 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -77,3 +77,4 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_IFGROUP) += xt_ifgroup.o
diff --git a/net/netfilter/xt_ifgroup.c b/net/netfilter/xt_ifgroup.c
new file mode 100644
index 0000000..07c3acc
--- /dev/null
+++ b/net/netfilter/xt_ifgroup.c
@@ -0,0 +1,108 @@
+/*
+ * An x_tables match module to match interface groups
+ *
+ * (C) 2006,2007 Balazs Scheidler <bazsi@balabit.hu>,
+ * Laszlo Attila Toth <panther@balabit.hu>
+ *
+ * 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 <linux/if_ether.h>
+#include <linux/if_packet.h>
+
+#include <linux/netfilter/xt_ifgroup.h>
+#include <linux/netfilter/x_tables.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Laszlo Attila Toth <panther@balabit.hu>");
+MODULE_DESCRIPTION("Xtables interface group matching module");
+MODULE_ALIAS("ipt_ifgroup");
+MODULE_ALIAS("ip6t_ifgroup");
+
+static bool ifgroup_match(const struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ const struct xt_match *match,
+ const void *matchinfo,
+ int offset,
+ unsigned int protoff,
+ bool *hotdrop)
+{
+#define FLAG_IS_SET(a,b) ((a & b) == b)
+#define MATCH_IN (((in->ifgroup & info->in_mask) == info->in_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_IN))
+#define MATCH_OUT (((out->ifgroup & info->out_mask) == info->out_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_OUT))
+
+ const struct xt_ifgroup_info *info = matchinfo;
+ bool verdict = false;
+
+ if ((info->flags & XT_IFGROUP_MATCH_IN) && (info->flags & XT_IFGROUP_MATCH_OUT))
+ verdict = MATCH_IN && MATCH_OUT;
+ else if (info->flags & XT_IFGROUP_MATCH_IN)
+ verdict = MATCH_IN;
+ else if (info->flags & XT_IFGROUP_MATCH_OUT)
+ verdict = MATCH_OUT;
+ return verdict;
+}
+
+static bool ifgroup_checkentry(const char *tablename, const void *ip_void,
+ const struct xt_match *match,
+ void *matchinfo, unsigned int hook_mask)
+{
+ struct xt_ifgroup_info *info = matchinfo;
+
+ if (!(info->flags & (XT_IFGROUP_MATCH_IN|XT_IFGROUP_MATCH_OUT))) {
+ printk(KERN_ERR "xt_ifgroup: neither incoming nor "
+ "outgoing device selected\n");
+ return false;
+ }
+ if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
+ && info->flags & XT_IFGROUP_MATCH_OUT) {
+ printk(KERN_ERR "xt_ifgroup: output device not valid in "
+ "PRE_ROUTING and INPUT\n");
+ return false;
+ }
+ if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
+ && info->flags & XT_IFGROUP_MATCH_IN) {
+ printk(KERN_ERR "xt_ifgroup: input device not valid in "
+ "POST_ROUTING and OUTPUT\n");
+ return false;
+ }
+ return true;
+}
+
+static struct xt_match xt_ifgroup_match[] __read_mostly = {
+ {
+ .name = "ifgroup",
+ .match = ifgroup_match,
+ .checkentry = ifgroup_checkentry,
+ .matchsize = sizeof(struct xt_ifgroup_info),
+ .family = AF_INET,
+ .me = THIS_MODULE,
+
+ },
+ {
+ .name = "ifgroup",
+ .match = ifgroup_match,
+ .checkentry = ifgroup_checkentry,
+ .matchsize = sizeof(struct xt_ifgroup_info),
+ .family = AF_INET6,
+ .me = THIS_MODULE,
+ },
+};
+
+static int __init xt_ifgroup_init(void)
+{
+ return xt_register_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));
+}
+
+static void __exit xt_ifgroup_fini(void)
+{
+ xt_unregister_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));
+}
+
+module_init(xt_ifgroup_init);
+module_exit(xt_ifgroup_fini);
--
1.5.2.5
^ permalink raw reply related
* [PATCH] [TCP]: Remove lost_retrans zero special cases
From: Ilpo Järvinen @ 2007-10-18 10:17 UTC (permalink / raw)
To: TAKANO Ryousei, David Miller; +Cc: y-kodama, Netdev
In-Reply-To: <Pine.LNX.4.64.0710181214140.3767@kivilampi-30.cs.helsinki.fi>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 3275 bytes --]
On Thu, 18 Oct 2007, Ilpo Järvinen wrote:
> On Thu, 18 Oct 2007, TAKANO Ryousei wrote:
>
> > From: David Miller <davem@davemloft.net>
> > Subject: Re: [PATCH 7/7] [TCP]: Limit processing lost_retrans loop to work-to-do cases
> > Date: Thu, 11 Oct 2007 17:36:22 -0700 (PDT)
> >
> > > From: "Ilpo_Järvinen" <ilpo.jarvinen@helsinki.fi>
> > > Date: Thu, 11 Oct 2007 14:41:07 +0300
> > >
> > > > This addition of lost_retrans_low to tcp_sock might be
> > > > unnecessary, it's not clear how often lost_retrans worker is
> > > > executed when there wasn't work to do.
> > > >
> > > > Cc: TAKANO Ryousei <takano@axe-inc.co.jp>
> > > > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
> > >
> > > Applied.
> >
> > > + after(highest_sack_end_seq, tp->lost_retrans_low) &&
> >
> > This limit degrades the performance of my test case described before,
>
> Thanks for testing.... Btw, just noticed that lost_retrans_low addition
> patch incorrectly dropped check for highest_sack_end_seq (probably due to
> incorrect resolution from my side at some point of development of those
> two patches as I added that check later on when realized it's necessary),
> patching that below... Since it causes zero received_upto in
> tcp_mark_lost_retrans, some RETRANS bits got cleared unintentionally
> because of that.
...snip...
> --
>
> [PATCH] [TCP]: Add highest_sack_end_seq check back to lost_retrans call
Try this patch instead not on the top of the one I sent earlier (IMHO
this is better approach):
--
[PATCH] [TCP]: Remove lost_retrans zero seqno special cases
Both high-sack detection and new lowest seq variables have
unnecessary zero special case which are now removed by setting
safe initial seqnos.
This also fixes problem which caused zero received_upto being
passed to tcp_mark_lost_retrans which confused after relations
within the marker loop causing incorrect TCPCB_SACKED_RETRANS
clearing. The problem was noticed because of a performance
report from TAKANO Ryousei <takano@axe-inc.co.jp>.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
net/ipv4/tcp_input.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 0f00966..9288220 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1121,7 +1121,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
struct sk_buff *skb;
int flag = 0;
int cnt = 0;
- u32 new_low_seq = 0;
+ u32 new_low_seq = tp->snd_nxt;
tcp_for_write_queue(skb, sk) {
u32 ack_seq = TCP_SKB_CB(skb)->ack_seq;
@@ -1153,7 +1153,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT);
}
} else {
- if (!new_low_seq || before(ack_seq, new_low_seq))
+ if (before(ack_seq, new_low_seq))
new_low_seq = ack_seq;
cnt += tcp_skb_pcount(skb);
}
@@ -1242,7 +1242,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
int reord = tp->packets_out;
int prior_fackets;
- u32 highest_sack_end_seq = 0;
+ u32 highest_sack_end_seq = tp->lost_retrans_low;
int flag = 0;
int found_dup_sack = 0;
int cached_fack_count;
--
1.5.0.6
^ permalink raw reply related
* Re: [PATCH 0/2] Interface groups, round two
From: Patrick McHardy @ 2007-10-18 10:20 UTC (permalink / raw)
To: Laszlo Attila Toth; +Cc: netdev, netfilter-devel
In-Reply-To: <11927025171404-git-send-email-panther@balabit.hu>
Laszlo Attila Toth wrote:
> Hello,
>
> Here is the new version of ifgroup patches.
>
> The interface group value is u_int32_t in net_device which should be enough.
> Previously it was an int.
>
> Usage:
> ip link set eth0 group 4
> but currently it cannot be unset, only changed to another value.
The only reason why it can't be set to zero again seems to
be this part from the iproute patch:
+ if (rtnl_ifgroup_a2n(&group, *argv) || group == 0)
Why don't you allow a value of zero?
^ permalink raw reply
* Re: [PATCH 1/2] Interface group: core (netlink) part
From: Patrick McHardy @ 2007-10-18 10:22 UTC (permalink / raw)
To: Laszlo Attila Toth; +Cc: netdev, netfilter-devel
In-Reply-To: <1192702517840-git-send-email-panther@balabit.hu>
Laszlo Attila Toth wrote:
> @@ -846,6 +850,12 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
> write_unlock_bh(&dev_base_lock);
> }
>
> + if (tb[IFLA_IFGROUP]) {
> + write_lock_bh(&dev_base_lock);
> + dev->ifgroup = nla_get_u32(tb[IFLA_IFGROUP]);
> + write_unlock_bh(&dev_base_lock);
> + }
So no notifications at all? Mhh .. I guess its OK for now, this stuff
needs to be fixed to notify once for all changes anyway.
^ permalink raw reply
* Re: [PATCH 2/2] Interface group match
From: Patrick McHardy @ 2007-10-18 10:27 UTC (permalink / raw)
To: Laszlo Attila Toth; +Cc: netdev, netfilter-devel
In-Reply-To: <11927025171911-git-send-email-panther@balabit.hu>
Laszlo Attila Toth wrote:
> Interface group values can be checked on both input and output interfaces.
>
> Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
> ---
> include/linux/netfilter/xt_ifgroup.h | 18 ++++++
> net/netfilter/Kconfig | 16 +++++
> net/netfilter/Makefile | 1 +
> net/netfilter/xt_ifgroup.c | 108 ++++++++++++++++++++++++++++++++++
> 4 files changed, 143 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/netfilter/xt_ifgroup.h b/include/linux/netfilter/xt_ifgroup.h
> new file mode 100644
> index 0000000..9ac75de
> --- /dev/null
> +++ b/include/linux/netfilter/xt_ifgroup.h
> @@ -0,0 +1,18 @@
> +#ifndef _XT_IFGROUP_H
> +#define _XT_IFGROUP_H
> +
> +#define XT_IFGROUP_INVERT_IN 0x01
> +#define XT_IFGROUP_INVERT_OUT 0x02
> +#define XT_IFGROUP_MATCH_IN 0x04
> +#define XT_IFGROUP_MATCH_OUT 0x08
> +
> +struct xt_ifgroup_info {
> + u_int32_t in_group;
> + u_int32_t in_mask;
> + u_int32_t out_group;
> + u_int32_t out_mask;
> + u_int8_t flags;
> +};
> +
> +#endif /*_XT_IFGROUP_H*/
> +
> diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
> index 3599770..0864e19 100644
> --- a/net/netfilter/Kconfig
> +++ b/net/netfilter/Kconfig
> @@ -597,6 +597,22 @@ config NETFILTER_XT_MATCH_QUOTA
> If you want to compile it as a module, say M here and read
> <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
>
> +config NETFILTER_XT_MATCH_IFGROUP
> + tristate '"ifgroup" interface group match support'
> + depends on NETFILTER_XTABLES
> + help
> + Interface group matching allows you to match a packet by
> + its incoming interface "group", settable using ip link set
> + group
> +
> + Typical usage is to assign dynamic interfaces to a group
> + when they come up using "ip link set group" and then match
> + incoming packets with a rule like this:
> +
> + iptables -A INPUT -m ifgroup --if-group openvpn-rw1 -j LOG
> +
> + To compile it as a module, choose M here. If unsure, say N.
> +
> config NETFILTER_XT_MATCH_REALM
> tristate '"realm" match support'
> depends on NETFILTER_XTABLES
> diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
> index 0c054bf..da9ab07 100644
> --- a/net/netfilter/Makefile
> +++ b/net/netfilter/Makefile
> @@ -77,3 +77,4 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
> obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
> obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
> obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
> +obj-$(CONFIG_NETFILTER_XT_MATCH_IFGROUP) += xt_ifgroup.o
> diff --git a/net/netfilter/xt_ifgroup.c b/net/netfilter/xt_ifgroup.c
> new file mode 100644
> index 0000000..07c3acc
> --- /dev/null
> +++ b/net/netfilter/xt_ifgroup.c
> @@ -0,0 +1,108 @@
> +/*
> + * An x_tables match module to match interface groups
> + *
> + * (C) 2006,2007 Balazs Scheidler <bazsi@balabit.hu>,
> + * Laszlo Attila Toth <panther@balabit.hu>
> + *
> + * 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 <linux/if_ether.h>
> +#include <linux/if_packet.h>
These two look unnecessary.
> +
> +#include <linux/netfilter/xt_ifgroup.h>
> +#include <linux/netfilter/x_tables.h>
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Laszlo Attila Toth <panther@balabit.hu>");
> +MODULE_DESCRIPTION("Xtables interface group matching module");
> +MODULE_ALIAS("ipt_ifgroup");
> +MODULE_ALIAS("ip6t_ifgroup");
> +
> +static bool ifgroup_match(const struct sk_buff *skb,
> + const struct net_device *in,
> + const struct net_device *out,
> + const struct xt_match *match,
> + const void *matchinfo,
> + int offset,
> + unsigned int protoff,
> + bool *hotdrop)
> +{
> +#define FLAG_IS_SET(a,b) ((a & b) == b)
> +#define MATCH_IN (((in->ifgroup & info->in_mask) == info->in_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_IN))
> +#define MATCH_OUT (((out->ifgroup & info->out_mask) == info->out_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_OUT))
Exceeds 80 characters and looks pretty obfuscating. Please open
code this or use an inline function.
> +
> + const struct xt_ifgroup_info *info = matchinfo;
> + bool verdict = false;
> +
> + if ((info->flags & XT_IFGROUP_MATCH_IN) && (info->flags & XT_IFGROUP_MATCH_OUT))
> + verdict = MATCH_IN && MATCH_OUT;
> + else if (info->flags & XT_IFGROUP_MATCH_IN)
> + verdict = MATCH_IN;
> + else if (info->flags & XT_IFGROUP_MATCH_OUT)
> + verdict = MATCH_OUT;
How about:
if (info->flags & XT_IFGROUP_MATCH_IN && !MATCH_IN)
return false;
if (info->flags & XT_IFGROUP_MATCH_OUT && !MATCH_OUT)
return false;
instead of having each match twice?
> + return verdict;
> +}
> +
> +static bool ifgroup_checkentry(const char *tablename, const void *ip_void,
> + const struct xt_match *match,
> + void *matchinfo, unsigned int hook_mask)
> +{
> + struct xt_ifgroup_info *info = matchinfo;
> +
> + if (!(info->flags & (XT_IFGROUP_MATCH_IN|XT_IFGROUP_MATCH_OUT))) {
> + printk(KERN_ERR "xt_ifgroup: neither incoming nor "
> + "outgoing device selected\n");
> + return false;
> + }
> + if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
> + && info->flags & XT_IFGROUP_MATCH_OUT) {
> + printk(KERN_ERR "xt_ifgroup: output device not valid in "
> + "PRE_ROUTING and INPUT\n");
> + return false;
> + }
> + if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
> + && info->flags & XT_IFGROUP_MATCH_IN) {
> + printk(KERN_ERR "xt_ifgroup: input device not valid in "
> + "POST_ROUTING and OUTPUT\n");
> + return false;
> + }
> + return true;
> +}
> +
> +static struct xt_match xt_ifgroup_match[] __read_mostly = {
> + {
> + .name = "ifgroup",
> + .match = ifgroup_match,
> + .checkentry = ifgroup_checkentry,
> + .matchsize = sizeof(struct xt_ifgroup_info),
> + .family = AF_INET,
> + .me = THIS_MODULE,
> +
> + },
> + {
> + .name = "ifgroup",
> + .match = ifgroup_match,
> + .checkentry = ifgroup_checkentry,
> + .matchsize = sizeof(struct xt_ifgroup_info),
> + .family = AF_INET6,
> + .me = THIS_MODULE,
> + },
> +};
> +
> +static int __init xt_ifgroup_init(void)
> +{
> + return xt_register_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));
Also exceeds 80 characters.
> +}
> +
> +static void __exit xt_ifgroup_fini(void)
> +{
> + xt_unregister_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));
> +}
> +
> +module_init(xt_ifgroup_init);
> +module_exit(xt_ifgroup_fini);
^ permalink raw reply
* Re: TCP port randomization
From: Krzysztof Oledzki @ 2007-10-18 10:29 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20071017153412.6ef040bf@freepuppy.rosehill>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2572 bytes --]
On Wed, 17 Oct 2007, Stephen Hemminger wrote:
> On Thu, 18 Oct 2007 00:31:13 +0200 (CEST)
> Krzysztof Oledzki <olel@ans.pl> wrote:
>
>>
>>
>> On Wed, 17 Oct 2007, Stephen Hemminger wrote:
>>
>>> On Wed, 17 Oct 2007 23:15:48 +0200 (CEST)
>>> Krzysztof Oledzki <olel@ans.pl> wrote:
>>>
>>>> Hello,
>>>>
>>>> Is it normal that TCP port randomization (tested with 2.6.22) works only
>>>> when explicitly binding to a IP address:
>>>>
>>>>
>>>> --- cut here ---
>>>> root@fw1:~# nc 192.168.129.28 11
>>>> (UNKNOWN) [192.168.129.28] 11 (systat) : Connection refused
>>>> root@fw1:~# nc 192.168.129.28 11
>>>> (UNKNOWN) [192.168.129.28] 11 (systat) : Connection refused
>>>> root@fw1:~# nc 192.168.129.28 11
>>>> (UNKNOWN) [192.168.129.28] 11 (systat) : Connection refused
>>>>
>>>> 23:11:11.896126 IP 192.168.129.2.37839 > 192.168.129.28.11: S
>>>> 23:11:12.146573 IP 192.168.129.2.37840 > 192.168.129.28.11: S
>>>> 23:11:12.396488 IP 192.168.129.2.37841 > 192.168.129.28.11: S
>>>> --- cut here ---
>>>>
>>>>
>>>> --- cut here ---
>>>> root@fw1:~# nc -s 192.168.129.2 192.168.129.28 11
>>>> (UNKNOWN) [192.168.129.28] 11 (systat) : Connection refused
>>>> root@fw1:~# nc -s 192.168.129.2 192.168.129.28 11
>>>> (UNKNOWN) [192.168.129.28] 11 (systat) : Connection refused
>>>> root@fw1:~# nc -s 192.168.129.2 192.168.129.28 11
>>>> (UNKNOWN) [192.168.129.28] 11 (systat) : Connection refused
>>>>
>>>> 23:11:31.704391 IP 192.168.129.2.57204 > 192.168.129.28.11: S
>>>> 23:11:34.400048 IP 192.168.129.2.14512 > 192.168.129.28.11: S
>>>> 23:11:34.606707 IP 192.168.129.2.20117 > 192.168.129.28.11: S
>>>> --- cut here ---
>>>>
>>>> Best regards,
>>>>
>>>> Krzysztof Olędzki
>>>
>>> It is a expected side effect.
>>
>> So it is not possible to use randomization without binding to a specific
>> srcip?
>>
>>> The starting point for the search
>>> is based on hash(srcaddr, dstaddr, dstport, secret).
>>> You are using same source, dest and port so yes it will stay
>>> the same until rekeying occurs.
>>> The secret only changes every 5min same as TCP initial sequence number.
>>
>> If I get it right, even with explicitly selected constant srcaddr port
>> numbers should simply increase? This is not what I observed.
>>
>>
> When you set srcaddr, it calls bind, and bind does randomization always
> independent of address.
>
> This existing behavior may seem odd, but it shouldn't present a security
> problem.
Right. Thank you very much for the explanation.
Best regards,
Krzysztof Olędzki
^ permalink raw reply
* Re: s390x: getting ipv6 bugs on mainline since 2.6.23-git3
From: Martin Schwidefsky @ 2007-10-18 10:37 UTC (permalink / raw)
To: Patrick McHardy
Cc: Andy Whitcroft, linux390, linux-s390, netdev, linux-kernel,
Kamalesh Babulal
In-Reply-To: <47172AD5.2030009@trash.net>
On Thu, 2007-10-18 at 11:43 +0200, Patrick McHardy wrote:
> Andy Whitcroft wrote:
> > Seems we are getting some kind of bug out of our s390x partition (lnxabat1)
> > when booting latest mainline releases, specifically since 2.6.23-git3.
> >
> > Kernel BUG at 0000000000000002 Ýverbose debug info unavailable?
> > illegal operation: 0001 Ý#1?
> Which network driver are you using? Please post the output of
> "ip link list <dev>".
This is a bug in the qeth driver. It has been introduced by this commit:
commit 3b04ddde02cf1b6f14f2697da5c20eca5715017f
Author: Stephen Hemminger <shemminger@linux-foundation.org>
Date: Tue Oct 9 01:40:57 2007 -0700
[NET]: Move hardware header operations out of netdevice.
Since hardware header operations are part of the protocol class
not the device instance, make them into a separate object and
save memory.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
I've hacked up a fix for it. The real fix will be done by our networking
people.
--
blue skies,
Martin.
"Reality continues to ruin my life." - Calvin.
---
drivers/s390/net/qeth_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff -urpN linux-2.6/drivers/s390/net/qeth_main.c linux-2.6-patched/drivers/s390/net/qeth_main.c
--- linux-2.6/drivers/s390/net/qeth_main.c 2007-10-17 15:05:36.000000000 +0200
+++ linux-2.6-patched/drivers/s390/net/qeth_main.c 2007-10-17 15:05:46.000000000 +0200
@@ -6643,7 +6643,8 @@ qeth_netdev_init(struct net_device *dev)
dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid;
dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid;
#endif
- dev->header_ops = &qeth_null_ops;
+ if (qeth_get_netdev_flags(card) & IFF_NOARP)
+ dev->header_ops = &qeth_null_ops;
#ifdef CONFIG_QETH_IPV6
/*IPv6 address autoconfiguration stuff*/
^ permalink raw reply
* ip_frag_reasm() can return uninitialized variable
From: Adrian Bunk @ 2007-10-18 10:52 UTC (permalink / raw)
To: Herbert Xu; +Cc: netdev, linux-kernel
Since commit 1706d58763c36133d7fce6cc78b1444fd40db28c ip_frag_reasm()
can return the value of an uninitialized variable:
<-- snip -->
...
static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
struct net_device *dev)
{
struct iphdr *iph;
struct sk_buff *fp, *head = qp->q.fragments;
int len;
int ihlen;
int err;
ipq_kill(qp);
/* Make the one we just received the head. */
if (prev) {
head = prev->next;
fp = skb_clone(head, GFP_ATOMIC);
if (!fp)
goto out_nomem;
...
out_nomem:
LIMIT_NETDEBUG(KERN_ERR "IP: queue_glue: no memory for gluing "
"queue %p\n", qp);
goto out_fail;
...
out_fail:
IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
return err;
}
...
<-- snip -->
Spotted by the Coverity checker.
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
^ permalink raw reply
* Re: [PATCH] [TCP]: Remove lost_retrans zero special cases
From: TAKANO Ryousei @ 2007-10-18 10:55 UTC (permalink / raw)
To: ilpo.jarvinen; +Cc: davem, y-kodama, netdev
In-Reply-To: <Pine.LNX.4.64.0710181314130.3767@kivilampi-30.cs.helsinki.fi>
From: "Ilpo Järvinen" <ilpo.jarvinen@helsinki.fi>
Subject: [PATCH] [TCP]: Remove lost_retrans zero special cases
Date: Thu, 18 Oct 2007 13:17:24 +0300 (EEST)
> [PATCH] [TCP]: Remove lost_retrans zero seqno special cases
>
> Both high-sack detection and new lowest seq variables have
> unnecessary zero special case which are now removed by setting
> safe initial seqnos.
>
> This also fixes problem which caused zero received_upto being
> passed to tcp_mark_lost_retrans which confused after relations
> within the marker loop causing incorrect TCPCB_SACKED_RETRANS
> clearing. The problem was noticed because of a performance
> report from TAKANO Ryousei <takano@axe-inc.co.jp>.
>
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
> ---
> net/ipv4/tcp_input.c | 6 +++---
> 1 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
> index 0f00966..9288220 100644
> --- a/net/ipv4/tcp_input.c
> +++ b/net/ipv4/tcp_input.c
> @@ -1121,7 +1121,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
> struct sk_buff *skb;
> int flag = 0;
> int cnt = 0;
> - u32 new_low_seq = 0;
> + u32 new_low_seq = tp->snd_nxt;
>
> tcp_for_write_queue(skb, sk) {
> u32 ack_seq = TCP_SKB_CB(skb)->ack_seq;
> @@ -1153,7 +1153,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
> NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT);
> }
> } else {
> - if (!new_low_seq || before(ack_seq, new_low_seq))
> + if (before(ack_seq, new_low_seq))
> new_low_seq = ack_seq;
> cnt += tcp_skb_pcount(skb);
> }
> @@ -1242,7 +1242,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
> int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
> int reord = tp->packets_out;
> int prior_fackets;
> - u32 highest_sack_end_seq = 0;
> + u32 highest_sack_end_seq = tp->lost_retrans_low;
> int flag = 0;
> int found_dup_sack = 0;
> int cached_fack_count;
> --
> 1.5.0.6
Thanks Ilpo! This patch solves the problem, as shown below:
iteration :001 .... done. T = 17.365902 BW = 460.672876 Mbps
iteration :002 .... done. T = 16.456351 BW = 486.134501 Mbps
iteration :003 .... done. T = 16.658353 BW = 480.239550 Mbps
iteration :004 .... done. T = 16.468834 BW = 485.766026 Mbps
iteration :005 .... done. T = 16.596055 BW = 482.042268 Mbps
Acked-by: Ryousei Takano <takano-ryousei@aist.go.jp>
^ permalink raw reply
* Re: [Bugme-new] [Bug 9174] New: linux-2.6.23-git11 kernel panic
From: Patrick McHardy @ 2007-10-18 10:58 UTC (permalink / raw)
To: plamen.petrov; +Cc: Andrew Morton, bugme-daemon, netdev, Stephen Hemminger
In-Reply-To: <47172D10.2040309@trash.net>
[-- Attachment #1: Type: text/plain, Size: 716 bytes --]
Patrick McHardy wrote:
> Andrew Morton wrote:
>> On Wed, 17 Oct 2007 07:36:16 -0700 (PDT)
>> bugme-daemon@bugzilla.kernel.org wrote:
>>
>>> http://bugzilla.kernel.org/show_bug.cgi?id=9174
>>>
>>> Summary: linux-2.6.23-git11 kernel panic
> >>
>
>>> EIP is at packet_rcv_0x1a2/0x360
>
>
> Please find out on which device the packet socket is opened by
> looking at /proc/net/packet and comparing the Iface shown there
> to the ifindexes listed in "ip link list".
Well, he replied in private mail, the device in question is
an IPv6-over-IPv4 tunnel, which doesn't have any header_ops,
so the crash happens in dev_parse_header when dereferencing
them.
Signed-off-by: Patrick McHardy <kaber@trash.net>
[-- Attachment #2: x --]
[-- Type: text/plain, Size: 434 bytes --]
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 39dd83b..452c88d 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -827,7 +827,7 @@ static inline int dev_parse_header(const struct sk_buff *skb,
{
const struct net_device *dev = skb->dev;
- if (!dev->header_ops->parse)
+ if (!dev->header_ops || !dev->header_ops->parse)
return 0;
return dev->header_ops->parse(skb, haddr);
}
^ permalink raw reply related
* Re: [PATCH] [TCP]: Remove lost_retrans zero special cases
From: Ilpo Järvinen @ 2007-10-18 11:07 UTC (permalink / raw)
To: TAKANO Ryousei, David Miller; +Cc: y-kodama, Netdev
In-Reply-To: <20071018.195558.103454352.takano@axe-inc.co.jp>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 3084 bytes --]
On Thu, 18 Oct 2007, TAKANO Ryousei wrote:
> From: "Ilpo Järvinen" <ilpo.jarvinen@helsinki.fi>
> Subject: [PATCH] [TCP]: Remove lost_retrans zero special cases
> Date: Thu, 18 Oct 2007 13:17:24 +0300 (EEST)
>
> > [PATCH] [TCP]: Remove lost_retrans zero seqno special cases
> >
> > Both high-sack detection and new lowest seq variables have
> > unnecessary zero special case which are now removed by setting
> > safe initial seqnos.
> >
> > This also fixes problem which caused zero received_upto being
> > passed to tcp_mark_lost_retrans which confused after relations
> > within the marker loop causing incorrect TCPCB_SACKED_RETRANS
> > clearing. The problem was noticed because of a performance
> > report from TAKANO Ryousei <takano@axe-inc.co.jp>.
> >
> > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
> > ---
> > net/ipv4/tcp_input.c | 6 +++---
> > 1 files changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
> > index 0f00966..9288220 100644
> > --- a/net/ipv4/tcp_input.c
> > +++ b/net/ipv4/tcp_input.c
> > @@ -1121,7 +1121,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
> > struct sk_buff *skb;
> > int flag = 0;
> > int cnt = 0;
> > - u32 new_low_seq = 0;
> > + u32 new_low_seq = tp->snd_nxt;
> >
> > tcp_for_write_queue(skb, sk) {
> > u32 ack_seq = TCP_SKB_CB(skb)->ack_seq;
> > @@ -1153,7 +1153,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
> > NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT);
> > }
> > } else {
> > - if (!new_low_seq || before(ack_seq, new_low_seq))
> > + if (before(ack_seq, new_low_seq))
> > new_low_seq = ack_seq;
> > cnt += tcp_skb_pcount(skb);
> > }
> > @@ -1242,7 +1242,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
> > int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
> > int reord = tp->packets_out;
> > int prior_fackets;
> > - u32 highest_sack_end_seq = 0;
> > + u32 highest_sack_end_seq = tp->lost_retrans_low;
> > int flag = 0;
> > int found_dup_sack = 0;
> > int cached_fack_count;
> > --
> > 1.5.0.6
>
> Thanks Ilpo! This patch solves the problem, as shown below:
>
> iteration :001 .... done. T = 17.365902 BW = 460.672876 Mbps
> iteration :002 .... done. T = 16.456351 BW = 486.134501 Mbps
> iteration :003 .... done. T = 16.658353 BW = 480.239550 Mbps
> iteration :004 .... done. T = 16.468834 BW = 485.766026 Mbps
> iteration :005 .... done. T = 16.596055 BW = 482.042268 Mbps
>
> Acked-by: Ryousei Takano <takano-ryousei@aist.go.jp>
Thanks for quick testing, it was actually quite bad bug. I first
thought that it's just performance issue and therefore suspected
that the problem is elsewhere until I realized that the zero can
be used as seqno.
Dave, please put this one to net-2.6 and forget the other patch with
title "[TCP]: Add highest_sack_end_seq check back...", it would just
add another (wrong) zero special case back (they won't conflict with
each other, so being this verbose here) :-).
--
i.
^ permalink raw reply
* Re: BUG: unable to handle kernel NULL pointer dereference at virtual address 000000b0
From: Krzysztof Oledzki @ 2007-10-18 11:22 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev
In-Reply-To: <47161415.1060808@cosmosbay.com>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 4054 bytes --]
On Wed, 17 Oct 2007, Eric Dumazet wrote:
> Krzysztof Oledzki a écrit :
>>
>>
>> On Wed, 17 Oct 2007, Eric Dumazet wrote:
>>
>>> Krzysztof Oledzki a écrit :
>>>>
>>>>
>>>> On Wed, 17 Oct 2007, Eric Dumazet wrote:
>>>>
>>>>> Krzysztof Oledzki a écrit :
>>>>>> Hello,
>>>>>>
>>>>>> Today I found in my logs:
>>>>>>
>>>>>> BUG: unable to handle kernel NULL pointer dereference at virtual
>>>>>> address 000000b0
>>>>>> printing eip:
>>>>>> 78395f65
>>>>>> *pde = 00000000
>>>>>> Oops: 0000 [#1]
>>>>>> PREEMPT SMP
>>>>>> CPU: 0
>>>>>> EIP: 0060:[<78395f65>] Not tainted VLI
>>>>>> EFLAGS: 00210286 (2.6.22.9 #1)
>>>>>> EIP is at __ip_route_output_key+0x412/0x722
>>>>>> eax: 80000000 ebx: 00000000 ecx: 5dd2b1c3 edx: 00000000
>>>>>> esi: 00000000 edi: d44c7e30 ebp: ec8c4980 esp: d44c7ddc
>>>>>> ds: 007b es: 007b fs: 00d8 gs: 0033 ss: 0068
>>>>>> Process smtpd (pid: 12479, ti=d44c6000 task=9e759510 task.ti=d44c6000)
>>>>>> Stack: d44c7e7c d44c7e7c d44c7eb8 00000000 d44c7e7c 00000000 00000000
>>>>>> 00000005
>>>>>> 00000000 ffffffff 5dd2b1c3 00000000 00000000 00000000 00000000
>>>>>> 00000000
>>>>>> 00000000 00000000 00000000 00000000 00000000 00030000 00000000
>>>>>> d44c7e7c
>>>>>> Call Trace:
>>>>>> [<78396280>] ip_route_output_flow+0xb/0x3e
>>>>>> [<783b2b29>] ip4_datagram_connect+0x1c9/0x308
>>>>>> [<783ba70a>] inet_dgram_connect+0x45/0x4e
>>>>>> [<7837135e>] sys_connect+0x72/0x9c
>>>>>> [<78371607>] sock_map_fd+0x41/0x4a
>>>>>> [<7840d1b1>] _spin_lock+0x33/0x3e
>>>>>> [<7840d623>] _spin_unlock+0x25/0x3b
>>>>>> [<78371607>] sock_map_fd+0x41/0x4a
>>>>>> [<78372792>] sys_socketcall+0x8f/0x242
>>>>>> [<7813e99c>] trace_hardirqs_on+0x122/0x14c
>>>>>> [<78103dc6>] sysenter_past_esp+0x8f/0x99
>>>>>> [<78103d96>] sysenter_past_esp+0x5f/0x99
>>>>>> =======================
>>>>>> Code: fa e0 00 00 00 75 07 c6 44 24 56 05 eb 14 81 fa f0 00 00 00 0f 84
>>>>>> e1 02 00 00 84 c0 0f 84 d9 02 00 00 8b 44 24 0c 0d 00 00 00 80 <f6> 86
>>>>>> b0 00 00 00 08 0f 44 44 24 0c 89 44 24 0c b8 01 00 00 00
>>>>>> EIP: [<78395f65>] __ip_route_output_key+0x412/0x722 SS:ESP
>>>>>> 0068:d44c7ddc
>>>>>>
>>>>>> Shortly before it there was:
>>>>>> Oct 17 07:17:55 cougar postfix/master[3400]: warning: process
>>>>>> /usr/lib/postfix/smtpd pid 12479 killed by signal 11
>>>>>>
>>>>>> Best regards,
>>>>>>
>>>>>>
>>>>>> Krzysztof Olędzki
>>>>>
>>>>> Hello Krzysztof
>>>>>
>>>>> Could you give us some details about this ? kernel version at least.
>>>>
>>>> Yes, I was little to hurry sending this bug report. Anyway, it is
>>>> 2.6.22.9 like mentioned in the oops: EFLAGS: 00210286 (2.6.22.9 #1)
>>>>
>>>>> (you could for example take a look at REPORTING-BUGS, or run
>>>>> scripts/ver_linux)
>>>>
>>>> Linux cougar 2.6.22.9 #1 SMP PREEMPT Wed Oct 3 10:24:19 CEST 2007 i686
>>>> Intel(R) Pentium(R) D CPU 3.20GHz GenuineIntel GNU/Linux
>>>>
>>>> Gnu C 4.1.2
>>>> Gnu make 3.81
>>>> binutils 2.17
>>>> util-linux 2.12r
>>>> mount 2.12r
>>>> module-init-tools 3.2.2
>>>> e2fsprogs 1.40.2
>>>> Linux C Library > libc.2.5
>>>> Dynamic linker (ldd) 2.5
>>>> Procps 3.2.7
>>>> Net-tools 1.60
>>>> Kbd 1.12
>>>> Sh-utils 6.9
>>>>
>>>
>>> Yes indeed, version was on your initial report.
>>>
>>> It seems this kernel is unusual (VMSPLIT_2G_OPT instead of stdandard
>>> VMSPLIT_3G), any chance you provide full .config ?
>>
>> Attached, both .config and dmesg.
>>
>
> Hum, you are using IPT_TPROXY thing, which is not in linux-2.6.22.9
It is only compiled in, not used at the moment.
> I have no idea how this can taint the kernel, since you provide no
> information.
>
> Try to reproduce the problem with a genuine kernel.
OK. Thank you.
Best regards,
Krzysztof Olędzki
^ permalink raw reply
* Re: [PATCH] PHYLIB: IRQ event workqueue handling fixes
From: Maciej W. Rozycki @ 2007-10-18 11:30 UTC (permalink / raw)
To: Jarek Poplawski
Cc: Andy Fleming, Andrew Morton, Jeff Garzik, netdev, linux-kernel
In-Reply-To: <20071017085809.GA1658@ff.dom.local>
On Wed, 17 Oct 2007, Jarek Poplawski wrote:
> I'm not sure free_irq() should maintain the depth count - rather warn
> on not zero. But, IMHO, any activity on freed irq seems suspicious to
> me (and doesn't look like very common), even if it's safe with current
> implementation.
No way to avoid it with DEBUG_SHIRQ.
> Yes, these DEBUG_SHIRQ checks are suspicious to me too, but they seem
> to be reasonable only in the case of possible resent irqs (so not for
> all irqs). On the other hand, it seems, proper irq handler with proper
> hardware shouldn't have any problems with such a check.
What do you mean by "proper irq handler with proper hardware"? Using
softirqs (they used to be called bottom-halves) is actually a natural way
of handling any interrupt which requires extensive processing.
> 1) phy_change() checks PHY_HALTED flag without lock; I think it's
> racy: eg. if it's done during phy_stop() it can check just before
> the flag is set and reenable interrupts just after phy_stop() ends.
I remember having a look into it, but it was long ago and I cannot
immediately recall the conclusion. Which means it is either broken or
deserves a comment as non-obvious. I will have a look into it again, but
I am resource-starved a little at the moment, sorry.
> 2) phy_change() doesn't reenable irq line after it sees returns
> with errors; IMHO it should at least write some warning, but maybe
> try some safety plan, so enable_irq() and try to disable interrupts
> and free_irq() on the next call (if it happens). (But, I can be very
> wrong with this - maybe it's OK and official way.)
No way to do this safely -- at this point the device probably still has
its interrupt output asserted and the register to clear it is
inaccessible, so enabling the line will enter an infinite loop. At this
point the system is no longer stable, so it is better to keep at least
some functionality, so that it may be attempted to be shut down cleanly,
rather than make it completely irresponsive. The alternative is panic().
> 3) phy_interrupt() checks PHY_HALTED flag without lock too, but I'm
> not sure now if it could be dangerous after fixing #1; on the other
> hand even if we know it's not our regular interrupt, with current
> DEBUG_SHIRQ it could be easier to call schedule_work() anyway since
> we are sure it's before/in free_irq() yet.
See #1 above.
> 4) phy_interrupt() should check return value from schedule_work() and
> enable irq on 0.
No -- the work already pending will do that.
> 5) phy_stop_interrupts(): maybe I miss something, but it seems
> phy_stop() is required before this, so maybe there should be a
> comment on this?
The API is documented in: Documentation/networking/phy.txt -- you are
welcome to improve. If you do not want to get into the gory details, just
use the cooked interface and phy_disconnect() will do the dirty work for
you.
> 6) phy_stop_interrupts(): if I'm not wrong with #3 calling
> phy_disable_interrupts() looks like we are not sure this phy_stop()
> really works; than maybe a WARN_ON?
WARN_ON what?
> 7) phy_stop_interrupts(): after above mentioned changes in
> phy_interrupt(), and phy_changes() (always enable_irq()) I can't see
> any reason why there should be more than one skipped enable_irq(),
> so checking return from cancel_work_sync() shouldn't be enough
> instead of this atomic counter.
CONFIG_DEBUG_SHIRQ. Barring this option, cancel_work_sync() could have
been moved to the front of free_irq(). I think I have seen this in
reality, with the interrupt line left stuck disabled afterwards, but I
will double check when I have an opportunity. The approach implemented
with this patch does work, which is the important bit, and if
simplification is possible, then it may be applied later.
> 8) phy_stop_interrupts(): I'm not sure this additional call from
> DEBUG_SHIRQ should be so dangerous, eg.:
>
> /*
> * status == PHY_HALTED &&
> * interrupts are stopped after phy_stop()
> */
> if (cancel_work_sync(...))
> enable_irq();
>
> free_irq(...);
> /*
> * possible schedule_work() from DEBUG_SHIRQ only,
> * but proper check for PHY_HALTED is done;
> * so, let's flush after this too:
> */
> cancel_work_sync();
Well, if there is another handler registered on this line, you'll get
your interrupt line stuck disabled.
> Of course, I don't know phy.c enough, so most of this can be terribly
> wrong, then feel free to forget about this - I don't expect you should
> waste any time for explaining me these things - after all they are
> doubts only.
I am not sure I know phy.c well enough either, ;-) and your concerns are
appreciated as interesting conclusions may develop. If someone disagrees
with what I have written here, they are welcome to speak out too.
Maciej
^ permalink raw reply
* Re: [PATCH 0/2] Interface groups, round two
From: Laszlo Attila Toth @ 2007-10-18 11:34 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netdev, netfilter-devel
In-Reply-To: <47173354.9060301@trash.net>
Patrick McHardy írta:
> Laszlo Attila Toth wrote:
>> Hello,
>>
>> Here is the new version of ifgroup patches.
>>
>> The interface group value is u_int32_t in net_device which should be
>> enough.
>> Previously it was an int.
>>
>> Usage:
>> ip link set eth0 group 4
>> but currently it cannot be unset, only changed to another value.
>
>
> The only reason why it can't be set to zero again seems to
> be this part from the iproute patch:
>
> + if (rtnl_ifgroup_a2n(&group, *argv) || group == 0)
>
> Why don't you allow a value of zero?
>
It has historical reason. The original version which didn't use netlink
(at kernel 2.6.17) used zero to indicate that group was not set. You
wrote previously that this part is useless for new kernels. I'll fix
this (with type of "group" variable to unsigned int32 to be consistent
with the kernel part).
--
Attila
^ permalink raw reply
* Re: [PATCH] PHYLIB: IRQ event workqueue handling fixes
From: Maciej W. Rozycki @ 2007-10-18 11:37 UTC (permalink / raw)
To: Jarek Poplawski
Cc: Andy Fleming, Andrew Morton, Jeff Garzik, netdev, linux-kernel
In-Reply-To: <20071018063157.GA1694@ff.dom.local>
On Thu, 18 Oct 2007, Jarek Poplawski wrote:
> After rethinking, it looks like this last cancel should be useless.
> So, if phy_interrupt() schedules only if !PHY_HALTED and phy_change()
> does enable_irq() with no exeptions, it seems phy_interrupt() even
> without lock must see PHY_HALTED state before this free_irq() with
> possible DEBUG_SHIRQ call, then maybe only this safety:
>
> WARN_ON(work_pending(&phydev->phy_queue));
Good point.
Maciej
^ 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