Skip to content

Commit

Permalink
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Browse files Browse the repository at this point in the history
  • Loading branch information
Linus Torvalds committed Nov 10, 2005
2 parents b8cbfa6 + f3b84ec commit 985834a
Show file tree
Hide file tree
Showing 24 changed files with 240 additions and 149 deletions.
56 changes: 56 additions & 0 deletions Documentation/networking/dccp.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
DCCP protocol
============

Last updated: 10 November 2005

Contents
========

- Introduction
- Missing features
- Socket options
- Notes

Introduction
============

Datagram Congestion Control Protocol (DCCP) is an unreliable, connection
based protocol designed to solve issues present in UDP and TCP particularly
for real time and multimedia traffic.

It has a base protocol and pluggable congestion control IDs (CCIDs).

It is at draft RFC status and the homepage for DCCP as a protocol is at:
http://www.icir.org/kohler/dcp/

Missing features
================

The DCCP implementation does not currently have all the features that are in
the draft RFC.

In particular the following are missing:
- CCID2 support
- feature negotiation

When testing against other implementations it appears that elapsed time
options are not coded compliant to the specification.

Socket options
==============

DCCP_SOCKOPT_PACKET_SIZE is used for CCID3 to set default packet size for
calculations.

DCCP_SOCKOPT_SERVICE sets the service. This is compulsory as per the
specification. If you don't set it you will get EPROTO.

Notes
=====

SELinux does not yet have support for DCCP. You will need to turn it off or
else you will get EACCES.

DCCP does not travel through NAT successfully at present. This is because
the checksum covers the psuedo-header as per TCP and UDP. It should be
relatively trivial to add Linux NAT support for DCCP.
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ DCCP PROTOCOL
P: Arnaldo Carvalho de Melo
M: acme@mandriva.com
L: dccp@vger.kernel.org
W: http://www.wlug.org.nz/DCCP
W: http://linux-net.osdl.org/index.php/DCCP
S: Maintained

DECnet NETWORK LAYER
Expand Down
4 changes: 2 additions & 2 deletions drivers/atm/horizon.c
Original file line number Diff line number Diff line change
Expand Up @@ -1511,8 +1511,8 @@ static inline short setup_idle_tx_channel (hrz_dev * dev, hrz_vcc * vcc) {
// a.k.a. prepare the channel and remember that we have done so.

tx_ch_desc * tx_desc = &memmap->tx_descs[tx_channel];
u16 rd_ptr;
u16 wr_ptr;
u32 rd_ptr;
u32 wr_ptr;
u16 channel = vcc->channel;

unsigned long flags;
Expand Down
16 changes: 5 additions & 11 deletions drivers/net/bnx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -2707,7 +2707,7 @@ bnx2_init_nvram(struct bnx2 *bp)

if (j == entry_count) {
bp->flash_info = NULL;
printk(KERN_ALERT "Unknown flash/EEPROM type.\n");
printk(KERN_ALERT PFX "Unknown flash/EEPROM type.\n");
rc = -ENODEV;
}

Expand Down Expand Up @@ -3903,6 +3903,8 @@ bnx2_test_loopback(struct bnx2 *bp)

pkt_size = 1514;
skb = dev_alloc_skb(pkt_size);
if (!skb)
return -ENOMEM;
packet = skb_put(skb, pkt_size);
memcpy(packet, bp->mac_addr, 6);
memset(packet + 6, 0x0, 8);
Expand Down Expand Up @@ -4798,11 +4800,7 @@ bnx2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
struct bnx2 *bp = dev->priv;
int rc;

if (eeprom->offset > bp->flash_info->total_size)
return -EINVAL;

if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size)
eeprom->len = bp->flash_info->total_size - eeprom->offset;
/* parameters already validated in ethtool_get_eeprom */

rc = bnx2_nvram_read(bp, eeprom->offset, eebuf, eeprom->len);

Expand All @@ -4816,11 +4814,7 @@ bnx2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
struct bnx2 *bp = dev->priv;
int rc;

if (eeprom->offset > bp->flash_info->total_size)
return -EINVAL;

if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size)
eeprom->len = bp->flash_info->total_size - eeprom->offset;
/* parameters already validated in ethtool_set_eeprom */

rc = bnx2_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);

Expand Down
4 changes: 3 additions & 1 deletion include/linux/if_ether.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#ifndef _LINUX_IF_ETHER_H
#define _LINUX_IF_ETHER_H

#include <linux/types.h>

/*
* IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
* and FCS/CRC (frame check sequence).
Expand Down Expand Up @@ -100,7 +102,7 @@
struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
unsigned short h_proto; /* packet type ID field */
__be16 h_proto; /* packet type ID field */
} __attribute__((packed));

#ifdef __KERNEL__
Expand Down
7 changes: 7 additions & 0 deletions include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,13 @@ extern int netdev_max_backlog;
extern int weight_p;
extern int netdev_set_master(struct net_device *dev, struct net_device *master);
extern int skb_checksum_help(struct sk_buff *skb, int inward);
#ifdef CONFIG_BUG
extern void netdev_rx_csum_fault(struct net_device *dev);
#else
static inline void netdev_rx_csum_fault(struct net_device *dev)
{
}
#endif
/* rx skb timestamps */
extern void net_enable_timestamp(void);
extern void net_disable_timestamp(void);
Expand Down
27 changes: 25 additions & 2 deletions include/linux/skbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -1236,8 +1236,7 @@ extern unsigned int datagram_poll(struct file *file, struct socket *sock,
extern int skb_copy_datagram_iovec(const struct sk_buff *from,
int offset, struct iovec *to,
int size);
extern int skb_copy_and_csum_datagram_iovec(const
struct sk_buff *skb,
extern int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
int hlen,
struct iovec *iov);
extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb);
Expand Down Expand Up @@ -1305,6 +1304,30 @@ static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *

extern void __net_timestamp(struct sk_buff *skb);

extern unsigned int __skb_checksum_complete(struct sk_buff *skb);

/**
* skb_checksum_complete - Calculate checksum of an entire packet
* @skb: packet to process
*
* This function calculates the checksum over the entire packet plus
* the value of skb->csum. The latter can be used to supply the
* checksum of a pseudo header as used by TCP/UDP. It returns the
* checksum.
*
* For protocols that contain complete checksums such as ICMP/TCP/UDP,
* this function can be used to verify that checksum on received
* packets. In that case the function should return zero if the
* checksum is correct. In particular, this function will return zero
* if skb->ip_summed is CHECKSUM_UNNECESSARY which indicates that the
* hardware has already verified the correctness of the checksum.
*/
static inline unsigned int skb_checksum_complete(struct sk_buff *skb)
{
return skb->ip_summed != CHECKSUM_UNNECESSARY &&
__skb_checksum_complete(skb);
}

#ifdef CONFIG_NETFILTER
static inline void nf_conntrack_put(struct nf_conntrack *nfct)
{
Expand Down
3 changes: 2 additions & 1 deletion include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/slab.h>
#include <linux/cache.h>
#include <linux/percpu.h>
#include <linux/skbuff.h>

#include <net/inet_connection_sock.h>
#include <net/inet_timewait_sock.h>
Expand Down Expand Up @@ -852,7 +853,7 @@ static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len,

static __inline__ int __tcp_checksum_complete(struct sk_buff *skb)
{
return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
return __skb_checksum_complete(skb);
}

static __inline__ int tcp_checksum_complete(struct sk_buff *skb)
Expand Down
21 changes: 18 additions & 3 deletions net/core/datagram.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,20 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
return -EFAULT;
}

unsigned int __skb_checksum_complete(struct sk_buff *skb)
{
unsigned int sum;

sum = (u16)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
if (likely(!sum)) {
if (unlikely(skb->ip_summed == CHECKSUM_HW))
netdev_rx_csum_fault(skb->dev);
skb->ip_summed = CHECKSUM_UNNECESSARY;
}
return sum;
}
EXPORT_SYMBOL(__skb_checksum_complete);

/**
* skb_copy_and_csum_datagram_iovec - Copy and checkum skb to user iovec.
* @skb: skbuff
Expand All @@ -363,7 +377,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
* -EFAULT - fault during copy. Beware, in this case iovec
* can be modified!
*/
int skb_copy_and_csum_datagram_iovec(const struct sk_buff *skb,
int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
int hlen, struct iovec *iov)
{
unsigned int csum;
Expand All @@ -376,8 +390,7 @@ int skb_copy_and_csum_datagram_iovec(const struct sk_buff *skb,
iov++;

if (iov->iov_len < chunk) {
if ((unsigned short)csum_fold(skb_checksum(skb, 0, chunk + hlen,
skb->csum)))
if (__skb_checksum_complete(skb))
goto csum_error;
if (skb_copy_datagram_iovec(skb, hlen, iov, chunk))
goto fault;
Expand All @@ -388,6 +401,8 @@ int skb_copy_and_csum_datagram_iovec(const struct sk_buff *skb,
goto fault;
if ((unsigned short)csum_fold(csum))
goto csum_error;
if (unlikely(skb->ip_summed == CHECKSUM_HW))
netdev_rx_csum_fault(skb->dev);
iov->iov_len -= chunk;
iov->iov_base += chunk;
}
Expand Down
12 changes: 12 additions & 0 deletions net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,18 @@ int skb_checksum_help(struct sk_buff *skb, int inward)
return ret;
}

/* Take action when hardware reception checksum errors are detected. */
#ifdef CONFIG_BUG
void netdev_rx_csum_fault(struct net_device *dev)
{
if (net_ratelimit()) {
printk(KERN_ERR "%s: hw csum failure.\n", dev->name);
dump_stack();
}
}
EXPORT_SYMBOL(netdev_rx_csum_fault);
#endif

#ifdef CONFIG_HIGHMEM
/* Actually, we should eliminate this check as soon as we know, that:
* 1. IOMMU is present and allows to map all the memory.
Expand Down
18 changes: 11 additions & 7 deletions net/core/netpoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,20 @@ void netpoll_queue(struct sk_buff *skb)
static int checksum_udp(struct sk_buff *skb, struct udphdr *uh,
unsigned short ulen, u32 saddr, u32 daddr)
{
if (uh->check == 0)
unsigned int psum;

if (uh->check == 0 || skb->ip_summed == CHECKSUM_UNNECESSARY)
return 0;

if (skb->ip_summed == CHECKSUM_HW)
return csum_tcpudp_magic(
saddr, daddr, ulen, IPPROTO_UDP, skb->csum);
psum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);

if (skb->ip_summed == CHECKSUM_HW &&
!(u16)csum_fold(csum_add(psum, skb->csum)))
return 0;

skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
skb->csum = psum;

return csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
return __skb_checksum_complete(skb);
}

/*
Expand Down Expand Up @@ -489,7 +493,7 @@ int __netpoll_rx(struct sk_buff *skb)

if (ulen != len)
goto out;
if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr) < 0)
if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr))
goto out;
if (np->local_ip && np->local_ip != ntohl(iph->daddr))
goto out;
Expand Down
6 changes: 3 additions & 3 deletions net/ipv4/icmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -934,11 +934,11 @@ int icmp_rcv(struct sk_buff *skb)
case CHECKSUM_HW:
if (!(u16)csum_fold(skb->csum))
break;
LIMIT_NETDEBUG(KERN_DEBUG "icmp v4 hw csum failure\n");
/* fall through */
case CHECKSUM_NONE:
if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0)))
skb->csum = 0;
if (__skb_checksum_complete(skb))
goto error;
default:;
}

if (!pskb_pull(skb, sizeof(struct icmphdr)))
Expand Down
19 changes: 14 additions & 5 deletions net/ipv4/igmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -872,11 +872,18 @@ int igmp_rcv(struct sk_buff *skb)
return 0;
}

if (!pskb_may_pull(skb, sizeof(struct igmphdr)) ||
(u16)csum_fold(skb_checksum(skb, 0, len, 0))) {
in_dev_put(in_dev);
kfree_skb(skb);
return 0;
if (!pskb_may_pull(skb, sizeof(struct igmphdr)))
goto drop;

switch (skb->ip_summed) {
case CHECKSUM_HW:
if (!(u16)csum_fold(skb->csum))
break;
/* fall through */
case CHECKSUM_NONE:
skb->csum = 0;
if (__skb_checksum_complete(skb))
goto drop;
}

ih = skb->h.igmph;
Expand Down Expand Up @@ -906,6 +913,8 @@ int igmp_rcv(struct sk_buff *skb)
default:
NETDEBUG(KERN_DEBUG "New IGMP type=%d, why we do not know about it?\n", ih->type);
}

drop:
in_dev_put(in_dev);
kfree_skb(skb);
return 0;
Expand Down
15 changes: 8 additions & 7 deletions net/ipv4/ip_gre.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,15 +577,16 @@ static int ipgre_rcv(struct sk_buff *skb)
goto drop_nolock;

if (flags&GRE_CSUM) {
if (skb->ip_summed == CHECKSUM_HW) {
switch (skb->ip_summed) {
case CHECKSUM_HW:
csum = (u16)csum_fold(skb->csum);
if (csum)
skb->ip_summed = CHECKSUM_NONE;
}
if (skb->ip_summed == CHECKSUM_NONE) {
skb->csum = skb_checksum(skb, 0, skb->len, 0);
if (!csum)
break;
/* fall through */
case CHECKSUM_NONE:
skb->csum = 0;
csum = __skb_checksum_complete(skb);
skb->ip_summed = CHECKSUM_HW;
csum = (u16)csum_fold(skb->csum);
}
offset += 4;
}
Expand Down
Loading

0 comments on commit 985834a

Please sign in to comment.