Commit 7191d7fe authored by David S. Miller's avatar David S. Miller

Merge http://linux-lksctp.bkbits.net/lksctp-2.5.work

into nuts.davemloft.net:/disk1/BK/net-2.6
parents 321fe6f8 bb3959ca
......@@ -21,10 +21,6 @@ config NETDEVICES
If unsure, say Y.
if NETDEVICES
source "drivers/net/arcnet/Kconfig"
endif
config DUMMY
tristate "Dummy net driver support"
depends on NETDEVICES
......@@ -155,6 +151,10 @@ config NET_SB1000
If you don't have this card, of course say N.
if NETDEVICES
source "drivers/net/arcnet/Kconfig"
endif
#
# Ethernet
#
......@@ -1178,6 +1178,17 @@ config IBMLANA
boards with this driver should be possible, but has not been tested
up to now due to lack of hardware.
config IBMVETH
tristate "IBM LAN Virtual Ethernet support"
depends on NETDEVICES && NET_ETHERNET && PPC_PSERIES
---help---
This driver supports virtual ethernet adapters on newer IBM iSeries
and pSeries systems.
To compile this driver as a module, choose M here and read
<file:Documentation/networking/net-modules.txt>. The module will
be called ibmveth.
config NET_PCI
bool "EISA, VLB, PCI and on board controllers"
depends on NET_ETHERNET && (ISA || EISA || PCI)
......@@ -2103,6 +2114,17 @@ config IXGB_NAPI
endmenu
source "drivers/net/tokenring/Kconfig"
source "drivers/net/wireless/Kconfig"
source "drivers/net/pcmcia/Kconfig"
source "drivers/net/wan/Kconfig"
source "drivers/atm/Kconfig"
source "drivers/s390/net/Kconfig"
config VETH
tristate "iSeries Virtual Ethernet driver support"
......@@ -2170,17 +2192,6 @@ config HIPPI
under Linux, say Y here (you must also remember to enable the driver
for your HIPPI card below). Most people will say N here.
config IBMVETH
tristate "IBM LAN Virtual Ethernet support"
depends on NETDEVICES && NET_ETHERNET && PPC_PSERIES
---help---
This driver supports virtual ethernet adapters on newer IBM iSeries
and pSeries systems.
To compile this driver as a module, choose M here and read
<file:Documentation/networking/net-modules.txt>. The module will
be called ibmveth.
config ROADRUNNER
tristate "Essential RoadRunner HIPPI PCI adapter support (EXPERIMENTAL)"
depends on HIPPI && PCI
......@@ -2438,10 +2449,6 @@ config SLIP_MODE_SLIP6
end of the link as well. It's good enough, for example, to run IP
over the async ports of a Camtec JNT Pad. If unsure, say N.
source "drivers/net/wireless/Kconfig"
source "drivers/net/tokenring/Kconfig"
config NET_FC
bool "Fibre Channel driver support"
depends on NETDEVICES && SCSI && PCI
......@@ -2501,11 +2508,3 @@ config NETCONSOLE
---help---
If you want to log kernel messages over the network, enable this.
See Documentation/networking/netconsole.txt for details.
source "drivers/net/wan/Kconfig"
source "drivers/net/pcmcia/Kconfig"
source "drivers/atm/Kconfig"
source "drivers/s390/net/Kconfig"
......@@ -119,6 +119,13 @@ extern void netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code);
extern int netlink_register_notifier(struct notifier_block *nb);
extern int netlink_unregister_notifier(struct notifier_block *nb);
/* finegrained unicast helpers: */
struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid);
struct sock *netlink_getsockbyfilp(struct file *filp);
int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long timeo);
void netlink_detachskb(struct sock *sk, struct sk_buff *skb);
int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol);
/*
* skb should fit one page. This choice is good for headerless malloc.
*
......
......@@ -47,7 +47,11 @@
#define RTM_NEWPREFIX (RTM_BASE+36)
#define RTM_GETPREFIX (RTM_BASE+38)
#define RTM_MAX (RTM_BASE+39)
#define RTM_GETMULTICAST (RTM_BASE+42)
#define RTM_GETANYCAST (RTM_BASE+46)
#define RTM_MAX (RTM_BASE+47)
/*
Generic structure for encapsulation of optional route information.
......@@ -340,7 +344,8 @@ enum
IFA_LABEL,
IFA_BROADCAST,
IFA_ANYCAST,
IFA_CACHEINFO
IFA_CACHEINFO,
IFA_MULTICAST
};
#define IFA_MAX IFA_CACHEINFO
......
......@@ -129,59 +129,6 @@ config IPV6
source "net/ipv6/Kconfig"
config DECNET
tristate "DECnet Support"
---help---
The DECnet networking protocol was used in many products made by
Digital (now Compaq). It provides reliable stream and sequenced
packet communications over which run a variety of services similar
to those which run over TCP/IP.
To find some tools to use with the kernel layer support, please
look at Patrick Caulfield's web site:
<http://linux-decnet.sourceforge.net/>.
More detailed documentation is available in
<file:Documentation/networking/decnet.txt>.
Be sure to say Y to "/proc file system support" and "Sysctl support"
below when using DECnet, since you will need sysctl support to aid
in configuration at run time.
The DECnet code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called decnet.
source "net/decnet/Kconfig"
config BRIDGE
tristate "802.1d Ethernet Bridging"
---help---
If you say Y here, then your Linux box will be able to act as an
Ethernet bridge, which means that the different Ethernet segments it
is connected to will appear as one Ethernet to the participants.
Several such bridges can work together to create even larger
networks of Ethernets using the IEEE 802.1 spanning tree algorithm.
As this is a standard, Linux bridges will cooperate properly with
other third party bridge products.
In order to use the Ethernet bridge, you'll need the bridge
configuration tools; see <file:Documentation/networking/bridge.txt>
for location. Please read the Bridge mini-HOWTO for more
information.
If you enable iptables support along with the bridge support then you
turn your bridge into a bridging IP firewall.
iptables will then see the IP packets being bridged, so you need to
take this into account when setting up your firewall rules.
Enabling arptables support when bridging will let arptables see
bridged ARP traffic in the arptables FORWARD chain.
To compile this code as a module, choose M here: the module
will be called bridge.
If unsure, say N.
menuconfig NETFILTER
bool "Network packet filtering (replaces ipchains)"
---help---
......@@ -345,9 +292,62 @@ config ATM_BR2684_IPFILTER
large number of IP-only vcc's. Do not enable this unless you are sure
you know what you are doing.
config BRIDGE
tristate "802.1d Ethernet Bridging"
---help---
If you say Y here, then your Linux box will be able to act as an
Ethernet bridge, which means that the different Ethernet segments it
is connected to will appear as one Ethernet to the participants.
Several such bridges can work together to create even larger
networks of Ethernets using the IEEE 802.1 spanning tree algorithm.
As this is a standard, Linux bridges will cooperate properly with
other third party bridge products.
In order to use the Ethernet bridge, you'll need the bridge
configuration tools; see <file:Documentation/networking/bridge.txt>
for location. Please read the Bridge mini-HOWTO for more
information.
If you enable iptables support along with the bridge support then you
turn your bridge into a bridging IP firewall.
iptables will then see the IP packets being bridged, so you need to
take this into account when setting up your firewall rules.
Enabling arptables support when bridging will let arptables see
bridged ARP traffic in the arptables FORWARD chain.
To compile this code as a module, choose M here: the module
will be called bridge.
If unsure, say N.
config VLAN_8021Q
tristate "802.1Q VLAN Support"
config DECNET
tristate "DECnet Support"
---help---
The DECnet networking protocol was used in many products made by
Digital (now Compaq). It provides reliable stream and sequenced
packet communications over which run a variety of services similar
to those which run over TCP/IP.
To find some tools to use with the kernel layer support, please
look at Patrick Caulfield's web site:
<http://linux-decnet.sourceforge.net/>.
More detailed documentation is available in
<file:Documentation/networking/decnet.txt>.
Be sure to say Y to "/proc file system support" and "Sysctl support"
below when using DECnet, since you will need sysctl support to aid
in configuration at run time.
The DECnet code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called decnet.
source "net/decnet/Kconfig"
source "net/llc/Kconfig"
config IPX
......@@ -650,14 +650,6 @@ endmenu
endmenu
source "drivers/net/Kconfig"
source "net/ax25/Kconfig"
source "net/irda/Kconfig"
source "net/bluetooth/Kconfig"
config NETPOLL
def_bool NETCONSOLE
......@@ -674,4 +666,13 @@ config NETPOLL_TRAP
config NET_POLL_CONTROLLER
def_bool NETPOLL
source "net/ax25/Kconfig"
source "net/irda/Kconfig"
source "net/bluetooth/Kconfig"
source "drivers/net/Kconfig"
endmenu
......@@ -6,9 +6,8 @@
# Joerg Reuter DL1BKE <jreuter@yaina.de>
# 19980129 Moved to net/ax25/Config.in, sourcing device drivers.
menu "Amateur Radio support"
config HAMRADIO
menuconfig HAMRADIO
depends on NET
bool "Amateur Radio support"
help
If you want to connect your Linux box to an amateur radio, answer Y
......@@ -109,5 +108,3 @@ source "drivers/net/hamradio/Kconfig"
endmenu
endmenu
......@@ -2,10 +2,8 @@
# Bluetooth subsystem configuration
#
menu "Bluetooth support"
menuconfig BT
depends on NET
config BT
tristate "Bluetooth subsystem support"
help
Bluetooth is low-cost, low-power, short-range wireless technology.
......@@ -62,5 +60,3 @@ source "net/bluetooth/cmtp/Kconfig"
source "drivers/bluetooth/Kconfig"
endmenu
......@@ -32,7 +32,7 @@ static int br_dev_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if (copy_from_user(args, data, 4*sizeof(unsigned long)))
return -EFAULT;
return br_ioctl(dev->priv, args[0], args[1], args[2], args[3]);
return br_ioctl_device(dev->priv, args[0], args[1], args[2], args[3]);
}
static struct net_device_stats *br_dev_get_stats(struct net_device *dev)
......
......@@ -24,6 +24,9 @@
#include <asm/uaccess.h>
#include "br_private.h"
/* Limited to 256 ports because of STP protocol pdu */
#define BR_MAX_PORTS 256
static int br_initial_port_cost(struct net_device *dev)
{
if (!strncmp(dev->name, "lec", 3))
......@@ -126,34 +129,46 @@ static struct net_bridge *new_nb(const char *name)
return br;
}
static int free_port(struct net_bridge *br)
{
int index;
struct net_bridge_port *p;
long inuse[BR_MAX_PORTS/(sizeof(long)*8)];
/* find free port number */
memset(inuse, 0, sizeof(inuse));
list_for_each_entry(p, &br->port_list, list) {
set_bit(p->port_no, inuse);
}
index = find_first_zero_bit(inuse, BR_MAX_PORTS);
if (index >= BR_MAX_PORTS)
return -EXFULL;
return index;
}
/* called under bridge lock */
static struct net_bridge_port *new_nbp(struct net_bridge *br, struct net_device *dev)
{
int i;
int index;
struct net_bridge_port *p;
index = free_port(br);
if (index < 0)
return ERR_PTR(index);
p = kmalloc(sizeof(*p), GFP_ATOMIC);
if (p == NULL)
return p;
return ERR_PTR(-ENOMEM);
memset(p, 0, sizeof(*p));
p->br = br;
p->dev = dev;
p->path_cost = br_initial_port_cost(dev);
p->priority = 0x80;
for (i=1;i<255;i++)
if (br_get_port(br, i) == NULL)
break;
if (i == 255) {
kfree(p);
return NULL;
}
dev->br_port = p;
p->port_no = i;
p->port_no = index;
br_init_port(p);
p->state = BR_STATE_DISABLED;
......@@ -218,10 +233,10 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
return -ELOOP;
dev_hold(dev);
if ((p = new_nbp(br, dev)) == NULL) {
spin_unlock_bh(&br->lock);
p = new_nbp(br, dev);
if (IS_ERR(p)) {
dev_put(dev);
return -EXFULL;
return PTR_ERR(p);
}
dev_set_promiscuity(dev, 1);
......@@ -262,13 +277,14 @@ int br_get_bridge_ifindices(int *indices, int num)
return i;
}
void br_get_port_ifindices(struct net_bridge *br, int *ifindices)
void br_get_port_ifindices(struct net_bridge *br, int *ifindices, int num)
{
struct net_bridge_port *p;
rcu_read_lock();
list_for_each_entry_rcu(p, &br->port_list, list) {
ifindices[p->port_no] = p->dev->ifindex;
if (p->port_no < num)
ifindices[p->port_no] = p->dev->ifindex;
}
rcu_read_unlock();
}
......
......@@ -38,11 +38,8 @@ static unsigned long timer_residue(const struct timer_list *timer)
? (timer->expires - jiffies) : 0);
}
static int br_ioctl_device(struct net_bridge *br,
unsigned int cmd,
unsigned long arg0,
unsigned long arg1,
unsigned long arg2)
int br_ioctl_device(struct net_bridge *br, unsigned int cmd,
unsigned long arg0, unsigned long arg1, unsigned long arg2)
{
if (br == NULL)
return -EINVAL;
......@@ -55,6 +52,9 @@ static int br_ioctl_device(struct net_bridge *br,
struct net_device *dev;
int ret;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
dev = dev_get_by_index(arg0);
if (dev == NULL)
return -EINVAL;
......@@ -104,23 +104,27 @@ static int br_ioctl_device(struct net_bridge *br,
case BRCTL_GET_PORT_LIST:
{
int *indices;
int num = arg1 ? arg1 : 256; /* compatiablity */
int ret = 0;
int *indices;
indices = kmalloc(256*sizeof(int), GFP_KERNEL);
indices = kmalloc(num*sizeof(int), GFP_KERNEL);
if (indices == NULL)
return -ENOMEM;
memset(indices, 0, 256*sizeof(int));
memset(indices, 0, num*sizeof(int));
br_get_port_ifindices(br, indices);
if (copy_to_user((void *)arg0, indices, 256*sizeof(int)))
br_get_port_ifindices(br, indices, num);
if (copy_to_user((void *)arg0, indices, num*sizeof(int)))
ret = -EFAULT;
kfree(indices);
return ret;
}
case BRCTL_SET_BRIDGE_FORWARD_DELAY:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
spin_lock_bh(&br->lock);
br->bridge_forward_delay = user_to_ticks(arg0);
if (br_is_root_bridge(br))
......@@ -129,6 +133,9 @@ static int br_ioctl_device(struct net_bridge *br,
return 0;
case BRCTL_SET_BRIDGE_HELLO_TIME:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
spin_lock_bh(&br->lock);
br->bridge_hello_time = user_to_ticks(arg0);
if (br_is_root_bridge(br))
......@@ -137,6 +144,9 @@ static int br_ioctl_device(struct net_bridge *br,
return 0;
case BRCTL_SET_BRIDGE_MAX_AGE:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
spin_lock_bh(&br->lock);
br->bridge_max_age = user_to_ticks(arg0);
if (br_is_root_bridge(br))
......@@ -145,10 +155,10 @@ static int br_ioctl_device(struct net_bridge *br,
return 0;
case BRCTL_SET_AGEING_TIME:
br->ageing_time = user_to_ticks(arg0);
return 0;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
case BRCTL_SET_GC_INTERVAL: /* no longer used */
br->ageing_time = user_to_ticks(arg0);
return 0;
case BRCTL_GET_PORT_INFO:
......@@ -185,10 +195,16 @@ static int br_ioctl_device(struct net_bridge *br,
}
case BRCTL_SET_BRIDGE_STP_STATE:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
br->stp_enabled = arg0?1:0;
return 0;
case BRCTL_SET_BRIDGE_PRIORITY:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
spin_lock_bh(&br->lock);
br_stp_set_bridge_priority(br, arg0);
spin_unlock_bh(&br->lock);
......@@ -199,6 +215,9 @@ static int br_ioctl_device(struct net_bridge *br,
struct net_bridge_port *p;
int ret = 0;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
spin_lock_bh(&br->lock);
if ((p = br_get_port(br, arg0)) == NULL)
ret = -EINVAL;
......@@ -213,6 +232,9 @@ static int br_ioctl_device(struct net_bridge *br,
struct net_bridge_port *p;
int ret = 0;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
spin_lock_bh(&br->lock);
if ((p = br_get_port(br, arg0)) == NULL)
ret = -EINVAL;
......@@ -243,9 +265,6 @@ static int br_ioctl_deviceless(unsigned int cmd,
int *indices;
int ret = 0;
if (arg1 > 64)
arg1 = 64;
indices = kmalloc(arg1*sizeof(int), GFP_KERNEL);
if (indices == NULL)
return -ENOMEM;
......@@ -265,6 +284,9 @@ static int br_ioctl_deviceless(unsigned int cmd,
{
char buf[IFNAMSIZ];
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (copy_from_user(buf, (void *)arg0, IFNAMSIZ))
return -EFAULT;
......@@ -285,25 +307,8 @@ int br_ioctl_deviceless_stub(unsigned long arg)
{
unsigned long i[3];
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (copy_from_user(i, (void *)arg, 3*sizeof(unsigned long)))
return -EFAULT;
return br_ioctl_deviceless(i[0], i[1], i[2]);
}
int br_ioctl(struct net_bridge *br, unsigned int cmd, unsigned long arg0, unsigned long arg1, unsigned long arg2)
{
int err;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
err = br_ioctl_deviceless(cmd, arg0, arg1);
if (err == -EOPNOTSUPP)
err = br_ioctl_device(br, cmd, arg0, arg1, arg2);
return err;
}
......@@ -57,7 +57,8 @@ struct net_bridge_port
struct net_bridge *br;
struct net_device *dev;
struct list_head list;
int port_no;
__u8 port_no;
__u8 priority;
/* STP */
port_id port_id;
......@@ -69,7 +70,6 @@ struct net_bridge_port
port_id designated_port;
unsigned topology_change_ack:1;
unsigned config_pending:1;
int priority;
struct timer_list forward_delay_timer;
struct timer_list hold_timer;
......@@ -167,18 +167,18 @@ extern int br_del_if(struct net_bridge *br,
extern int br_get_bridge_ifindices(int *indices,
int num);
extern void br_get_port_ifindices(struct net_bridge *br,
int *ifindices);
int *ifindices, int num);
/* br_input.c */
extern int br_handle_frame_finish(struct sk_buff *skb);
extern int br_handle_frame(struct sk_buff *skb);
/* br_ioctl.c */
extern int br_ioctl(struct net_bridge *br,
unsigned int cmd,
unsigned long arg0,
unsigned long arg1,
unsigned long arg2);
extern int br_ioctl_device(struct net_bridge *br,
unsigned int cmd,
unsigned long arg0,
unsigned long arg1,
unsigned long arg2);
extern int br_ioctl_deviceless_stub(unsigned long arg);
/* br_netfilter.c */
......
......@@ -2223,7 +2223,9 @@ static int igmp_mc_seq_show(struct seq_file *seq, void *v)
struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
char *querier;
#ifdef CONFIG_IP_MULTICAST
querier = IGMP_V1_SEEN(state->in_dev) ? "V1" : "V2";
querier = IGMP_V1_SEEN(state->in_dev) ? "V1" :
IGMP_V2_SEEN(state->in_dev) ? "V2" :
"V3";
#else
querier = "NONE";
#endif
......@@ -2236,7 +2238,9 @@ static int igmp_mc_seq_show(struct seq_file *seq, void *v)
seq_printf(seq,
"\t\t\t\t%08lX %5d %d:%08lX\t\t%d\n",
im->multiaddr, im->users,
im->tm_running, jiffies_to_clock_t(im->timer.expires-jiffies), im->reporter);
im->tm_running, im->tm_running ?
jiffies_to_clock_t(im->timer.expires-jiffies) : 0,
im->reporter);
}
return 0;
}
......
......@@ -2553,7 +2553,89 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
return -1;
}
static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
u32 pid, u32 seq, int event)
{
struct ifaddrmsg *ifm;
struct nlmsghdr *nlh;
struct ifa_cacheinfo ci;
unsigned char *b = skb->tail;
nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
ifm = NLMSG_DATA(nlh);
ifm->ifa_family = AF_INET6;
ifm->ifa_prefixlen = 128;
ifm->ifa_flags = IFA_F_PERMANENT;
ifm->ifa_scope = RT_SCOPE_UNIVERSE;
if (ipv6_addr_scope(&ifmca->mca_addr)&IFA_SITE)
ifm->ifa_scope = RT_SCOPE_SITE;
ifm->ifa_index = ifmca->idev->dev->ifindex;
RTA_PUT(skb, IFA_MULTICAST, 16, &ifmca->mca_addr);
ci.cstamp = (__u32)(TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) / HZ
* 100 + TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) % HZ
* 100 / HZ);
ci.tstamp = (__u32)(TIME_DELTA(ifmca->mca_tstamp, INITIAL_JIFFIES) / HZ
* 100 + TIME_DELTA(ifmca->mca_tstamp, INITIAL_JIFFIES) % HZ
* 100 / HZ);
ci.ifa_prefered = INFINITY_LIFE_TIME;
ci.ifa_valid = INFINITY_LIFE_TIME;
RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci);
nlh->nlmsg_len = skb->tail - b;
return skb->len;
nlmsg_failure:
rtattr_failure:
skb_trim(skb, b - skb->data);
return -1;
}
static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
u32 pid, u32 seq, int event)
{
struct ifaddrmsg *ifm;
struct nlmsghdr *nlh;
struct ifa_cacheinfo ci;
unsigned char *b = skb->tail;
nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
ifm = NLMSG_DATA(nlh);
ifm->ifa_family = AF_INET6;
ifm->ifa_prefixlen = 128;
ifm->ifa_flags = IFA_F_PERMANENT;
ifm->ifa_scope = RT_SCOPE_UNIVERSE;
if (ipv6_addr_scope(&ifaca->aca_addr)&IFA_SITE)
ifm->ifa_scope = RT_SCOPE_SITE;
ifm->ifa_index = ifaca->aca_idev->dev->ifindex;
RTA_PUT(skb, IFA_ANYCAST, 16, &ifaca->aca_addr);
ci.cstamp = (__u32)(TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) / HZ
* 100 + TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) % HZ
* 100 / HZ);
ci.tstamp = (__u32)(TIME_DELTA(ifaca->aca_tstamp, INITIAL_JIFFIES) / HZ
* 100 + TIME_DELTA(ifaca->aca_tstamp, INITIAL_JIFFIES) % HZ
* 100 / HZ);
ci.ifa_prefered = INFINITY_LIFE_TIME;
ci.ifa_valid = INFINITY_LIFE_TIME;
RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci);
nlh->nlmsg_len = skb->tail - b;
return skb->len;
nlmsg_failure:
rtattr_failure:
skb_trim(skb, b - skb->data);
return -1;
}
enum addr_type_t
{
UNICAST_ADDR,
MULTICAST_ADDR,
ANYCAST_ADDR,
};
static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
enum addr_type_t type)
{
int idx, ip_idx;
int s_idx, s_ip_idx;
......@@ -2561,7 +2643,9 @@ static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
struct net_device *dev;
struct inet6_dev *idev = NULL;
struct inet6_ifaddr *ifa;
struct ifmcaddr6 *ifmca;
struct ifacaddr6 *ifaca;
s_idx = cb->args[0];
s_ip_idx = ip_idx = cb->args[1];
read_lock(&dev_base_lock);
......@@ -2575,28 +2659,58 @@ static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
if ((idev = in6_dev_get(dev)) == NULL)
continue;
read_lock_bh(&idev->lock);
/* unicast address */
for (ifa = idev->addr_list; ifa;
ifa = ifa->if_next, ip_idx++) {
if (ip_idx < s_ip_idx)
continue;
if ((err = inet6_fill_ifaddr(skb, ifa,
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
goto done;
}
/* temp addr */
switch (type) {
case UNICAST_ADDR:
/* unicast address */
for (ifa = idev->addr_list; ifa;
ifa = ifa->if_next, ip_idx++) {
if (ip_idx < s_ip_idx)
continue;
if ((err = inet6_fill_ifaddr(skb, ifa,
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
goto done;
}
/* temp addr */
#ifdef CONFIG_IPV6_PRIVACY
for (ifa = idev->tempaddr_list; ifa;
ifa = ifa->tmp_next, ip_idx++) {
if (ip_idx < s_ip_idx)
continue;
if ((err = inet6_fill_ifaddr(skb, ifa,
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
goto done;
}
for (ifa = idev->tempaddr_list; ifa;
ifa = ifa->tmp_next, ip_idx++) {
if (ip_idx < s_ip_idx)
continue;
if ((err = inet6_fill_ifaddr(skb, ifa,
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
goto done;
}
#endif
break;
case MULTICAST_ADDR:
/* multicast address */
for (ifmca = idev->mc_list; ifmca;
ifmca = ifmca->next, ip_idx++) {
if (ip_idx < s_ip_idx)
continue;
if ((err = inet6_fill_ifmcaddr(skb, ifmca,
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, RTM_GETMULTICAST)) <= 0)
goto done;
}
break;
case ANYCAST_ADDR:
/* anycast address */
for (ifaca = idev->ac_list; ifaca;
ifaca = ifaca->aca_next, ip_idx++) {
if (ip_idx < s_ip_idx)
continue;
if ((err = inet6_fill_ifacaddr(skb, ifaca,
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, RTM_GETANYCAST)) <= 0)
goto done;
}
break;
default:
break;
}
read_unlock_bh(&idev->lock);
in6_dev_put(idev);
}
......@@ -2611,6 +2725,25 @@ static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
{
enum addr_type_t type = UNICAST_ADDR;
return inet6_dump_addr(skb, cb, type);
}
static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
{
enum addr_type_t type = MULTICAST_ADDR;
return inet6_dump_addr(skb, cb, type);
}
static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
{
enum addr_type_t type = ANYCAST_ADDR;
return inet6_dump_addr(skb, cb, type);
}
static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
{
struct sk_buff *skb;
......@@ -2835,6 +2968,8 @@ static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
[RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, },
[RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, },
[RTM_GETADDR - RTM_BASE] = { .dumpit = inet6_dump_ifaddr, },
[RTM_GETMULTICAST - RTM_BASE] = { .dumpit = inet6_dump_ifmcaddr, },
[RTM_GETANYCAST - RTM_BASE] = { .dumpit = inet6_dump_ifacaddr, },
[RTM_NEWROUTE - RTM_BASE] = { .doit = inet6_rtm_newroute, },
[RTM_DELROUTE - RTM_BASE] = { .doit = inet6_rtm_delroute, },
[RTM_GETROUTE - RTM_BASE] = { .doit = inet6_rtm_getroute,
......
......@@ -1317,6 +1317,7 @@ static void mld_sendpack(struct sk_buff *skb)
struct inet6_dev *idev = in6_dev_get(skb->dev);
int err;
IP6_INC_STATS(Ip6OutRequests);
payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h -
sizeof(struct ipv6hdr);
mldlen = skb->tail - skb->h.raw;
......@@ -1326,8 +1327,12 @@ static void mld_sendpack(struct sk_buff *skb)
IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0));
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
dev_queue_xmit);
if (!err)
if (!err) {
ICMP6_INC_STATS(idev,Icmp6OutMsgs);
IP6_INC_STATS(Ip6OutMcastPkts);
} else
IP6_INC_STATS(Ip6OutDiscards);
if (likely(idev != NULL))
in6_dev_put(idev);
}
......@@ -1608,6 +1613,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
IPV6_TLV_ROUTERALERT, 2, 0, 0,
IPV6_TLV_PADN, 0 };
IP6_INC_STATS(Ip6OutRequests);
snd_addr = addr;
if (type == ICMPV6_MGM_REDUCTION) {
snd_addr = &all_routers;
......@@ -1620,8 +1626,10 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err);
if (skb == NULL)
if (skb == NULL) {
IP6_INC_STATS(Ip6OutDiscards);
return;
}
skb_reserve(skb, LL_RESERVED_SPACE(dev));
if (dev->hard_header) {
......@@ -1664,13 +1672,16 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
else
ICMP6_INC_STATS(idev, Icmp6OutGroupMembResponses);
ICMP6_INC_STATS(idev, Icmp6OutMsgs);
}
IP6_INC_STATS(Ip6OutMcastPkts);
} else
IP6_INC_STATS(Ip6OutDiscards);
if (likely(idev != NULL))
in6_dev_put(idev);
return;
out:
IP6_INC_STATS(Ip6OutDiscards);
kfree_skb(skb);
}
......
......@@ -2,11 +2,9 @@
# IrDA protocol configuration
#
menu "IrDA (infrared) support"
menuconfig IRDA
depends on NET
config IRDA
tristate "IrDA subsystem support"
tristate "IrDA (infrared) subsystem support"
---help---
Say Y here if you want to build support for the IrDA (TM) protocols.
The Infrared Data Associations (tm) specifies standards for wireless
......@@ -95,5 +93,3 @@ config IRDA_DEBUG
source "drivers/net/irda/Kconfig"
endmenu
......@@ -2636,7 +2636,7 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
addr->sadb_address_len =
(sizeof(struct sadb_address)+sockaddr_size)/
sizeof(uint64_t);
addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
addr->sadb_address_proto = 0;
addr->sadb_address_reserved = 0;
if (x->props.family == AF_INET) {
......
......@@ -415,38 +415,65 @@ static void netlink_overrun(struct sock *sk)
}
}
int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock)
struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid)
{
struct sock *sk;
struct netlink_opt *nlk;
int len = skb->len;
int protocol = ssk->sk_protocol;
long timeo;
DECLARE_WAITQUEUE(wait, current);
timeo = sock_sndtimeo(ssk, nonblock);
struct sock *sock;
struct netlink_opt *nlk;
retry:
sk = netlink_lookup(protocol, pid);
if (sk == NULL)
goto no_dst;
nlk = nlk_sk(sk);
sock = netlink_lookup(protocol, pid);
if (!sock)
return ERR_PTR(-ECONNREFUSED);
/* Don't bother queuing skb if kernel socket has no input function */
if (nlk->pid == 0 && !nlk->data_ready)
goto no_dst;
nlk = nlk_sk(sock);
if (nlk->pid == 0 && !nlk->data_ready) {
sock_put(sock);
return ERR_PTR(-ECONNREFUSED);
}
return sock;
}
struct sock *netlink_getsockbyfilp(struct file *filp)
{
struct inode *inode = filp->f_dentry->d_inode;
struct socket *socket;
struct sock *sock;
if (!inode->i_sock || !(socket = SOCKET_I(inode)))
return ERR_PTR(-ENOTSOCK);
sock = socket->sk;
if (sock->sk_family != AF_NETLINK)
return ERR_PTR(-EINVAL);
sock_hold(sock);
return sock;
}
/*
* Attach a skb to a netlink socket.
* The caller must hold a reference to the destination socket. On error, the
* reference is dropped. The skb is not send to the destination, just all
* all error checks are performed and memory in the queue is reserved.
* Return values:
* < 0: error. skb freed, reference to sock dropped.
* 0: continue
* 1: repeat lookup - reference dropped while waiting for socket memory.
*/
int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long timeo)
{
struct netlink_opt *nlk;
nlk = nlk_sk(sk);
#ifdef NL_EMULATE_DEV
if (nlk->handler) {
skb_orphan(skb);
len = nlk->handler(protocol, skb);
sock_put(sk);
return len;
}
if (nlk->handler)
return 0;
#endif
if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
test_bit(0, &nlk->state)) {
DECLARE_WAITQUEUE(wait, current);
if (!timeo) {
if (!nlk->pid)
netlink_overrun(sk);
......@@ -471,19 +498,60 @@ int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock
kfree_skb(skb);
return sock_intr_errno(timeo);
}
goto retry;
return 1;
}
skb_orphan(skb);
skb_set_owner_r(skb, sk);
return 0;
}
int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol)
{
struct netlink_opt *nlk;
int len = skb->len;
nlk = nlk_sk(sk);
#ifdef NL_EMULATE_DEV
if (nlk->handler) {
skb_orphan(skb);
len = nlk->handler(protocol, skb);
sock_put(sk);
return len;
}
#endif
skb_queue_tail(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk, len);
sock_put(sk);
return len;
}
no_dst:
void netlink_detachskb(struct sock *sk, struct sk_buff *skb)
{
kfree_skb(skb);
return -ECONNREFUSED;
sock_put(sk);
}
int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock)
{
struct sock *sk;
int err;
long timeo;
timeo = sock_sndtimeo(ssk, nonblock);
retry:
sk = netlink_getsockbypid(ssk, pid);
if (IS_ERR(sk)) {
kfree_skb(skb);
return PTR_ERR(skb);
}
err = netlink_attachskb(sk, skb, nonblock, timeo);
if (err == 1)
goto retry;
if (err)
return err;
return netlink_sendskb(sk, skb, ssk->sk_protocol);
}
static __inline__ int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment