Commit c4331890 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/net-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 20efbf29 6bfeebf2
...@@ -630,19 +630,15 @@ static int __init scc_enet_init(void) ...@@ -630,19 +630,15 @@ static int __init scc_enet_init(void)
bd = (bd_t *)__res; bd = (bd_t *)__res;
/* Allocate some private information. /* Create an Ethernet device instance.
*/ */
cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL); dev = alloc_etherdev(sizeof(*cep));
if (cep == NULL) if (!dev)
return -ENOMEM; return -ENOMEM;
__clear_user(cep,sizeof(*cep)); cep = dev->priv;
spin_lock_init(&cep->lock); spin_lock_init(&cep->lock);
/* Create an Ethernet device instance.
*/
dev = init_etherdev(0, 0);
/* Get pointer to SCC area in parameter RAM. /* Get pointer to SCC area in parameter RAM.
*/ */
ep = (scc_enet_t *)(&immap->im_dprambase[PROFF_ENET]); ep = (scc_enet_t *)(&immap->im_dprambase[PROFF_ENET]);
...@@ -771,6 +767,7 @@ static int __init scc_enet_init(void) ...@@ -771,6 +767,7 @@ static int __init scc_enet_init(void)
/* Allocate a page. /* Allocate a page.
*/ */
mem_addr = __get_free_page(GFP_KERNEL); mem_addr = __get_free_page(GFP_KERNEL);
/* BUG: no check for failure */
/* Initialize the BD for every fragment in the page. /* Initialize the BD for every fragment in the page.
*/ */
...@@ -808,6 +805,7 @@ static int __init scc_enet_init(void) ...@@ -808,6 +805,7 @@ static int __init scc_enet_init(void)
/* Install our interrupt handler. /* Install our interrupt handler.
*/ */
request_irq(SIU_INT_ENET, scc_enet_interrupt, 0, "enet", dev); request_irq(SIU_INT_ENET, scc_enet_interrupt, 0, "enet", dev);
/* BUG: no check for failure */
/* Set GSMR_H to enable all normal operating modes. /* Set GSMR_H to enable all normal operating modes.
* Set GSMR_L to enable Ethernet to MC68160. * Set GSMR_L to enable Ethernet to MC68160.
...@@ -837,7 +835,6 @@ static int __init scc_enet_init(void) ...@@ -837,7 +835,6 @@ static int __init scc_enet_init(void)
io->iop_pdatc |= PC_EST8260_ENET_NOTFD; io->iop_pdatc |= PC_EST8260_ENET_NOTFD;
dev->base_addr = (unsigned long)ep; dev->base_addr = (unsigned long)ep;
dev->priv = cep;
/* The CPM Ethernet specific entries in the device structure. */ /* The CPM Ethernet specific entries in the device structure. */
dev->open = scc_enet_open; dev->open = scc_enet_open;
...@@ -852,6 +849,12 @@ static int __init scc_enet_init(void) ...@@ -852,6 +849,12 @@ static int __init scc_enet_init(void)
*/ */
sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
err = register_netdev(dev);
if (err) {
kfree(dev);
return err;
}
printk("%s: SCC ENET Version 0.1, ", dev->name); printk("%s: SCC ENET Version 0.1, ", dev->name);
for (i=0; i<5; i++) for (i=0; i<5; i++)
printk("%02x:", dev->dev_addr[i]); printk("%02x:", dev->dev_addr[i]);
......
...@@ -1328,7 +1328,7 @@ static int __init fec_enet_init(void) ...@@ -1328,7 +1328,7 @@ static int __init fec_enet_init(void)
struct net_device *dev; struct net_device *dev;
struct fcc_enet_private *cep; struct fcc_enet_private *cep;
fcc_info_t *fip; fcc_info_t *fip;
int i, np; int i, np, err;
volatile immap_t *immap; volatile immap_t *immap;
volatile iop8260_t *io; volatile iop8260_t *io;
...@@ -1339,23 +1339,16 @@ static int __init fec_enet_init(void) ...@@ -1339,23 +1339,16 @@ static int __init fec_enet_init(void)
fip = fcc_ports; fip = fcc_ports;
while (np-- > 0) { while (np-- > 0) {
/* Create an Ethernet device instance.
/* Allocate some private information.
*/ */
cep = (struct fcc_enet_private *) dev = alloc_etherdev(sizeof(*cep));
kmalloc(sizeof(*cep), GFP_KERNEL); if (!dev)
if (cep == NULL)
return -ENOMEM; return -ENOMEM;
__clear_user(cep,sizeof(*cep)); cep = dev->priv;
spin_lock_init(&cep->lock); spin_lock_init(&cep->lock);
cep->fip = fip; cep->fip = fip;
/* Create an Ethernet device instance.
*/
dev = init_etherdev(0, 0);
dev->priv = cep;
init_fcc_shutdown(fip, cep, immap); init_fcc_shutdown(fip, cep, immap);
init_fcc_ioports(fip, io, immap); init_fcc_ioports(fip, io, immap);
init_fcc_param(fip, dev, immap); init_fcc_param(fip, dev, immap);
...@@ -1376,6 +1369,12 @@ static int __init fec_enet_init(void) ...@@ -1376,6 +1369,12 @@ static int __init fec_enet_init(void)
init_fcc_startup(fip, dev); init_fcc_startup(fip, dev);
err = register_netdev(dev);
if (err) {
kfree(dev);
return err;
}
printk("%s: FCC ENET Version 0.3, ", dev->name); printk("%s: FCC ENET Version 0.3, ", dev->name);
for (i=0; i<5; i++) for (i=0; i<5; i++)
printk("%02x:", dev->dev_addr[i]); printk("%02x:", dev->dev_addr[i]);
......
...@@ -643,7 +643,7 @@ static int __init scc_enet_init(void) ...@@ -643,7 +643,7 @@ static int __init scc_enet_init(void)
{ {
struct net_device *dev; struct net_device *dev;
struct scc_enet_private *cep; struct scc_enet_private *cep;
int i, j, k; int i, j, k, err;
unsigned char *eap, *ba; unsigned char *eap, *ba;
dma_addr_t mem_addr; dma_addr_t mem_addr;
bd_t *bd; bd_t *bd;
...@@ -659,19 +659,13 @@ static int __init scc_enet_init(void) ...@@ -659,19 +659,13 @@ static int __init scc_enet_init(void)
bd = (bd_t *)__res; bd = (bd_t *)__res;
/* Allocate some private information. dev = alloc_etherdev(sizeof(*cep));
*/ if (!dev)
cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
if (cep == NULL)
return -ENOMEM; return -ENOMEM;
__clear_user(cep,sizeof(*cep)); cep = dev->priv;
spin_lock_init(&cep->lock); spin_lock_init(&cep->lock);
/* Create an Ethernet device instance.
*/
dev = init_etherdev(0, 0);
/* Get pointer to SCC area in parameter RAM. /* Get pointer to SCC area in parameter RAM.
*/ */
ep = (scc_enet_t *)(&cp->cp_dparam[PROFF_ENET]); ep = (scc_enet_t *)(&cp->cp_dparam[PROFF_ENET]);
...@@ -841,6 +835,7 @@ static int __init scc_enet_init(void) ...@@ -841,6 +835,7 @@ static int __init scc_enet_init(void)
/* Allocate a page. /* Allocate a page.
*/ */
ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr); ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
/* BUG: no check for failure */
/* Initialize the BD for every fragment in the page. /* Initialize the BD for every fragment in the page.
*/ */
...@@ -939,7 +934,6 @@ static int __init scc_enet_init(void) ...@@ -939,7 +934,6 @@ static int __init scc_enet_init(void)
#endif #endif
dev->base_addr = (unsigned long)ep; dev->base_addr = (unsigned long)ep;
dev->priv = cep;
#if 0 #if 0
dev->name = "CPM_ENET"; dev->name = "CPM_ENET";
#endif #endif
...@@ -953,6 +947,12 @@ static int __init scc_enet_init(void) ...@@ -953,6 +947,12 @@ static int __init scc_enet_init(void)
dev->get_stats = scc_enet_get_stats; dev->get_stats = scc_enet_get_stats;
dev->set_multicast_list = set_multicast_list; dev->set_multicast_list = set_multicast_list;
err = register_netdev(dev);
if (err) {
kfree(dev);
return err;
}
/* And last, enable the transmit and receive processing. /* And last, enable the transmit and receive processing.
*/ */
sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
......
...@@ -1570,7 +1570,7 @@ static int __init fec_enet_init(void) ...@@ -1570,7 +1570,7 @@ static int __init fec_enet_init(void)
{ {
struct net_device *dev; struct net_device *dev;
struct fec_enet_private *fep; struct fec_enet_private *fep;
int i, j, k; int i, j, k, err;
unsigned char *eap, *iap, *ba; unsigned char *eap, *iap, *ba;
unsigned long mem_addr; unsigned long mem_addr;
volatile cbd_t *bdp; volatile cbd_t *bdp;
...@@ -1586,17 +1586,11 @@ static int __init fec_enet_init(void) ...@@ -1586,17 +1586,11 @@ static int __init fec_enet_init(void)
bd = (bd_t *)__res; bd = (bd_t *)__res;
/* Allocate some private information. dev = alloc_etherdev(sizeof(*fep));
*/ if (!dev)
fep = (struct fec_enet_private *)kmalloc(sizeof(*fep), GFP_KERNEL);
if (fep == NULL)
return -ENOMEM; return -ENOMEM;
__clear_user(fep,sizeof(*fep)); fep = dev->priv;
/* Create an Ethernet device instance.
*/
dev = init_etherdev(0, 0);
fecp = &(immap->im_cpm.cp_fec); fecp = &(immap->im_cpm.cp_fec);
...@@ -1661,6 +1655,7 @@ static int __init fec_enet_init(void) ...@@ -1661,6 +1655,7 @@ static int __init fec_enet_init(void)
/* Allocate a page. /* Allocate a page.
*/ */
ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr); ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
/* BUG: no check for failure */
/* Initialize the BD for every fragment in the page. /* Initialize the BD for every fragment in the page.
*/ */
...@@ -1715,7 +1710,6 @@ static int __init fec_enet_init(void) ...@@ -1715,7 +1710,6 @@ static int __init fec_enet_init(void)
#endif #endif
dev->base_addr = (unsigned long)fecp; dev->base_addr = (unsigned long)fecp;
dev->priv = fep;
/* The FEC Ethernet specific entries in the device structure. */ /* The FEC Ethernet specific entries in the device structure. */
dev->open = fec_enet_open; dev->open = fec_enet_open;
...@@ -1752,6 +1746,12 @@ static int __init fec_enet_init(void) ...@@ -1752,6 +1746,12 @@ static int __init fec_enet_init(void)
fecp->fec_mii_speed = 0; /* turn off MDIO */ fecp->fec_mii_speed = 0; /* turn off MDIO */
#endif /* CONFIG_USE_MDIO */ #endif /* CONFIG_USE_MDIO */
err = register_netdev(dev);
if (err) {
kfree(dev);
return err;
}
printk ("%s: FEC ENET Version 0.2, FEC irq %d" printk ("%s: FEC ENET Version 0.2, FEC irq %d"
#ifdef PHY_INTERRUPT #ifdef PHY_INTERRUPT
", MII irq %d" ", MII irq %d"
......
...@@ -184,8 +184,8 @@ extern struct dn_fib_table *dn_fib_tables[]; ...@@ -184,8 +184,8 @@ extern struct dn_fib_table *dn_fib_tables[];
#else /* Endnode */ #else /* Endnode */
#define dn_fib_init() (0) #define dn_fib_init() do { } while(0)
#define dn_fib_cleanup() (0) #define dn_fib_cleanup() do { } while(0)
#define dn_fib_lookup(fl, res) (-ESRCH) #define dn_fib_lookup(fl, res) (-ESRCH)
#define dn_fib_info_put(fi) do { } while(0) #define dn_fib_info_put(fi) do { } while(0)
......
...@@ -299,7 +299,8 @@ extern int ipv6_rcv(struct sk_buff *skb, ...@@ -299,7 +299,8 @@ extern int ipv6_rcv(struct sk_buff *skb,
extern int ip6_xmit(struct sock *sk, extern int ip6_xmit(struct sock *sk,
struct sk_buff *skb, struct sk_buff *skb,
struct flowi *fl, struct flowi *fl,
struct ipv6_txoptions *opt); struct ipv6_txoptions *opt,
int ipfragok);
extern int ip6_nd_hdr(struct sock *sk, extern int ip6_nd_hdr(struct sock *sk,
struct sk_buff *skb, struct sk_buff *skb,
...@@ -315,7 +316,7 @@ extern int ip6_build_xmit(struct sock *sk, ...@@ -315,7 +316,7 @@ extern int ip6_build_xmit(struct sock *sk,
unsigned length, unsigned length,
struct ipv6_txoptions *opt, struct ipv6_txoptions *opt,
int hlimit, int flags); int hlimit, int flags);
extern int ip6_found_nexthdr(struct sk_buff *skb, u8 **nexthdr); extern int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr);
extern int ip6_append_data(struct sock *sk, extern int ip6_append_data(struct sock *sk,
int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb),
......
...@@ -790,7 +790,8 @@ void xfrm6_policy_init(void); ...@@ -790,7 +790,8 @@ void xfrm6_policy_init(void);
struct xfrm_policy *xfrm_policy_alloc(int gfp); struct xfrm_policy *xfrm_policy_alloc(int gfp);
extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *); extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *);
int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
struct xfrm_policy *xfrm_policy_delete(int dir, struct xfrm_selector *sel); struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
int delete);
struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete); struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete);
void xfrm_policy_flush(void); void xfrm_policy_flush(void);
u32 xfrm_get_acqseq(void); u32 xfrm_get_acqseq(void);
......
...@@ -39,57 +39,6 @@ ...@@ -39,57 +39,6 @@
#define MAX_SG_ONSTACK 4 #define MAX_SG_ONSTACK 4
/* BUGS:
* - we assume replay seqno is always present.
*/
/* Move to common area: it is shared with AH. */
/* Common with AH after some work on arguments. */
static int get_offset(u8 *packet, u32 packet_len, u8 *nexthdr, struct ipv6_opt_hdr **prevhdr)
{
u16 offset = sizeof(struct ipv6hdr);
struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(packet + offset);
u8 nextnexthdr;
*nexthdr = ((struct ipv6hdr*)packet)->nexthdr;
while (offset + 1 < packet_len) {
switch (*nexthdr) {
case NEXTHDR_HOP:
case NEXTHDR_ROUTING:
offset += ipv6_optlen(exthdr);
*nexthdr = exthdr->nexthdr;
*prevhdr = exthdr;
exthdr = (struct ipv6_opt_hdr*)(packet + offset);
break;
case NEXTHDR_DEST:
nextnexthdr =
((struct ipv6_opt_hdr*)(packet + offset + ipv6_optlen(exthdr)))->nexthdr;
/* XXX We know the option is inner dest opt
with next next header check. */
if (nextnexthdr != NEXTHDR_HOP &&
nextnexthdr != NEXTHDR_ROUTING &&
nextnexthdr != NEXTHDR_DEST) {
return offset;
}
offset += ipv6_optlen(exthdr);
*nexthdr = exthdr->nexthdr;
*prevhdr = exthdr;
exthdr = (struct ipv6_opt_hdr*)(packet + offset);
break;
default :
return offset;
}
}
return offset;
}
int esp6_output(struct sk_buff *skb) int esp6_output(struct sk_buff *skb)
{ {
int err; int err;
...@@ -101,12 +50,12 @@ int esp6_output(struct sk_buff *skb) ...@@ -101,12 +50,12 @@ int esp6_output(struct sk_buff *skb)
struct crypto_tfm *tfm; struct crypto_tfm *tfm;
struct esp_data *esp; struct esp_data *esp;
struct sk_buff *trailer; struct sk_buff *trailer;
struct ipv6_opt_hdr *prevhdr = NULL;
int blksize; int blksize;
int clen; int clen;
int alen; int alen;
int nfrags; int nfrags;
u8 nexthdr; u8 *prevhdr;
u8 nexthdr = 0;
/* First, if the skb is not checksummed, complete checksum. */ /* First, if the skb is not checksummed, complete checksum. */
if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) { if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
...@@ -123,7 +72,9 @@ int esp6_output(struct sk_buff *skb) ...@@ -123,7 +72,9 @@ int esp6_output(struct sk_buff *skb)
/* Strip IP header in transport mode. Save it. */ /* Strip IP header in transport mode. Save it. */
if (!x->props.mode) { if (!x->props.mode) {
hdr_len = get_offset(skb->nh.raw, skb->len, &nexthdr, &prevhdr); hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
nexthdr = *prevhdr;
*prevhdr = IPPROTO_ESP;
iph = kmalloc(hdr_len, GFP_ATOMIC); iph = kmalloc(hdr_len, GFP_ATOMIC);
if (!iph) { if (!iph) {
err = -ENOMEM; err = -ENOMEM;
...@@ -178,18 +129,12 @@ int esp6_output(struct sk_buff *skb) ...@@ -178,18 +129,12 @@ int esp6_output(struct sk_buff *skb)
ipv6_addr_copy(&top_iph->daddr, ipv6_addr_copy(&top_iph->daddr,
(struct in6_addr *)&x->id.daddr); (struct in6_addr *)&x->id.daddr);
} else { } else {
/* XXX exthdr */
esph = (struct ipv6_esp_hdr*)skb_push(skb, x->props.header_len); esph = (struct ipv6_esp_hdr*)skb_push(skb, x->props.header_len);
skb->h.raw = (unsigned char*)esph; skb->h.raw = (unsigned char*)esph;
top_iph = (struct ipv6hdr*)skb_push(skb, hdr_len); top_iph = (struct ipv6hdr*)skb_push(skb, hdr_len);
memcpy(top_iph, iph, hdr_len); memcpy(top_iph, iph, hdr_len);
kfree(iph); kfree(iph);
top_iph->payload_len = htons(skb->len + alen - sizeof(struct ipv6hdr)); top_iph->payload_len = htons(skb->len + alen - sizeof(struct ipv6hdr));
if (prevhdr) {
prevhdr->nexthdr = IPPROTO_ESP;
} else {
top_iph->nexthdr = IPPROTO_ESP;
}
*(u8*)(trailer->tail - 1) = nexthdr; *(u8*)(trailer->tail - 1) = nexthdr;
} }
...@@ -302,6 +247,7 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b ...@@ -302,6 +247,7 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b
struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags]; struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags];
struct scatterlist *sg = sgbuf; struct scatterlist *sg = sgbuf;
u8 padlen; u8 padlen;
u8 *prevhdr;
if (unlikely(nfrags > MAX_SG_ONSTACK)) { if (unlikely(nfrags > MAX_SG_ONSTACK)) {
sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
...@@ -325,11 +271,13 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b ...@@ -325,11 +271,13 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b
} }
/* ... check padding bits here. Silly. :-) */ /* ... check padding bits here. Silly. :-) */
ret_nexthdr = ((struct ipv6hdr*)tmp_hdr)->nexthdr = nexthdr[1];
pskb_trim(skb, skb->len - alen - padlen - 2); pskb_trim(skb, skb->len - alen - padlen - 2);
skb->h.raw = skb_pull(skb, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen); skb->h.raw = skb_pull(skb, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen);
skb->nh.raw += sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; skb->nh.raw += sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen;
memcpy(skb->nh.raw, tmp_hdr, hdr_len); memcpy(skb->nh.raw, tmp_hdr, hdr_len);
skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
ip6_find_1stfragopt(skb, &prevhdr);
ret_nexthdr = *prevhdr = nexthdr[1];
} }
kfree(tmp_hdr); kfree(tmp_hdr);
return ret_nexthdr; return ret_nexthdr;
......
...@@ -145,7 +145,7 @@ static inline int ip6_input_finish(struct sk_buff *skb) ...@@ -145,7 +145,7 @@ static inline int ip6_input_finish(struct sk_buff *skb)
nexthdr = skb->nh.ipv6h->nexthdr; nexthdr = skb->nh.ipv6h->nexthdr;
nhoff = offsetof(struct ipv6hdr, nexthdr); nhoff = offsetof(struct ipv6hdr, nexthdr);
/* Skip hop-by-hop options, they are already parsed. */ /* Skip hop-by-hop options, they are already parsed. */
if (nexthdr == NEXTHDR_HOP) { if (nexthdr == NEXTHDR_HOP) {
nhoff = sizeof(struct ipv6hdr); nhoff = sizeof(struct ipv6hdr);
nexthdr = skb->h.raw[0]; nexthdr = skb->h.raw[0];
......
...@@ -196,7 +196,7 @@ static inline int ip6_maybe_reroute(struct sk_buff *skb) ...@@ -196,7 +196,7 @@ static inline int ip6_maybe_reroute(struct sk_buff *skb)
*/ */
int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
struct ipv6_txoptions *opt) struct ipv6_txoptions *opt, int ipfragok)
{ {
struct ipv6_pinfo *np = sk ? inet6_sk(sk) : NULL; struct ipv6_pinfo *np = sk ? inet6_sk(sk) : NULL;
struct in6_addr *first_hop = &fl->fl6_dst; struct in6_addr *first_hop = &fl->fl6_dst;
...@@ -258,13 +258,14 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, ...@@ -258,13 +258,14 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
ipv6_addr_copy(&hdr->daddr, first_hop); ipv6_addr_copy(&hdr->daddr, first_hop);
mtu = dst_pmtu(dst); mtu = dst_pmtu(dst);
if (skb->len <= mtu) { if ((skb->len <= mtu) || ipfragok) {
IP6_INC_STATS(Ip6OutRequests); IP6_INC_STATS(Ip6OutRequests);
return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute); return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
} }
if (net_ratelimit()) if (net_ratelimit())
printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
kfree_skb(skb); kfree_skb(skb);
return -EMSGSIZE; return -EMSGSIZE;
...@@ -381,7 +382,7 @@ static int ip6_frag_xmit(struct sock *sk, inet_getfrag_t getfrag, ...@@ -381,7 +382,7 @@ static int ip6_frag_xmit(struct sock *sk, inet_getfrag_t getfrag,
/* /*
* Length of fragmented part on every packet but * Length of fragmented part on every packet but
* the last must be an: * the last must be an:
* "integer multiple of 8 octects". * "integer multiple of 8 octets".
*/ */
frag_len = (mtu - unfrag_len) & ~0x7; frag_len = (mtu - unfrag_len) & ~0x7;
...@@ -587,7 +588,7 @@ int ip6_build_xmit(struct sock *sk, inet_getfrag_t getfrag, const void *data, ...@@ -587,7 +588,7 @@ int ip6_build_xmit(struct sock *sk, inet_getfrag_t getfrag, const void *data,
if (err) { if (err) {
#if IP6_DEBUG >= 2 #if IP6_DEBUG >= 2
printk(KERN_DEBUG "ip6_build_xmit: " printk(KERN_DEBUG "ip6_build_xmit: "
"no availiable source address\n"); "no available source address\n");
#endif #endif
goto out; goto out;
} }
...@@ -887,7 +888,7 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) ...@@ -887,7 +888,7 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
#endif #endif
} }
int ip6_found_nexthdr(struct sk_buff *skb, u8 **nexthdr) int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
{ {
u16 offset = sizeof(struct ipv6hdr); u16 offset = sizeof(struct ipv6hdr);
struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1); struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
...@@ -929,7 +930,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) ...@@ -929,7 +930,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
u8 *prevhdr, nexthdr = 0; u8 *prevhdr, nexthdr = 0;
dev = rt->u.dst.dev; dev = rt->u.dst.dev;
hlen = ip6_found_nexthdr(skb, &prevhdr); hlen = ip6_find_1stfragopt(skb, &prevhdr);
nexthdr = *prevhdr; nexthdr = *prevhdr;
mtu = dst_pmtu(&rt->u.dst) - hlen - sizeof(struct frag_hdr); mtu = dst_pmtu(&rt->u.dst) - hlen - sizeof(struct frag_hdr);
...@@ -1187,7 +1188,7 @@ int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) ...@@ -1187,7 +1188,7 @@ int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
if (err) { if (err) {
#if IP6_DEBUG >= 2 #if IP6_DEBUG >= 2
printk(KERN_DEBUG "ip6_build_xmit: " printk(KERN_DEBUG "ip6_build_xmit: "
"no availiable source address\n"); "no available source address\n");
#endif #endif
return err; return err;
} }
......
...@@ -105,7 +105,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, s ...@@ -105,7 +105,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, s
iph = skb->nh.ipv6h; iph = skb->nh.ipv6h;
iph->payload_len = htons(skb->len); iph->payload_len = htons(skb->len);
ip6_found_nexthdr(skb, &prevhdr); ip6_find_1stfragopt(skb, &prevhdr);
*prevhdr = nexthdr; *prevhdr = nexthdr;
out: out:
if (tmp_hdr) if (tmp_hdr)
...@@ -160,7 +160,7 @@ static int ipcomp6_output(struct sk_buff *skb) ...@@ -160,7 +160,7 @@ static int ipcomp6_output(struct sk_buff *skb)
skb->nh.raw = skb->data; /* == top_iph */ skb->nh.raw = skb->data; /* == top_iph */
skb->h.raw = skb->nh.raw + hdr_len; skb->h.raw = skb->nh.raw + hdr_len;
} else { } else {
hdr_len = ip6_found_nexthdr(skb, &prevhdr); hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
nexthdr = *prevhdr; nexthdr = *prevhdr;
} }
...@@ -203,7 +203,7 @@ static int ipcomp6_output(struct sk_buff *skb) ...@@ -203,7 +203,7 @@ static int ipcomp6_output(struct sk_buff *skb)
top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
skb->nh.raw = skb->data; /* top_iph */ skb->nh.raw = skb->data; /* top_iph */
ip6_found_nexthdr(skb, &prevhdr); ip6_find_1stfragopt(skb, &prevhdr);
*prevhdr = IPPROTO_COMP; *prevhdr = IPPROTO_COMP;
ipch = (struct ipv6_comp_hdr *)((unsigned char *)top_iph + hdr_len); ipch = (struct ipv6_comp_hdr *)((unsigned char *)top_iph + hdr_len);
......
...@@ -35,6 +35,6 @@ EXPORT_SYMBOL(ipv6_chk_addr); ...@@ -35,6 +35,6 @@ EXPORT_SYMBOL(ipv6_chk_addr);
EXPORT_SYMBOL(in6addr_any); EXPORT_SYMBOL(in6addr_any);
EXPORT_SYMBOL(in6addr_loopback); EXPORT_SYMBOL(in6addr_loopback);
EXPORT_SYMBOL(in6_dev_finish_destroy); EXPORT_SYMBOL(in6_dev_finish_destroy);
EXPORT_SYMBOL(ip6_found_nexthdr); EXPORT_SYMBOL(ip6_find_1stfragopt);
EXPORT_SYMBOL(xfrm6_rcv); EXPORT_SYMBOL(xfrm6_rcv);
EXPORT_SYMBOL(xfrm6_clear_mutable_options); EXPORT_SYMBOL(xfrm6_clear_mutable_options);
...@@ -939,7 +939,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req, ...@@ -939,7 +939,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
csum_partial((char *)th, skb->len, skb->csum)); csum_partial((char *)th, skb->len, skb->csum));
ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr); ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr);
err = ip6_xmit(sk, skb, &fl, opt); err = ip6_xmit(sk, skb, &fl, opt, 0);
if (err == NET_XMIT_CN) if (err == NET_XMIT_CN)
err = 0; err = 0;
} }
...@@ -1057,7 +1057,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb) ...@@ -1057,7 +1057,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
buff->dst = ip6_route_output(NULL, &fl); buff->dst = ip6_route_output(NULL, &fl);
if (buff->dst->error == 0) { if (buff->dst->error == 0) {
ip6_xmit(NULL, buff, &fl, NULL); ip6_xmit(NULL, buff, &fl, NULL, 0);
TCP_INC_STATS_BH(TcpOutSegs); TCP_INC_STATS_BH(TcpOutSegs);
TCP_INC_STATS_BH(TcpOutRsts); TCP_INC_STATS_BH(TcpOutRsts);
return; return;
...@@ -1120,7 +1120,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ...@@ -1120,7 +1120,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
buff->dst = ip6_route_output(NULL, &fl); buff->dst = ip6_route_output(NULL, &fl);
if (buff->dst->error == 0) { if (buff->dst->error == 0) {
ip6_xmit(NULL, buff, &fl, NULL); ip6_xmit(NULL, buff, &fl, NULL, 0);
TCP_INC_STATS_BH(TcpOutSegs); TCP_INC_STATS_BH(TcpOutSegs);
return; return;
} }
...@@ -1823,7 +1823,7 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok) ...@@ -1823,7 +1823,7 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
/* Restore final destination back after routing done */ /* Restore final destination back after routing done */
ipv6_addr_copy(&fl.fl6_dst, &np->daddr); ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
return ip6_xmit(sk, skb, &fl, np->opt); return ip6_xmit(sk, skb, &fl, np->opt, 0);
} }
static void v6_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr) static void v6_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
......
...@@ -1990,7 +1990,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg ...@@ -1990,7 +1990,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
if (sel.dport) if (sel.dport)
sel.dport_mask = ~0; sel.dport_mask = ~0;
xp = xfrm_policy_delete(pol->sadb_x_policy_dir-1, &sel); xp = xfrm_policy_bysel(pol->sadb_x_policy_dir-1, &sel, 1);
if (xp == NULL) if (xp == NULL)
return -ENOENT; return -ENOENT;
......
...@@ -337,7 +337,7 @@ EXPORT_SYMBOL(xfrm_find_acq); ...@@ -337,7 +337,7 @@ EXPORT_SYMBOL(xfrm_find_acq);
EXPORT_SYMBOL(xfrm_alloc_spi); EXPORT_SYMBOL(xfrm_alloc_spi);
EXPORT_SYMBOL(xfrm_state_flush); EXPORT_SYMBOL(xfrm_state_flush);
EXPORT_SYMBOL(xfrm_policy_kill); EXPORT_SYMBOL(xfrm_policy_kill);
EXPORT_SYMBOL(xfrm_policy_delete); EXPORT_SYMBOL(xfrm_policy_bysel);
EXPORT_SYMBOL(xfrm_policy_insert); EXPORT_SYMBOL(xfrm_policy_insert);
EXPORT_SYMBOL(xfrm_policy_walk); EXPORT_SYMBOL(xfrm_policy_walk);
EXPORT_SYMBOL(xfrm_policy_flush); EXPORT_SYMBOL(xfrm_policy_flush);
......
...@@ -176,7 +176,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport, ...@@ -176,7 +176,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport,
SCTP_INC_STATS(SctpOutSCTPPacks); SCTP_INC_STATS(SctpOutSCTPPacks);
return ip6_xmit(sk, skb, &fl, np->opt); return ip6_xmit(sk, skb, &fl, np->opt, ipfragok);
} }
/* Returns the dst cache entry for the given source and destination ip /* Returns the dst cache entry for the given source and destination ip
......
...@@ -878,8 +878,6 @@ int sctp_register_pf(struct sctp_pf *pf, sa_family_t family) ...@@ -878,8 +878,6 @@ int sctp_register_pf(struct sctp_pf *pf, sa_family_t family)
static int __init init_sctp_mibs(void) static int __init init_sctp_mibs(void)
{ {
int i;
sctp_statistics[0] = alloc_percpu(struct sctp_mib); sctp_statistics[0] = alloc_percpu(struct sctp_mib);
if (!sctp_statistics[0]) if (!sctp_statistics[0])
return -ENOMEM; return -ENOMEM;
......
...@@ -297,19 +297,25 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) ...@@ -297,19 +297,25 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
return 0; return 0;
} }
struct xfrm_policy *xfrm_policy_delete(int dir, struct xfrm_selector *sel) struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
int delete)
{ {
struct xfrm_policy *pol, **p; struct xfrm_policy *pol, **p;
write_lock_bh(&xfrm_policy_lock); write_lock_bh(&xfrm_policy_lock);
for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) { for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) {
if (memcmp(sel, &pol->selector, sizeof(*sel)) == 0) { if (memcmp(sel, &pol->selector, sizeof(*sel)) == 0) {
*p = pol->next; if (delete)
*p = pol->next;
break; break;
} }
} }
if (pol) if (pol) {
atomic_inc(&flow_cache_genid); if (delete)
atomic_inc(&flow_cache_genid);
else
xfrm_pol_hold(pol);
}
write_unlock_bh(&xfrm_policy_lock); write_unlock_bh(&xfrm_policy_lock);
return pol; return pol;
} }
......
...@@ -656,26 +656,6 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr ...@@ -656,26 +656,6 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
return 0; return 0;
} }
static int xfrm_del_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
{
struct xfrm_policy *xp;
struct xfrm_userpolicy_id *p;
int err;
p = NLMSG_DATA(nlh);
err = verify_policy_dir(p->dir);
if (err)
return err;
xp = xfrm_policy_delete(p->dir, &p->sel);
if (xp == NULL)
return -ENOENT;
xfrm_policy_kill(xp);
xfrm_pol_put(xp);
return 0;
}
static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr) static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr)
{ {
struct xfrm_dump_info *sp = ptr; struct xfrm_dump_info *sp = ptr;
...@@ -774,20 +754,36 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr ...@@ -774,20 +754,36 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
{ {
struct xfrm_policy *xp; struct xfrm_policy *xp;
struct xfrm_userpolicy_id *p; struct xfrm_userpolicy_id *p;
struct sk_buff *resp_skb;
int err; int err;
int delete;
p = NLMSG_DATA(nlh); p = NLMSG_DATA(nlh);
xp = xfrm_policy_byid(p->dir, p->index, 0); delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
err = verify_policy_dir(p->dir);
if (err)
return err;
if (p->index)
xp = xfrm_policy_byid(p->dir, p->index, delete);
else
xp = xfrm_policy_bysel(p->dir, &p->sel, delete);
if (xp == NULL) if (xp == NULL)
return -ENOENT; return -ENOENT;
resp_skb = xfrm_policy_netlink(skb, xp, p->dir, nlh->nlmsg_seq); if (delete)
if (IS_ERR(resp_skb)) { xfrm_policy_kill(xp);
err = PTR_ERR(resp_skb); else {
} else { struct sk_buff *resp_skb;
err = netlink_unicast(xfrm_nl, resp_skb,
NETLINK_CB(skb).pid, MSG_DONTWAIT); resp_skb = xfrm_policy_netlink(skb, xp, p->dir, nlh->nlmsg_seq);
if (IS_ERR(resp_skb)) {
err = PTR_ERR(resp_skb);
} else {
err = netlink_unicast(xfrm_nl, resp_skb,
NETLINK_CB(skb).pid,
MSG_DONTWAIT);
}
} }
xfrm_pol_put(xp); xfrm_pol_put(xp);
...@@ -819,7 +815,7 @@ static struct xfrm_link { ...@@ -819,7 +815,7 @@ static struct xfrm_link {
.dump = xfrm_dump_sa, .dump = xfrm_dump_sa,
}, },
{ .doit = xfrm_add_policy }, { .doit = xfrm_add_policy },
{ .doit = xfrm_del_policy }, { .doit = xfrm_get_policy },
{ {
.doit = xfrm_get_policy, .doit = xfrm_get_policy,
.dump = xfrm_dump_policy, .dump = xfrm_dump_policy,
......
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