提交 7e20ef03 编写于 作者: L Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (49 commits)
  [SCTP]: Set assoc_id correctly during INIT collision.
  [SCTP]: Re-order SCTP initializations to avoid race with sctp_rcv()
  [SCTP]: Fix the SO_REUSEADDR handling to be similar to TCP.
  [SCTP]: Verify all destination ports in sctp_connectx.
  [XFRM] SPD info TLV aggregation
  [XFRM] SAD info TLV aggregationx
  [AF_RXRPC]: Sort out MTU handling.
  [AF_IUCV/IUCV] : Add missing section annotations
  [AF_IUCV]: Implementation of a skb backlog queue
  [NETLINK]: Remove bogus BUG_ON
  [IPV6]: Some cleanups in include/net/ipv6.h
  [TCP]: zero out rx_opt in tcp_disconnect()
  [BNX2]: Fix TSO problem with small MSS.
  [NET]: Rework dev_base via list_head (v3)
  [TCP] Highspeed: Limited slow-start is nowadays in tcp_slow_start
  [BNX2]: Update version and reldate.
  [BNX2]: Print bus information for PCIE devices.
  [BNX2]: Add 1-shot MSI handler for 5709.
  [BNX2]: Restructure PHY event handling.
  [BNX2]: Add indirect spinlock.
  ...
......@@ -107,7 +107,7 @@ static void appldata_get_net_sum_data(void *data)
tx_dropped = 0;
collisions = 0;
read_lock(&dev_base_lock);
for (dev = dev_base; dev != NULL; dev = dev->next) {
for_each_netdev(dev) {
stats = dev->get_stats(dev);
rx_packets += stats->rx_packets;
tx_packets += stats->tx_packets;
......
......@@ -686,7 +686,8 @@ static inline int solaris_i(unsigned int fd, unsigned int cmd, u32 arg)
int i = 0;
read_lock_bh(&dev_base_lock);
for (d = dev_base; d; d = d->next) i++;
for_each_netdev(d)
i++;
read_unlock_bh(&dev_base_lock);
if (put_user (i, (int __user *)A(arg)))
......
......@@ -194,15 +194,15 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
sl = sl_tail = NULL;
read_lock(&dev_base_lock);
for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) {
for_each_netdev(ifp) {
dev_hold(ifp);
if (!is_aoe_netif(ifp))
continue;
goto cont;
skb = new_skb(sizeof *h + sizeof *ch);
if (skb == NULL) {
printk(KERN_INFO "aoe: skb alloc failure\n");
continue;
goto cont;
}
skb_put(skb, sizeof *h + sizeof *ch);
skb->dev = ifp;
......@@ -221,6 +221,8 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
skb->next = sl;
sl = skb;
cont:
dev_put(ifp);
}
read_unlock(&dev_base_lock);
......
此差异已折叠。
/* bnx2.h: Broadcom NX2 network driver.
*
* Copyright (c) 2004, 2005, 2006 Broadcom Corporation
* Copyright (c) 2004-2007 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -24,8 +24,11 @@ struct tx_bd {
u32 tx_bd_haddr_hi;
u32 tx_bd_haddr_lo;
u32 tx_bd_mss_nbytes;
#define TX_BD_TCP6_OFF2_SHL (14)
u32 tx_bd_vlan_tag_flags;
#define TX_BD_FLAGS_CONN_FAULT (1<<0)
#define TX_BD_FLAGS_TCP6_OFF0_MSK (3<<1)
#define TX_BD_FLAGS_TCP6_OFF0_SHL (1)
#define TX_BD_FLAGS_TCP_UDP_CKSUM (1<<1)
#define TX_BD_FLAGS_IP_CKSUM (1<<2)
#define TX_BD_FLAGS_VLAN_TAG (1<<3)
......@@ -34,6 +37,7 @@ struct tx_bd {
#define TX_BD_FLAGS_END (1<<6)
#define TX_BD_FLAGS_START (1<<7)
#define TX_BD_FLAGS_SW_OPTION_WORD (0x1f<<8)
#define TX_BD_FLAGS_TCP6_OFF4_SHL (12)
#define TX_BD_FLAGS_SW_FLAGS (1<<13)
#define TX_BD_FLAGS_SW_SNAP (1<<14)
#define TX_BD_FLAGS_SW_LSO (1<<15)
......@@ -6292,6 +6296,41 @@ struct l2_fhdr {
#define MII_BNX2_DSP_ADDRESS 0x17
#define MII_BNX2_DSP_EXPAND_REG 0x0f00
#define MII_BNX2_BLK_ADDR 0x1f
#define MII_BNX2_BLK_ADDR_IEEE0 0x0000
#define MII_BNX2_BLK_ADDR_GP_STATUS 0x8120
#define MII_BNX2_GP_TOP_AN_STATUS1 0x1b
#define MII_BNX2_GP_TOP_AN_SPEED_MSK 0x3f00
#define MII_BNX2_GP_TOP_AN_SPEED_10 0x0000
#define MII_BNX2_GP_TOP_AN_SPEED_100 0x0100
#define MII_BNX2_GP_TOP_AN_SPEED_1G 0x0200
#define MII_BNX2_GP_TOP_AN_SPEED_2_5G 0x0300
#define MII_BNX2_GP_TOP_AN_SPEED_1GKV 0x0d00
#define MII_BNX2_GP_TOP_AN_FD 0x8
#define MII_BNX2_BLK_ADDR_SERDES_DIG 0x8300
#define MII_BNX2_SERDES_DIG_1000XCTL1 0x10
#define MII_BNX2_SD_1000XCTL1_FIBER 0x01
#define MII_BNX2_SD_1000XCTL1_AUTODET 0x10
#define MII_BNX2_SERDES_DIG_MISC1 0x18
#define MII_BNX2_SD_MISC1_FORCE_MSK 0xf
#define MII_BNX2_SD_MISC1_FORCE_2_5G 0x0
#define MII_BNX2_SD_MISC1_FORCE 0x10
#define MII_BNX2_BLK_ADDR_OVER1G 0x8320
#define MII_BNX2_OVER1G_UP1 0x19
#define MII_BNX2_BLK_ADDR_BAM_NXTPG 0x8350
#define MII_BNX2_BAM_NXTPG_CTL 0x10
#define MII_BNX2_NXTPG_CTL_BAM 0x1
#define MII_BNX2_NXTPG_CTL_T2 0x2
#define MII_BNX2_BLK_ADDR_CL73_USERB0 0x8370
#define MII_BNX2_CL73_BAM_CTL1 0x12
#define MII_BNX2_CL73_BAM_EN 0x8000
#define MII_BNX2_CL73_BAM_STA_MGR_EN 0x4000
#define MII_BNX2_CL73_BAM_NP_AFT_BP_EN 0x2000
#define MII_BNX2_BLK_ADDR_AER 0xffd0
#define MII_BNX2_AER_AER 0x1e
#define MII_BNX2_AER_AER_AN_MMD 0x3800
#define MII_BNX2_BLK_ADDR_COMBO_IEEEB0 0xffe0
#define MIN_ETHERNET_PACKET_SIZE 60
#define MAX_ETHERNET_PACKET_SIZE 1514
#define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014
......@@ -6429,13 +6468,15 @@ struct bnx2 {
u32 last_status_idx;
u32 flags;
#define PCIX_FLAG 1
#define PCI_32BIT_FLAG 2
#define ONE_TDMA_FLAG 4 /* no longer used */
#define NO_WOL_FLAG 8
#define USING_DAC_FLAG 0x10
#define USING_MSI_FLAG 0x20
#define ASF_ENABLE_FLAG 0x40
#define PCIX_FLAG 0x00000001
#define PCI_32BIT_FLAG 0x00000002
#define ONE_TDMA_FLAG 0x00000004 /* no longer used */
#define NO_WOL_FLAG 0x00000008
#define USING_MSI_FLAG 0x00000020
#define ASF_ENABLE_FLAG 0x00000040
#define MSI_CAP_FLAG 0x00000080
#define ONE_SHOT_MSI_FLAG 0x00000100
#define PCIE_FLAG 0x00000200
/* Put tx producer and consumer fields in separate cache lines. */
......@@ -6484,6 +6525,7 @@ struct bnx2 {
/* Used to synchronize phy accesses. */
spinlock_t phy_lock;
spinlock_t indirect_lock;
u32 phy_flags;
#define PHY_SERDES_FLAG 1
......@@ -6495,6 +6537,13 @@ struct bnx2 {
#define PHY_INT_MODE_LINK_READY_FLAG 0x200
#define PHY_DIS_EARLY_DAC_FLAG 0x400
u32 mii_bmcr;
u32 mii_bmsr;
u32 mii_bmsr1;
u32 mii_adv;
u32 mii_lpa;
u32 mii_up1;
u32 chip_id;
/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
#define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000)
......
此差异已折叠。
此差异已折叠。
......@@ -1971,8 +1971,7 @@ static struct net_device *get_strip_dev(struct strip *strip_info)
sizeof(zero_address))) {
struct net_device *dev;
read_lock_bh(&dev_base_lock);
dev = dev_base;
while (dev) {
for_each_netdev(dev) {
if (dev->type == strip_info->dev->type &&
!memcmp(dev->dev_addr,
&strip_info->true_dev_addr,
......@@ -1983,7 +1982,6 @@ static struct net_device *get_strip_dev(struct strip *strip_info)
read_unlock_bh(&dev_base_lock);
return (dev);
}
dev = dev->next;
}
read_unlock_bh(&dev_base_lock);
}
......
......@@ -365,7 +365,7 @@ static __inline__ int led_get_net_activity(void)
* for reading should be OK */
read_lock(&dev_base_lock);
rcu_read_lock();
for (dev = dev_base; dev; dev = dev->next) {
for_each_netdev(dev) {
struct net_device_stats *stats;
struct in_device *in_dev = __in_dev_get_rcu(dev);
if (!in_dev || !in_dev->ifa_list)
......
......@@ -2020,7 +2020,6 @@ config AFS_FS
tristate "Andrew File System support (AFS) (EXPERIMENTAL)"
depends on INET && EXPERIMENTAL
select AF_RXRPC
select KEYS
help
If you say Y here, you will get an experimental Andrew File System
driver. It currently only supports unsecured read-only AFS access.
......
......@@ -18,7 +18,7 @@ kafs-objs := \
security.o \
server.o \
super.o \
use-rtnetlink.o \
netdevices.o \
vlclient.o \
vlocation.o \
vnode.o \
......
......@@ -468,7 +468,7 @@ int __init afs_callback_update_init(void)
/*
* shut down the callback update process
*/
void __exit afs_callback_update_kill(void)
void afs_callback_update_kill(void)
{
destroy_workqueue(afs_callback_update_worker);
}
......@@ -443,6 +443,7 @@ static void SRXAFSCB_GetCapabilities(struct work_struct *work)
reply.ia.netmask[loop] = ifs[loop].netmask.s_addr;
reply.ia.mtu[loop] = htonl(ifs[loop].mtu);
}
kfree(ifs);
}
reply.cap.capcount = htonl(1);
......
......@@ -266,7 +266,8 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call,
call->unmarshall++;
if (call->count < PAGE_SIZE) {
buffer = kmap_atomic(call->reply3, KM_USER0);
page = call->reply3;
buffer = kmap_atomic(page, KM_USER0);
memset(buffer + PAGE_SIZE - call->count, 0,
call->count);
kunmap_atomic(buffer, KM_USER0);
......
......@@ -349,7 +349,6 @@ struct afs_permits {
* record of one of a system's set of network interfaces
*/
struct afs_interface {
unsigned index; /* interface index */
struct in_addr address; /* IPv4 address bound to interface */
struct in_addr netmask; /* netmask applied to address */
unsigned mtu; /* MTU of interface */
......@@ -392,7 +391,7 @@ extern void afs_give_up_callback(struct afs_vnode *);
extern void afs_dispatch_give_up_callbacks(struct work_struct *);
extern void afs_flush_callback_breaks(struct afs_server *);
extern int __init afs_callback_update_init(void);
extern void __exit afs_callback_update_kill(void);
extern void afs_callback_update_kill(void);
/*
* cell.c
......@@ -564,7 +563,7 @@ extern void afs_fs_exit(void);
* use-rtnetlink.c
*/
extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool);
extern int afs_get_MAC_address(u8 [6]);
extern int afs_get_MAC_address(u8 *, size_t);
/*
* vlclient.c
......@@ -591,7 +590,7 @@ extern struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *,
struct key *,
const char *, size_t);
extern void afs_put_vlocation(struct afs_vlocation *);
extern void __exit afs_vlocation_purge(void);
extern void afs_vlocation_purge(void);
/*
* vnode.c
......
......@@ -54,7 +54,7 @@ static int __init afs_get_client_UUID(void)
/* read the MAC address of one of the external interfaces and construct
* a UUID from it */
ret = afs_get_MAC_address(afs_uuid.node);
ret = afs_get_MAC_address(afs_uuid.node, sizeof(afs_uuid.node));
if (ret < 0)
return ret;
......
/* AFS network device helpers
*
* Copyright (c) 2007 Patrick McHardy <kaber@trash.net>
*/
#include <linux/string.h>
#include <linux/rtnetlink.h>
#include <linux/inetdevice.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include "internal.h"
/*
* get a MAC address from a random ethernet interface that has a real one
* - the buffer will normally be 6 bytes in size
*/
int afs_get_MAC_address(u8 *mac, size_t maclen)
{
struct net_device *dev;
int ret = -ENODEV;
if (maclen != ETH_ALEN)
BUG();
rtnl_lock();
dev = __dev_getfirstbyhwtype(ARPHRD_ETHER);
if (dev) {
memcpy(mac, dev->dev_addr, maclen);
ret = 0;
}
rtnl_unlock();
return ret;
}
/*
* get a list of this system's interface IPv4 addresses, netmasks and MTUs
* - maxbufs must be at least 1
* - returns the number of interface records in the buffer
*/
int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs,
bool wantloopback)
{
struct net_device *dev;
struct in_device *idev;
int n = 0;
ASSERT(maxbufs > 0);
rtnl_lock();
for_each_netdev(dev) {
if (dev->type == ARPHRD_LOOPBACK && !wantloopback)
continue;
idev = __in_dev_get_rtnl(dev);
if (!idev)
continue;
for_primary_ifa(idev) {
bufs[n].address.s_addr = ifa->ifa_address;
bufs[n].netmask.s_addr = ifa->ifa_mask;
bufs[n].mtu = dev->mtu;
n++;
if (n >= maxbufs)
goto out;
} endfor_ifa(idev);
}
out:
rtnl_unlock();
return n;
}
......@@ -20,6 +20,7 @@
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/parser.h>
#include "internal.h"
#define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
......@@ -42,7 +43,7 @@ struct file_system_type afs_fs_type = {
.name = "afs",
.get_sb = afs_get_sb,
.kill_sb = kill_anon_super,
.fs_flags = FS_BINARY_MOUNTDATA,
.fs_flags = 0,
};
static const struct super_operations afs_super_ops = {
......@@ -58,6 +59,20 @@ static const struct super_operations afs_super_ops = {
static struct kmem_cache *afs_inode_cachep;
static atomic_t afs_count_active_inodes;
enum {
afs_no_opt,
afs_opt_cell,
afs_opt_rwpath,
afs_opt_vol,
};
static const match_table_t afs_options_list = {
{ afs_opt_cell, "cell=%s" },
{ afs_opt_rwpath, "rwpath" },
{ afs_opt_vol, "vol=%s" },
{ afs_no_opt, NULL },
};
/*
* initialise the filesystem
*/
......@@ -114,31 +129,6 @@ void __exit afs_fs_exit(void)
_leave("");
}
/*
* check that an argument has a value
*/
static int want_arg(char **_value, const char *option)
{
if (!_value || !*_value || !**_value) {
printk(KERN_NOTICE "kAFS: %s: argument missing\n", option);
return 0;
}
return 1;
}
/*
* check that there's no subsequent value
*/
static int want_no_value(char *const *_value, const char *option)
{
if (*_value && **_value) {
printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n",
option, *_value);
return 0;
}
return 1;
}
/*
* parse the mount options
* - this function has been shamelessly adapted from the ext3 fs which
......@@ -148,48 +138,46 @@ static int afs_parse_options(struct afs_mount_params *params,
char *options, const char **devname)
{
struct afs_cell *cell;
char *key, *value;
int ret;
substring_t args[MAX_OPT_ARGS];
char *p;
int token;
_enter("%s", options);
options[PAGE_SIZE - 1] = 0;
ret = 0;
while ((key = strsep(&options, ","))) {
value = strchr(key, '=');
if (value)
*value++ = 0;
_debug("kAFS: KEY: %s, VAL:%s", key, value ?: "-");
while ((p = strsep(&options, ","))) {
if (!*p)
continue;
if (strcmp(key, "rwpath") == 0) {
if (!want_no_value(&value, "rwpath"))
return -EINVAL;
params->rwpath = 1;
} else if (strcmp(key, "vol") == 0) {
if (!want_arg(&value, "vol"))
return -EINVAL;
*devname = value;
} else if (strcmp(key, "cell") == 0) {
if (!want_arg(&value, "cell"))
return -EINVAL;
cell = afs_cell_lookup(value, strlen(value));
token = match_token(p, afs_options_list, args);
switch (token) {
case afs_opt_cell:
cell = afs_cell_lookup(args[0].from,
args[0].to - args[0].from);
if (IS_ERR(cell))
return PTR_ERR(cell);
afs_put_cell(params->cell);
params->cell = cell;
} else {
printk("kAFS: Unknown mount option: '%s'\n", key);
ret = -EINVAL;
goto error;
break;
case afs_opt_rwpath:
params->rwpath = 1;
break;
case afs_opt_vol:
*devname = args[0].from;
break;
default:
printk(KERN_ERR "kAFS:"
" Unknown or invalid mount option: '%s'\n", p);
return -EINVAL;
}
}
ret = 0;
error:
_leave(" = %d", ret);
return ret;
_leave(" = 0");
return 0;
}
/*
......@@ -361,7 +349,6 @@ static int afs_fill_super(struct super_block *sb, void *data)
/*
* get an AFS superblock
* - TODO: don't use get_sb_nodev(), but rather call sget() directly
*/
static int afs_get_sb(struct file_system_type *fs_type,
int flags,
......@@ -386,7 +373,6 @@ static int afs_get_sb(struct file_system_type *fs_type,
goto error;
}
ret = afs_parse_device_name(&params, dev_name);
if (ret < 0)
goto error;
......
/* RTNETLINK client
*
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/if_addr.h>
#include <linux/if_arp.h>
#include <linux/inetdevice.h>
#include <net/netlink.h>
#include "internal.h"
struct afs_rtm_desc {
struct socket *nlsock;
struct afs_interface *bufs;
u8 *mac;
size_t nbufs;
size_t maxbufs;
void *data;
ssize_t datalen;
size_t datamax;
int msg_seq;
unsigned mac_index;
bool wantloopback;
int (*parse)(struct afs_rtm_desc *, struct nlmsghdr *);
};
/*
* parse an RTM_GETADDR response
*/
static int afs_rtm_getaddr_parse(struct afs_rtm_desc *desc,
struct nlmsghdr *nlhdr)
{
struct afs_interface *this;
struct ifaddrmsg *ifa;
struct rtattr *rtattr;
const char *name;
size_t len;
ifa = (struct ifaddrmsg *) NLMSG_DATA(nlhdr);
_enter("{ix=%d,af=%d}", ifa->ifa_index, ifa->ifa_family);
if (ifa->ifa_family != AF_INET) {
_leave(" = 0 [family %d]", ifa->ifa_family);
return 0;
}
if (desc->nbufs >= desc->maxbufs) {
_leave(" = 0 [max %zu/%zu]", desc->nbufs, desc->maxbufs);
return 0;
}
this = &desc->bufs[desc->nbufs];
this->index = ifa->ifa_index;
this->netmask.s_addr = inet_make_mask(ifa->ifa_prefixlen);
this->mtu = 0;
rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifaddrmsg));
len = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifaddrmsg));
name = "unknown";
for (; RTA_OK(rtattr, len); rtattr = RTA_NEXT(rtattr, len)) {
switch (rtattr->rta_type) {
case IFA_ADDRESS:
memcpy(&this->address, RTA_DATA(rtattr), 4);
break;
case IFA_LABEL:
name = RTA_DATA(rtattr);
break;
}
}
_debug("%s: "NIPQUAD_FMT"/"NIPQUAD_FMT,
name, NIPQUAD(this->address), NIPQUAD(this->netmask));
desc->nbufs++;
_leave(" = 0");
return 0;
}
/*
* parse an RTM_GETLINK response for MTUs
*/
static int afs_rtm_getlink_if_parse(struct afs_rtm_desc *desc,
struct nlmsghdr *nlhdr)
{
struct afs_interface *this;
struct ifinfomsg *ifi;
struct rtattr *rtattr;
const char *name;
size_t len, loop;
ifi = (struct ifinfomsg *) NLMSG_DATA(nlhdr);
_enter("{ix=%d}", ifi->ifi_index);
for (loop = 0; loop < desc->nbufs; loop++) {
this = &desc->bufs[loop];
if (this->index == ifi->ifi_index)
goto found;
}
_leave(" = 0 [no match]");
return 0;
found:
if (ifi->ifi_type == ARPHRD_LOOPBACK && !desc->wantloopback) {
_leave(" = 0 [loopback]");
return 0;
}
rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifinfomsg));
len = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifinfomsg));
name = "unknown";
for (; RTA_OK(rtattr, len); rtattr = RTA_NEXT(rtattr, len)) {
switch (rtattr->rta_type) {
case IFLA_MTU:
memcpy(&this->mtu, RTA_DATA(rtattr), 4);
break;
case IFLA_IFNAME:
name = RTA_DATA(rtattr);
break;
}
}
_debug("%s: "NIPQUAD_FMT"/"NIPQUAD_FMT" mtu %u",
name, NIPQUAD(this->address), NIPQUAD(this->netmask),
this->mtu);
_leave(" = 0");
return 0;
}
/*
* parse an RTM_GETLINK response for the MAC address belonging to the lowest
* non-internal interface
*/
static int afs_rtm_getlink_mac_parse(struct afs_rtm_desc *desc,
struct nlmsghdr *nlhdr)
{
struct ifinfomsg *ifi;
struct rtattr *rtattr;
const char *name;
size_t remain, len;
bool set;
ifi = (struct ifinfomsg *) NLMSG_DATA(nlhdr);
_enter("{ix=%d}", ifi->ifi_index);
if (ifi->ifi_index >= desc->mac_index) {
_leave(" = 0 [high]");
return 0;
}
if (ifi->ifi_type == ARPHRD_LOOPBACK) {
_leave(" = 0 [loopback]");
return 0;
}
rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifinfomsg));
remain = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifinfomsg));
name = "unknown";
set = false;
for (; RTA_OK(rtattr, remain); rtattr = RTA_NEXT(rtattr, remain)) {
switch (rtattr->rta_type) {
case IFLA_ADDRESS:
len = RTA_PAYLOAD(rtattr);
memcpy(desc->mac, RTA_DATA(rtattr),
min_t(size_t, len, 6));
desc->mac_index = ifi->ifi_index;
set = true;
break;
case IFLA_IFNAME:
name = RTA_DATA(rtattr);
break;
}
}
if (set)
_debug("%s: %02x:%02x:%02x:%02x:%02x:%02x",
name,
desc->mac[0], desc->mac[1], desc->mac[2],
desc->mac[3], desc->mac[4], desc->mac[5]);
_leave(" = 0");
return 0;
}
/*
* read the rtnetlink response and pass to parsing routine
*/
static int afs_read_rtm(struct afs_rtm_desc *desc)
{
struct nlmsghdr *nlhdr, tmphdr;
struct msghdr msg;
struct kvec iov[1];
void *data;
bool last = false;
int len, ret, remain;
_enter("");
do {
/* first of all peek to see how big the packet is */
memset(&msg, 0, sizeof(msg));
iov[0].iov_base = &tmphdr;
iov[0].iov_len = sizeof(tmphdr);
len = kernel_recvmsg(desc->nlsock, &msg, iov, 1,
sizeof(tmphdr), MSG_PEEK | MSG_TRUNC);
if (len < 0) {
_leave(" = %d [peek]", len);
return len;
}
if (len == 0)
continue;
if (len < sizeof(tmphdr) || len < NLMSG_PAYLOAD(&tmphdr, 0)) {
_leave(" = -EMSGSIZE");
return -EMSGSIZE;
}
if (desc->datamax < len) {
kfree(desc->data);
desc->data = NULL;
data = kmalloc(len, GFP_KERNEL);
if (!data)
return -ENOMEM;
desc->data = data;
}
desc->datamax = len;
/* read all the data from this packet */
iov[0].iov_base = desc->data;
iov[0].iov_len = desc->datamax;
desc->datalen = kernel_recvmsg(desc->nlsock, &msg, iov, 1,
desc->datamax, 0);
if (desc->datalen < 0) {
_leave(" = %zd [recv]", desc->datalen);
return desc->datalen;
}
nlhdr = desc->data;
/* check if the header is valid */
if (!NLMSG_OK(nlhdr, desc->datalen) ||
nlhdr->nlmsg_type == NLMSG_ERROR) {
_leave(" = -EIO");
return -EIO;
}
/* see if this is the last message */
if (nlhdr->nlmsg_type == NLMSG_DONE ||
!(nlhdr->nlmsg_flags & NLM_F_MULTI))
last = true;
/* parse the bits we got this time */
nlmsg_for_each_msg(nlhdr, desc->data, desc->datalen, remain) {
ret = desc->parse(desc, nlhdr);
if (ret < 0) {
_leave(" = %d [parse]", ret);
return ret;
}
}
} while (!last);
_leave(" = 0");
return 0;
}
/*
* list the interface bound addresses to get the address and netmask
*/
static int afs_rtm_getaddr(struct afs_rtm_desc *desc)
{
struct msghdr msg;
struct kvec iov[1];
int ret;
struct {
struct nlmsghdr nl_msg __attribute__((aligned(NLMSG_ALIGNTO)));
struct ifaddrmsg addr_msg __attribute__((aligned(NLMSG_ALIGNTO)));
} request;
_enter("");
memset(&request, 0, sizeof(request));
request.nl_msg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
request.nl_msg.nlmsg_type = RTM_GETADDR;
request.nl_msg.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
request.nl_msg.nlmsg_seq = desc->msg_seq++;
request.nl_msg.nlmsg_pid = 0;
memset(&msg, 0, sizeof(msg));
iov[0].iov_base = &request;
iov[0].iov_len = sizeof(request);
ret = kernel_sendmsg(desc->nlsock, &msg, iov, 1, iov[0].iov_len);
_leave(" = %d", ret);
return ret;
}
/*
* list the interface link statuses to get the MTUs
*/
static int afs_rtm_getlink(struct afs_rtm_desc *desc)
{
struct msghdr msg;
struct kvec iov[1];
int ret;
struct {
struct nlmsghdr nl_msg __attribute__((aligned(NLMSG_ALIGNTO)));
struct ifinfomsg link_msg __attribute__((aligned(NLMSG_ALIGNTO)));
} request;
_enter("");
memset(&request, 0, sizeof(request));
request.nl_msg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
request.nl_msg.nlmsg_type = RTM_GETLINK;
request.nl_msg.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
request.nl_msg.nlmsg_seq = desc->msg_seq++;
request.nl_msg.nlmsg_pid = 0;
memset(&msg, 0, sizeof(msg));
iov[0].iov_base = &request;
iov[0].iov_len = sizeof(request);
ret = kernel_sendmsg(desc->nlsock, &msg, iov, 1, iov[0].iov_len);
_leave(" = %d", ret);
return ret;
}
/*
* cull any interface records for which there isn't an MTU value
*/
static void afs_cull_interfaces(struct afs_rtm_desc *desc)
{
struct afs_interface *bufs = desc->bufs;
size_t nbufs = desc->nbufs;
int loop, point = 0;
_enter("{%zu}", nbufs);
for (loop = 0; loop < nbufs; loop++) {
if (desc->bufs[loop].mtu != 0) {
if (loop != point) {
ASSERTCMP(loop, >, point);
bufs[point] = bufs[loop];
}
point++;
}
}
desc->nbufs = point;
_leave(" [%zu/%zu]", desc->nbufs, nbufs);
}
/*
* get a list of this system's interface IPv4 addresses, netmasks and MTUs
* - returns the number of interface records in the buffer
*/
int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs,
bool wantloopback)
{
struct afs_rtm_desc desc;
int ret, loop;
_enter("");
memset(&desc, 0, sizeof(desc));
desc.bufs = bufs;
desc.maxbufs = maxbufs;
desc.wantloopback = wantloopback;
ret = sock_create_kern(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE,
&desc.nlsock);
if (ret < 0) {
_leave(" = %d [sock]", ret);
return ret;
}
/* issue RTM_GETADDR */
desc.parse = afs_rtm_getaddr_parse;
ret = afs_rtm_getaddr(&desc);
if (ret < 0)
goto error;
ret = afs_read_rtm(&desc);
if (ret < 0)
goto error;
/* issue RTM_GETLINK */
desc.parse = afs_rtm_getlink_if_parse;
ret = afs_rtm_getlink(&desc);
if (ret < 0)
goto error;
ret = afs_read_rtm(&desc);
if (ret < 0)
goto error;
afs_cull_interfaces(&desc);
ret = desc.nbufs;
for (loop = 0; loop < ret; loop++)
_debug("[%d] "NIPQUAD_FMT"/"NIPQUAD_FMT" mtu %u",
bufs[loop].index,
NIPQUAD(bufs[loop].address),
NIPQUAD(bufs[loop].netmask),
bufs[loop].mtu);
error:
kfree(desc.data);
sock_release(desc.nlsock);
_leave(" = %d", ret);
return ret;
}
/*
* get a MAC address from a random ethernet interface that has a real one
* - the buffer should be 6 bytes in size
*/
int afs_get_MAC_address(u8 mac[6])
{
struct afs_rtm_desc desc;
int ret;
_enter("");
memset(&desc, 0, sizeof(desc));
desc.mac = mac;
desc.mac_index = UINT_MAX;
ret = sock_create_kern(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE,
&desc.nlsock);
if (ret < 0) {
_leave(" = %d [sock]", ret);
return ret;
}
/* issue RTM_GETLINK */
desc.parse = afs_rtm_getlink_mac_parse;
ret = afs_rtm_getlink(&desc);
if (ret < 0)
goto error;
ret = afs_read_rtm(&desc);
if (ret < 0)
goto error;
if (desc.mac_index < UINT_MAX) {
/* got a MAC address */
_debug("[%d] %02x:%02x:%02x:%02x:%02x:%02x",
desc.mac_index,
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
} else {
ret = -ENONET;
}
error:
sock_release(desc.nlsock);
_leave(" = %d", ret);
return ret;
}
......@@ -602,7 +602,7 @@ int __init afs_vlocation_update_init(void)
/*
* discard all the volume location records for rmmod
*/
void __exit afs_vlocation_purge(void)
void afs_vlocation_purge(void)
{
afs_vlocation_timeout = 0;
......
......@@ -434,6 +434,7 @@ struct ethtool_ops {
#define SUPPORTED_10000baseT_Full (1 << 12)
#define SUPPORTED_Pause (1 << 13)
#define SUPPORTED_Asym_Pause (1 << 14)
#define SUPPORTED_2500baseX_Full (1 << 15)
/* Indicates what features are advertised by the interface. */
#define ADVERTISED_10baseT_Half (1 << 0)
......@@ -451,6 +452,7 @@ struct ethtool_ops {
#define ADVERTISED_10000baseT_Full (1 << 12)
#define ADVERTISED_Pause (1 << 13)
#define ADVERTISED_Asym_Pause (1 << 14)
#define ADVERTISED_2500baseX_Full (1 << 15)
/* The following are all involved in forcing a particular link
* mode for the device for setting things. When getting the
......
......@@ -304,7 +304,7 @@ struct net_device
unsigned long state;
struct net_device *next;
struct list_head dev_list;
/* The device initialization function. Called only once. */
int (*init)(struct net_device *dev);
......@@ -575,13 +575,36 @@ struct packet_type {
#include <linux/notifier.h>
extern struct net_device loopback_dev; /* The loopback */
extern struct net_device *dev_base; /* All devices */
extern struct list_head dev_base_head; /* All devices */
extern rwlock_t dev_base_lock; /* Device list lock */
#define for_each_netdev(d) \
list_for_each_entry(d, &dev_base_head, dev_list)
#define for_each_netdev_safe(d, n) \
list_for_each_entry_safe(d, n, &dev_base_head, dev_list)
#define for_each_netdev_continue(d) \
list_for_each_entry_continue(d, &dev_base_head, dev_list)
#define net_device_entry(lh) list_entry(lh, struct net_device, dev_list)
static inline struct net_device *next_net_device(struct net_device *dev)
{
struct list_head *lh;
lh = dev->dev_list.next;
return lh == &dev_base_head ? NULL : net_device_entry(lh);
}
static inline struct net_device *first_net_device(void)
{
return list_empty(&dev_base_head) ? NULL :
net_device_entry(dev_base_head.next);
}
extern int netdev_boot_setup_check(struct net_device *dev);
extern unsigned long netdev_boot_base(const char *prefix, int unit);
extern struct net_device *dev_getbyhwaddr(unsigned short type, char *hwaddr);
extern struct net_device *dev_getfirstbyhwtype(unsigned short type);
extern struct net_device *__dev_getfirstbyhwtype(unsigned short type);
extern void dev_add_pack(struct packet_type *pt);
extern void dev_remove_pack(struct packet_type *pt);
extern void __dev_remove_pack(struct packet_type *pt);
......
......@@ -87,24 +87,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
/* delete keymap entries */
void nf_ct_gre_keymap_destroy(struct nf_conn *ct);
/* get pointer to gre key, if present */
static inline __be32 *gre_key(struct gre_hdr *greh)
{
if (!greh->key)
return NULL;
if (greh->csum || greh->routing)
return (__be32 *)(greh+sizeof(*greh)+4);
return (__be32 *)(greh+sizeof(*greh));
}
/* get pointer ot gre csum, if present */
static inline __sum16 *gre_csum(struct gre_hdr *greh)
{
if (!greh->csum)
return NULL;
return (__sum16 *)(greh+sizeof(*greh));
}
extern void nf_ct_gre_keymap_flush(void);
extern void nf_nat_need_gre(void);
......
......@@ -55,18 +55,25 @@ static inline int nf_bridge_maybe_copy_header(struct sk_buff *skb)
return 0;
}
static inline unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb)
{
switch (skb->protocol) {
case __constant_htons(ETH_P_8021Q):
return VLAN_HLEN;
case __constant_htons(ETH_P_PPP_SES):
return PPPOE_SES_HLEN;
default:
return 0;
}
}
/* This is called by the IP fragmenting code and it ensures there is
* enough room for the encapsulating header (if there is one). */
static inline int nf_bridge_pad(const struct sk_buff *skb)
static inline unsigned int nf_bridge_pad(const struct sk_buff *skb)
{
int padding = 0;
if (skb->nf_bridge && skb->protocol == htons(ETH_P_8021Q))
padding = VLAN_HLEN;
else if (skb->nf_bridge && skb->protocol == htons(ETH_P_PPP_SES))
padding = PPPOE_SES_HLEN;
return padding;
if (skb->nf_bridge)
return nf_bridge_encap_header_len(skb);
return 0;
}
struct bridge_skb_cb {
......
......@@ -11,10 +11,10 @@
/* associates an integer enumerator with a pattern string. */
struct match_token {
int token;
char *pattern;
const char *pattern;
};
typedef struct match_token match_table_t[];
typedef const struct match_token match_table_t[];
/* Maximum number of arguments that match_token will find in a pattern */
enum {MAX_OPT_ARGS = 3};
......@@ -29,5 +29,5 @@ int match_token(char *, match_table_t table, substring_t args[]);
int match_int(substring_t *, int *result);
int match_octal(substring_t *, int *result);
int match_hex(substring_t *, int *result);
void match_strcpy(char *, substring_t *);
char *match_strdup(substring_t *);
void match_strcpy(char *, const substring_t *);
char *match_strdup(const substring_t *);
......@@ -1926,6 +1926,7 @@
#define PCI_DEVICE_ID_TIGON3_5752 0x1600
#define PCI_DEVICE_ID_TIGON3_5752M 0x1601
#define PCI_DEVICE_ID_NX2_5709 0x1639
#define PCI_DEVICE_ID_NX2_5709S 0x163a
#define PCI_DEVICE_ID_TIGON3_5700 0x1644
#define PCI_DEVICE_ID_TIGON3_5701 0x1645
#define PCI_DEVICE_ID_TIGON3_5702 0x1646
......
......@@ -197,7 +197,7 @@ typedef unsigned char *sk_buff_data_t;
* @tstamp: Time we arrived
* @dev: Device we arrived on/are leaving by
* @iif: ifindex of device we arrived on
* @h: Transport layer header
* @transport_header: Transport layer header
* @network_header: Network layer header
* @mac_header: Link layer header
* @dst: destination entry
......
......@@ -243,17 +243,6 @@ enum xfrm_ae_ftype_t {
#define XFRM_AE_MAX (__XFRM_AE_MAX - 1)
};
/* SAD Table filter flags */
enum xfrm_sad_ftype_t {
XFRM_SAD_UNSPEC,
XFRM_SAD_HMASK=1,
XFRM_SAD_HMAX=2,
XFRM_SAD_CNT=4,
__XFRM_SAD_MAX
#define XFRM_SAD_MAX (__XFRM_SAD_MAX - 1)
};
struct xfrm_userpolicy_type {
__u8 type;
__u16 reserved1;
......@@ -287,44 +276,41 @@ enum xfrm_attr_type_t {
enum xfrm_sadattr_type_t {
XFRMA_SAD_UNSPEC,
XFRMA_SADHMASK,
XFRMA_SADHMAX,
XFRMA_SADCNT,
XFRMA_SAD_CNT,
XFRMA_SAD_HINFO,
__XFRMA_SAD_MAX
#define XFRMA_SAD_MAX (__XFRMA_SAD_MAX - 1)
};
/* SPD Table filter flags */
enum xfrm_spd_ftype_t {
XFRM_SPD_UNSPEC,
XFRM_SPD_HMASK=1,
XFRM_SPD_HMAX=2,
XFRM_SPD_ICNT=4,
XFRM_SPD_OCNT=8,
XFRM_SPD_FCNT=16,
XFRM_SPD_ISCNT=32,
XFRM_SPD_OSCNT=64,
XFRM_SPD_FSCNT=128,
__XFRM_SPD_MAX
#define XFRM_SPD_MAX (__XFRM_SPD_MAX - 1)
struct xfrmu_sadhinfo {
__u32 sadhcnt; /* current hash bkts */
__u32 sadhmcnt; /* max allowed hash bkts */
};
enum xfrm_spdattr_type_t {
XFRMA_SPD_UNSPEC,
XFRMA_SPDHMASK,
XFRMA_SPDHMAX,
XFRMA_SPDICNT,
XFRMA_SPDOCNT,
XFRMA_SPDFCNT,
XFRMA_SPDISCNT,
XFRMA_SPDOSCNT,
XFRMA_SPDFSCNT,
XFRMA_SPD_INFO,
XFRMA_SPD_HINFO,
__XFRMA_SPD_MAX
#define XFRMA_SPD_MAX (__XFRMA_SPD_MAX - 1)
};
struct xfrmu_spdinfo {
__u32 incnt;
__u32 outcnt;
__u32 fwdcnt;
__u32 inscnt;
__u32 outscnt;
__u32 fwdscnt;
};
struct xfrmu_spdhinfo {
__u32 spdhcnt;
__u32 spdhmcnt;
};
struct xfrm_usersa_info {
struct xfrm_selector sel;
struct xfrm_id id;
......
......@@ -204,9 +204,9 @@ struct ip6_flowlabel
{
struct ip6_flowlabel *next;
__be32 label;
atomic_t users;
struct in6_addr dst;
struct ipv6_txoptions *opt;
atomic_t users;
unsigned long linger;
u8 share;
u32 owner;
......@@ -291,7 +291,7 @@ static inline int ipv6_addr_src_scope(const struct in6_addr *addr)
static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2)
{
return memcmp((const void *) a1, (const void *) a2, sizeof(struct in6_addr));
return memcmp(a1, a2, sizeof(struct in6_addr));
}
static inline int
......@@ -308,7 +308,7 @@ ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m,
static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2)
{
memcpy((void *) a1, (const void *) a2, sizeof(struct in6_addr));
memcpy(a1, a2, sizeof(struct in6_addr));
}
static inline void ipv6_addr_prefix(struct in6_addr *pfx,
......@@ -319,16 +319,12 @@ static inline void ipv6_addr_prefix(struct in6_addr *pfx,
int o = plen >> 3,
b = plen & 0x7;
memset(pfx->s6_addr, 0, sizeof(pfx->s6_addr));
memcpy(pfx->s6_addr, addr, o);
if (b != 0) {
if (b != 0)
pfx->s6_addr[o] = addr->s6_addr[o] & (0xff00 >> b);
o++;
}
if (o < 16)
memset(pfx->s6_addr + o, 0, 16 - o);
}
#ifndef __HAVE_ARCH_ADDR_SET
static inline void ipv6_addr_set(struct in6_addr *addr,
__be32 w1, __be32 w2,
__be32 w3, __be32 w4)
......@@ -338,7 +334,6 @@ static inline void ipv6_addr_set(struct in6_addr *addr,
addr->s6_addr32[2] = w3;
addr->s6_addr32[3] = w4;
}
#endif
static inline int ipv6_addr_equal(const struct in6_addr *a1,
const struct in6_addr *a2)
......
......@@ -28,6 +28,7 @@ enum {
IUCV_LISTEN,
IUCV_SEVERED,
IUCV_DISCONN,
IUCV_CLOSING,
IUCV_CLOSED
};
......@@ -62,6 +63,7 @@ struct iucv_sock {
struct sock *parent;
struct iucv_path *path;
struct sk_buff_head send_skb_q;
struct sk_buff_head backlog_skb_q;
unsigned int send_tag;
};
......
......@@ -100,6 +100,8 @@ typedef enum {
SCTP_CMD_T3_RTX_TIMERS_STOP, /* Stops T3-rtx pending timers */
SCTP_CMD_FORCE_PRIM_RETRAN, /* Forces retrans. over primary path. */
SCTP_CMD_SET_SK_ERR, /* Set sk_err */
SCTP_CMD_ASSOC_CHANGE, /* generate and send assoc_change event */
SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */
SCTP_CMD_LAST
} sctp_verb_t;
......
......@@ -378,11 +378,15 @@ static inline int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int
int sctp_v6_init(void);
void sctp_v6_exit(void);
int sctp_v6_add_protocol(void);
void sctp_v6_del_protocol(void);
#else /* #ifdef defined(CONFIG_IPV6) */
static inline int sctp_v6_init(void) { return 0; }
static inline void sctp_v6_exit(void) { return; }
static inline int sctp_v6_add_protocol(void) { return 0; }
static inline void sctp_v6_del_protocol(void) { return; }
#endif /* #if defined(CONFIG_IPV6) */
......
......@@ -1857,6 +1857,7 @@ int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
struct sctp_cookie*,
gfp_t gfp);
int sctp_assoc_set_id(struct sctp_association *, gfp_t);
int sctp_cmp_addr_exact(const union sctp_addr *ss1,
const union sctp_addr *ss2);
......
......@@ -736,7 +736,8 @@ static inline __u32 tcp_current_ssthresh(const struct sock *sk)
static inline void tcp_sync_left_out(struct tcp_sock *tp)
{
BUG_ON(tp->sacked_out + tp->lost_out > tp->packets_out);
BUG_ON(tp->rx_opt.sack_ok &&
(tp->sacked_out + tp->lost_out > tp->packets_out));
tp->left_out = tp->sacked_out + tp->lost_out;
}
......
......@@ -416,25 +416,6 @@ struct xfrm_audit
u32 secid;
};
/* SAD metadata, add more later */
struct xfrm_sadinfo
{
u32 sadhcnt; /* current hash bkts */
u32 sadhmcnt; /* max allowed hash bkts */
u32 sadcnt; /* current running count */
};
struct xfrm_spdinfo
{
u32 incnt;
u32 outcnt;
u32 fwdcnt;
u32 inscnt;
u32 outscnt;
u32 fwdscnt;
u32 spdhcnt;
u32 spdhmcnt;
};
#ifdef CONFIG_AUDITSYSCALL
extern void xfrm_audit_log(uid_t auid, u32 secid, int type, int result,
struct xfrm_policy *xp, struct xfrm_state *x);
......@@ -964,11 +945,29 @@ static inline int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **s
return -ENOSYS;
}
#endif
struct xfrmk_sadinfo {
u32 sadhcnt; /* current hash bkts */
u32 sadhmcnt; /* max allowed hash bkts */
u32 sadcnt; /* current running count */
};
struct xfrmk_spdinfo {
u32 incnt;
u32 outcnt;
u32 fwdcnt;
u32 inscnt;
u32 outscnt;
u32 fwdscnt;
u32 spdhcnt;
u32 spdhmcnt;
};
extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
extern int xfrm_state_delete(struct xfrm_state *x);
extern void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
extern void xfrm_sad_getinfo(struct xfrm_sadinfo *si);
extern void xfrm_spd_getinfo(struct xfrm_spdinfo *si);
extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si);
extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si);
extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq);
extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq);
extern void xfrm_replay_notify(struct xfrm_state *x, int event);
......
......@@ -22,7 +22,7 @@
* match extremely simple token=arg style patterns. If the pattern is found,
* the location(s) of the arguments will be returned in the @args array.
*/
static int match_one(char *s, char *p, substring_t args[])
static int match_one(char *s, const char *p, substring_t args[])
{
char *meta;
int argc = 0;
......@@ -43,7 +43,7 @@ static int match_one(char *s, char *p, substring_t args[])
p = meta + 1;
if (isdigit(*p))
len = simple_strtoul(p, &p, 10);
len = simple_strtoul(p, (char **) &p, 10);
else if (*p == '%') {
if (*s++ != '%')
return 0;
......@@ -102,7 +102,7 @@ static int match_one(char *s, char *p, substring_t args[])
*/
int match_token(char *s, match_table_t table, substring_t args[])
{
struct match_token *p;
const struct match_token *p;
for (p = table; !match_one(s, p->pattern, args) ; p++)
;
......@@ -190,7 +190,7 @@ int match_hex(substring_t *s, int *result)
* &substring_t @s to the c-style string @to. Caller guarantees that @to is
* large enough to hold the characters of @s.
*/
void match_strcpy(char *to, substring_t *s)
void match_strcpy(char *to, const substring_t *s)
{
memcpy(to, s->from, s->to - s->from);
to[s->to - s->from] = '\0';
......@@ -204,7 +204,7 @@ void match_strcpy(char *to, substring_t *s)
* the &substring_t @s. The caller is responsible for freeing the returned
* string with kfree().
*/
char *match_strdup(substring_t *s)
char *match_strdup(const substring_t *s)
{
char *p = kmalloc(s->to - s->from + 1, GFP_KERNEL);
if (p)
......
......@@ -117,8 +117,7 @@ static void __exit vlan_cleanup_devices(void)
struct net_device *dev, *nxt;
rtnl_lock();
for (dev = dev_base; dev; dev = nxt) {
nxt = dev->next;
for_each_netdev_safe(dev, nxt) {
if (dev->priv_flags & IFF_802_1Q_VLAN) {
unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
VLAN_DEV_INFO(dev)->vlan_id);
......
......@@ -237,13 +237,9 @@ int vlan_proc_rem_dev(struct net_device *vlandev)
* The following few functions build the content of /proc/net/vlan/config
*/
/* starting at dev, find a VLAN device */
static struct net_device *vlan_skip(struct net_device *dev)
static inline int is_vlan_dev(struct net_device *dev)
{
while (dev && !(dev->priv_flags & IFF_802_1Q_VLAN))
dev = dev->next;
return dev;
return dev->priv_flags & IFF_802_1Q_VLAN;
}
/* start read of /proc/net/vlan/config */
......@@ -257,19 +253,35 @@ static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
if (*pos == 0)
return SEQ_START_TOKEN;
for (dev = vlan_skip(dev_base); dev && i < *pos;
dev = vlan_skip(dev->next), ++i);
for_each_netdev(dev) {
if (!is_vlan_dev(dev))
continue;
if (i++ == *pos)
return dev;
}
return (i == *pos) ? dev : NULL;
return NULL;
}
static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct net_device *dev;
++*pos;
return vlan_skip((v == SEQ_START_TOKEN)
? dev_base
: ((struct net_device *)v)->next);
dev = (struct net_device *)v;
if (v == SEQ_START_TOKEN)
dev = net_device_entry(&dev_base_head);
for_each_netdev_continue(dev) {
if (!is_vlan_dev(dev))
continue;
return dev;
}
return NULL;
}
static void vlan_seq_stop(struct seq_file *seq, void *v)
......
......@@ -475,11 +475,9 @@ void __exit br_cleanup_bridges(void)
struct net_device *dev, *nxt;
rtnl_lock();
for (dev = dev_base; dev; dev = nxt) {
nxt = dev->next;
for_each_netdev_safe(dev, nxt)
if (dev->priv_flags & IFF_EBRIDGE)
del_br(dev->priv);
}
rtnl_unlock();
}
......@@ -27,7 +27,9 @@ static int get_bridge_ifindices(int *indices, int num)
struct net_device *dev;
int i = 0;
for (dev = dev_base; dev && i < num; dev = dev->next) {
for_each_netdev(dev) {
if (i >= num)
break;
if (dev->priv_flags & IFF_EBRIDGE)
indices[i++] = dev->ifindex;
}
......
此差异已折叠。
......@@ -109,7 +109,8 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
struct net_device *dev;
int idx;
for (dev = dev_base, idx = 0; dev; dev = dev->next) {
idx = 0;
for_each_netdev(dev) {
/* not a bridge port */
if (dev->br_port == NULL || idx < cb->args[0])
goto skip;
......
......@@ -156,13 +156,13 @@ static spinlock_t net_dma_event_lock;
#endif
/*
* The @dev_base list is protected by @dev_base_lock and the rtnl
* The @dev_base_head list is protected by @dev_base_lock and the rtnl
* semaphore.
*
* Pure readers hold dev_base_lock for reading.
*
* Writers must hold the rtnl semaphore while they loop through the
* dev_base list, and hold dev_base_lock for writing when they do the
* dev_base_head list, and hold dev_base_lock for writing when they do the
* actual updates. This allows pure readers to access the list even
* while a writer is preparing to update it.
*
......@@ -174,11 +174,10 @@ static spinlock_t net_dma_event_lock;
* unregister_netdevice(), which must be called with the rtnl
* semaphore held.
*/
struct net_device *dev_base;
static struct net_device **dev_tail = &dev_base;
LIST_HEAD(dev_base_head);
DEFINE_RWLOCK(dev_base_lock);
EXPORT_SYMBOL(dev_base);
EXPORT_SYMBOL(dev_base_head);
EXPORT_SYMBOL(dev_base_lock);
#define NETDEV_HASHBITS 8
......@@ -567,26 +566,38 @@ struct net_device *dev_getbyhwaddr(unsigned short type, char *ha)
ASSERT_RTNL();
for (dev = dev_base; dev; dev = dev->next)
for_each_netdev(dev)
if (dev->type == type &&
!memcmp(dev->dev_addr, ha, dev->addr_len))
break;
return dev;
return dev;
return NULL;
}
EXPORT_SYMBOL(dev_getbyhwaddr);
struct net_device *__dev_getfirstbyhwtype(unsigned short type)
{
struct net_device *dev;
ASSERT_RTNL();
for_each_netdev(dev)
if (dev->type == type)
return dev;
return NULL;
}
EXPORT_SYMBOL(__dev_getfirstbyhwtype);
struct net_device *dev_getfirstbyhwtype(unsigned short type)
{
struct net_device *dev;
rtnl_lock();
for (dev = dev_base; dev; dev = dev->next) {
if (dev->type == type) {
dev_hold(dev);
break;
}
}
dev = __dev_getfirstbyhwtype(type);
if (dev)
dev_hold(dev);
rtnl_unlock();
return dev;
}
......@@ -606,17 +617,19 @@ EXPORT_SYMBOL(dev_getfirstbyhwtype);
struct net_device * dev_get_by_flags(unsigned short if_flags, unsigned short mask)
{
struct net_device *dev;
struct net_device *dev, *ret;
ret = NULL;
read_lock(&dev_base_lock);
for (dev = dev_base; dev != NULL; dev = dev->next) {
for_each_netdev(dev) {
if (((dev->flags ^ if_flags) & mask) == 0) {
dev_hold(dev);
ret = dev;
break;
}
}
read_unlock(&dev_base_lock);
return dev;
return ret;
}
/**
......@@ -682,7 +695,7 @@ int dev_alloc_name(struct net_device *dev, const char *name)
if (!inuse)
return -ENOMEM;
for (d = dev_base; d; d = d->next) {
for_each_netdev(d) {
if (!sscanf(d->name, name, &i))
continue;
if (i < 0 || i >= max_netdevices)
......@@ -964,7 +977,7 @@ int register_netdevice_notifier(struct notifier_block *nb)
rtnl_lock();
err = raw_notifier_chain_register(&netdev_chain, nb);
if (!err) {
for (dev = dev_base; dev; dev = dev->next) {
for_each_netdev(dev) {
nb->notifier_call(nb, NETDEV_REGISTER, dev);
if (dev->flags & IFF_UP)
......@@ -2038,7 +2051,7 @@ static int dev_ifconf(char __user *arg)
*/
total = 0;
for (dev = dev_base; dev; dev = dev->next) {
for_each_netdev(dev) {
for (i = 0; i < NPROTO; i++) {
if (gifconf_list[i]) {
int done;
......@@ -2070,26 +2083,28 @@ static int dev_ifconf(char __user *arg)
* This is invoked by the /proc filesystem handler to display a device
* in detail.
*/
static struct net_device *dev_get_idx(loff_t pos)
void *dev_seq_start(struct seq_file *seq, loff_t *pos)
{
loff_t off;
struct net_device *dev;
loff_t i;
for (i = 0, dev = dev_base; dev && i < pos; ++i, dev = dev->next);
read_lock(&dev_base_lock);
if (!*pos)
return SEQ_START_TOKEN;
return i == pos ? dev : NULL;
}
off = 1;
for_each_netdev(dev)
if (off++ == *pos)
return dev;
void *dev_seq_start(struct seq_file *seq, loff_t *pos)
{
read_lock(&dev_base_lock);
return *pos ? dev_get_idx(*pos - 1) : SEQ_START_TOKEN;
return NULL;
}
void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
++*pos;
return v == SEQ_START_TOKEN ? dev_base : ((struct net_device *)v)->next;
return v == SEQ_START_TOKEN ?
first_net_device() : next_net_device((struct net_device *)v);
}
void dev_seq_stop(struct seq_file *seq, void *v)
......@@ -3071,11 +3086,9 @@ int register_netdevice(struct net_device *dev)
set_bit(__LINK_STATE_PRESENT, &dev->state);
dev->next = NULL;
dev_init_scheduler(dev);
write_lock_bh(&dev_base_lock);
*dev_tail = dev;
dev_tail = &dev->next;
list_add_tail(&dev->dev_list, &dev_base_head);
hlist_add_head(&dev->name_hlist, head);
hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex));
dev_hold(dev);
......@@ -3349,8 +3362,6 @@ void synchronize_net(void)
void unregister_netdevice(struct net_device *dev)
{
struct net_device *d, **dp;
BUG_ON(dev_boot_phase);
ASSERT_RTNL();
......@@ -3370,19 +3381,11 @@ void unregister_netdevice(struct net_device *dev)
dev_close(dev);
/* And unlink it from device chain. */
for (dp = &dev_base; (d = *dp) != NULL; dp = &d->next) {
if (d == dev) {
write_lock_bh(&dev_base_lock);
hlist_del(&dev->name_hlist);
hlist_del(&dev->index_hlist);
if (dev_tail == &dev->next)
dev_tail = dp;
*dp = d->next;
write_unlock_bh(&dev_base_lock);
break;
}
}
BUG_ON(!d);
write_lock_bh(&dev_base_lock);
list_del(&dev->dev_list);
hlist_del(&dev->name_hlist);
hlist_del(&dev->index_hlist);
write_unlock_bh(&dev_base_lock);
dev->reg_state = NETREG_UNREGISTERING;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册