mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-31 08:04:55 +00:00
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (42 commits) [IPV6]: Consolidate the ip6_pol_route_(input|output) pair [TCP]: Make snd_cwnd_cnt 32-bit [TCP]: Update the /proc/net/tcp documentation [NETNS]: Don't panic on creating the namespace's loopback [NEIGH]: Ensure that pneigh_lookup is protected with RTNL [INET]: kmalloc+memset -> kzalloc in frag_alloc_queue [ISDN]: Fix compile with CONFIG_ISDN_X25 disabled. [IPV6]: Replace sk_buff ** with sk_buff * in input handlers [SELINUX]: Update for netfilter ->hook() arg changes. [INET]: Consolidate the xxx_put [INET]: Small cleanup for xxx_put after evictor consolidation [INET]: Consolidate the xxx_evictor [INET]: Consolidate the xxx_frag_destroy [INET]: Consolidate xxx_the secret_rebuild [INET]: Consolidate the xxx_frag_kill [INET]: Collect common frag sysctl variables together [INET]: Collect frag queues management objects together [INET]: Move common fields from frag_queues in one place. [TG3]: Fix performance regression on 5705. [ISDN]: Remove local copy of device name to make sure renames work. ...
This commit is contained in:
commit
a52cefc80f
@ -1,8 +1,9 @@
|
||||
This document describes the interfaces /proc/net/tcp and /proc/net/tcp6.
|
||||
Note that these interfaces are deprecated in favor of tcp_diag.
|
||||
|
||||
These /proc interfaces provide information about currently active TCP
|
||||
connections, and are implemented by tcp_get_info() in net/ipv4/tcp_ipv4.c and
|
||||
tcp6_get_info() in net/ipv6/tcp_ipv6.c, respectively.
|
||||
connections, and are implemented by tcp4_seq_show() in net/ipv4/tcp_ipv4.c
|
||||
and tcp6_seq_show() in net/ipv6/tcp_ipv6.c, respectively.
|
||||
|
||||
It will first list all listening TCP sockets, and next list all established
|
||||
TCP connections. A typical entry of /proc/net/tcp would look like this (split
|
||||
|
@ -328,7 +328,7 @@ isdn_net_autohup(void)
|
||||
l->cps = (l->transcount * HZ) / (jiffies - last_jiffies);
|
||||
l->transcount = 0;
|
||||
if (dev->net_verbose > 3)
|
||||
printk(KERN_DEBUG "%s: %d bogocps\n", l->name, l->cps);
|
||||
printk(KERN_DEBUG "%s: %d bogocps\n", p->dev->name, l->cps);
|
||||
if ((l->flags & ISDN_NET_CONNECTED) && (!l->dialstate)) {
|
||||
anymore = 1;
|
||||
l->huptimer++;
|
||||
@ -350,12 +350,12 @@ isdn_net_autohup(void)
|
||||
if (l->hupflags & ISDN_CHARGEHUP) {
|
||||
if (l->hupflags & ISDN_WAITCHARGE) {
|
||||
printk(KERN_DEBUG "isdn_net: Hupflags of %s are %X\n",
|
||||
l->name, l->hupflags);
|
||||
p->dev->name, l->hupflags);
|
||||
isdn_net_hangup(p->dev);
|
||||
} else if (time_after(jiffies, l->chargetime + l->chargeint)) {
|
||||
printk(KERN_DEBUG
|
||||
"isdn_net: %s: chtime = %lu, chint = %d\n",
|
||||
l->name, l->chargetime, l->chargeint);
|
||||
p->dev->name, l->chargetime, l->chargeint);
|
||||
isdn_net_hangup(p->dev);
|
||||
}
|
||||
} else
|
||||
@ -442,8 +442,8 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
|
||||
#endif
|
||||
isdn_net_lp_disconnected(lp);
|
||||
isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
|
||||
printk(KERN_INFO "%s: remote hangup\n", lp->name);
|
||||
printk(KERN_INFO "%s: Chargesum is %d\n", lp->name,
|
||||
printk(KERN_INFO "%s: remote hangup\n", p->dev->name);
|
||||
printk(KERN_INFO "%s: Chargesum is %d\n", p->dev->name,
|
||||
lp->charge);
|
||||
isdn_net_unbind_channel(lp);
|
||||
return 1;
|
||||
@ -487,7 +487,7 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
|
||||
isdn_net_add_to_bundle(nd, lp);
|
||||
}
|
||||
}
|
||||
printk(KERN_INFO "isdn_net: %s connected\n", lp->name);
|
||||
printk(KERN_INFO "isdn_net: %s connected\n", p->dev->name);
|
||||
/* If first Chargeinfo comes before B-Channel connect,
|
||||
* we correct the timestamp here.
|
||||
*/
|
||||
@ -534,7 +534,7 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
|
||||
lp->hupflags |= ISDN_HAVECHARGE;
|
||||
lp->chargetime = jiffies;
|
||||
printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",
|
||||
lp->name, lp->chargetime);
|
||||
p->dev->name, lp->chargetime);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -565,7 +565,7 @@ isdn_net_dial(void)
|
||||
|
||||
#ifdef ISDN_DEBUG_NET_DIAL
|
||||
if (lp->dialstate)
|
||||
printk(KERN_DEBUG "%s: dialstate=%d\n", lp->name, lp->dialstate);
|
||||
printk(KERN_DEBUG "%s: dialstate=%d\n", p->dev->name, lp->dialstate);
|
||||
#endif
|
||||
switch (lp->dialstate) {
|
||||
case 0:
|
||||
@ -578,7 +578,7 @@ isdn_net_dial(void)
|
||||
lp->dial = lp->phone[1];
|
||||
if (!lp->dial) {
|
||||
printk(KERN_WARNING "%s: phone number deleted?\n",
|
||||
lp->name);
|
||||
p->dev->name);
|
||||
isdn_net_hangup(p->dev);
|
||||
break;
|
||||
}
|
||||
@ -632,13 +632,13 @@ isdn_net_dial(void)
|
||||
cmd.arg = lp->isdn_channel;
|
||||
if (!lp->dial) {
|
||||
printk(KERN_WARNING "%s: phone number deleted?\n",
|
||||
lp->name);
|
||||
p->dev->name);
|
||||
isdn_net_hangup(p->dev);
|
||||
break;
|
||||
}
|
||||
if (!strncmp(lp->dial->num, "LEASED", strlen("LEASED"))) {
|
||||
lp->dialstate = 4;
|
||||
printk(KERN_INFO "%s: Open leased line ...\n", lp->name);
|
||||
printk(KERN_INFO "%s: Open leased line ...\n", p->dev->name);
|
||||
} else {
|
||||
if(lp->dialtimeout > 0)
|
||||
if (time_after(jiffies, lp->dialstarted + lp->dialtimeout)) {
|
||||
@ -688,7 +688,7 @@ isdn_net_dial(void)
|
||||
dev->usage[i] |= ISDN_USAGE_OUTGOING;
|
||||
isdn_info_update();
|
||||
}
|
||||
printk(KERN_INFO "%s: dialing %d %s... %s\n", lp->name,
|
||||
printk(KERN_INFO "%s: dialing %d %s... %s\n", p->dev->name,
|
||||
lp->dialretry, cmd.parm.setup.phone,
|
||||
(cmd.parm.setup.si1 == 1) ? "DOV" : "");
|
||||
lp->dtimer = 0;
|
||||
@ -797,7 +797,7 @@ isdn_net_dial(void)
|
||||
*/
|
||||
if (lp->dtimer++ > lp->cbdelay)
|
||||
{
|
||||
printk(KERN_INFO "%s: hangup waiting for callback ...\n", lp->name);
|
||||
printk(KERN_INFO "%s: hangup waiting for callback ...\n", p->dev->name);
|
||||
lp->dtimer = 0;
|
||||
lp->dialstate = 4;
|
||||
cmd.driver = lp->isdn_device;
|
||||
@ -810,7 +810,7 @@ isdn_net_dial(void)
|
||||
break;
|
||||
default:
|
||||
printk(KERN_WARNING "isdn_net: Illegal dialstate %d for device %s\n",
|
||||
lp->dialstate, lp->name);
|
||||
lp->dialstate, p->dev->name);
|
||||
}
|
||||
p = (isdn_net_dev *) p->next;
|
||||
}
|
||||
@ -836,11 +836,11 @@ isdn_net_hangup(struct net_device *d)
|
||||
if (slp->flags & ISDN_NET_CONNECTED) {
|
||||
printk(KERN_INFO
|
||||
"isdn_net: hang up slave %s before %s\n",
|
||||
slp->name, lp->name);
|
||||
lp->slave->name, d->name);
|
||||
isdn_net_hangup(lp->slave);
|
||||
}
|
||||
}
|
||||
printk(KERN_INFO "isdn_net: local hangup %s\n", lp->name);
|
||||
printk(KERN_INFO "isdn_net: local hangup %s\n", d->name);
|
||||
#ifdef CONFIG_ISDN_PPP
|
||||
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
|
||||
isdn_ppp_free(lp);
|
||||
@ -858,7 +858,7 @@ isdn_net_hangup(struct net_device *d)
|
||||
cmd.command = ISDN_CMD_HANGUP;
|
||||
cmd.arg = lp->isdn_channel;
|
||||
isdn_command(&cmd);
|
||||
printk(KERN_INFO "%s: Chargesum is %d\n", lp->name, lp->charge);
|
||||
printk(KERN_INFO "%s: Chargesum is %d\n", d->name, lp->charge);
|
||||
isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
|
||||
}
|
||||
isdn_net_unbind_channel(lp);
|
||||
@ -885,7 +885,7 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp)
|
||||
/* fall back to old isdn_net_log_packet method() */
|
||||
char * buf = skb->data;
|
||||
|
||||
printk(KERN_DEBUG "isdn_net: protocol %04x is buggy, dev %s\n", skb->protocol, lp->name);
|
||||
printk(KERN_DEBUG "isdn_net: protocol %04x is buggy, dev %s\n", skb->protocol, lp->netdev->dev->name);
|
||||
p = buf;
|
||||
proto = ETH_P_IP;
|
||||
switch (lp->p_encap) {
|
||||
@ -1023,7 +1023,7 @@ void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb)
|
||||
ret = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb);
|
||||
if (ret != len) {
|
||||
/* we should never get here */
|
||||
printk(KERN_WARNING "%s: HL driver queue full\n", lp->name);
|
||||
printk(KERN_WARNING "%s: HL driver queue full\n", lp->netdev->dev->name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -1461,7 +1461,7 @@ isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
mod_timer(&lp->cisco_timer, expires);
|
||||
printk(KERN_INFO "%s: Keepalive period set "
|
||||
"to %d seconds.\n",
|
||||
lp->name, lp->cisco_keepalive_period);
|
||||
dev->name, lp->cisco_keepalive_period);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1512,7 +1512,7 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
|
||||
lp->cisco_line_state = 0;
|
||||
printk (KERN_WARNING
|
||||
"UPDOWN: Line protocol on Interface %s,"
|
||||
" changed state to down\n", lp->name);
|
||||
" changed state to down\n", lp->netdev->dev->name);
|
||||
/* should stop routing higher-level data accross */
|
||||
} else if ((!lp->cisco_line_state) &&
|
||||
(myseq_diff >= 0) && (myseq_diff <= 2)) {
|
||||
@ -1520,14 +1520,14 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
|
||||
lp->cisco_line_state = 1;
|
||||
printk (KERN_WARNING
|
||||
"UPDOWN: Line protocol on Interface %s,"
|
||||
" changed state to up\n", lp->name);
|
||||
" changed state to up\n", lp->netdev->dev->name);
|
||||
/* restart routing higher-level data accross */
|
||||
}
|
||||
|
||||
if (lp->cisco_debserint)
|
||||
printk (KERN_DEBUG "%s: HDLC "
|
||||
"myseq %lu, mineseen %lu%c, yourseen %lu, %s\n",
|
||||
lp->name, last_cisco_myseq, lp->cisco_mineseen,
|
||||
lp->netdev->dev->name, last_cisco_myseq, lp->cisco_mineseen,
|
||||
((last_cisco_myseq == lp->cisco_mineseen) ? '*' : 040),
|
||||
lp->cisco_yourseq,
|
||||
((lp->cisco_line_state) ? "line up" : "line down"));
|
||||
@ -1682,7 +1682,7 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
|
||||
"remote ip: %d.%d.%d.%d, "
|
||||
"local ip: %d.%d.%d.%d "
|
||||
"mask: %d.%d.%d.%d\n",
|
||||
lp->name,
|
||||
lp->netdev->dev->name,
|
||||
HIPQUAD(addr),
|
||||
HIPQUAD(local),
|
||||
HIPQUAD(mask));
|
||||
@ -1690,7 +1690,7 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
|
||||
slarp_reply_out:
|
||||
printk(KERN_INFO "%s: got invalid slarp "
|
||||
"reply (%d.%d.%d.%d/%d.%d.%d.%d) "
|
||||
"- ignored\n", lp->name,
|
||||
"- ignored\n", lp->netdev->dev->name,
|
||||
HIPQUAD(addr), HIPQUAD(mask));
|
||||
break;
|
||||
case CISCO_SLARP_KEEPALIVE:
|
||||
@ -1701,7 +1701,8 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
|
||||
lp->cisco_last_slarp_in) {
|
||||
printk(KERN_DEBUG "%s: Keepalive period mismatch - "
|
||||
"is %d but should be %d.\n",
|
||||
lp->name, period, lp->cisco_keepalive_period);
|
||||
lp->netdev->dev->name, period,
|
||||
lp->cisco_keepalive_period);
|
||||
}
|
||||
lp->cisco_last_slarp_in = jiffies;
|
||||
p += get_u32(p, &my_seq);
|
||||
@ -1732,12 +1733,12 @@ isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb)
|
||||
|
||||
if (addr != CISCO_ADDR_UNICAST && addr != CISCO_ADDR_BROADCAST) {
|
||||
printk(KERN_WARNING "%s: Unknown Cisco addr 0x%02x\n",
|
||||
lp->name, addr);
|
||||
lp->netdev->dev->name, addr);
|
||||
goto out_free;
|
||||
}
|
||||
if (ctrl != CISCO_CTRL) {
|
||||
printk(KERN_WARNING "%s: Unknown Cisco ctrl 0x%02x\n",
|
||||
lp->name, ctrl);
|
||||
lp->netdev->dev->name, ctrl);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
@ -1748,7 +1749,8 @@ isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb)
|
||||
case CISCO_TYPE_CDP:
|
||||
if (lp->cisco_debserint)
|
||||
printk(KERN_DEBUG "%s: Received CDP packet. use "
|
||||
"\"no cdp enable\" on cisco.\n", lp->name);
|
||||
"\"no cdp enable\" on cisco.\n",
|
||||
lp->netdev->dev->name);
|
||||
goto out_free;
|
||||
default:
|
||||
/* no special cisco protocol */
|
||||
@ -1843,7 +1845,7 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
|
||||
};
|
||||
#endif /* CONFIG_ISDN_X25 */
|
||||
printk(KERN_WARNING "%s: unknown encapsulation, dropping\n",
|
||||
lp->name);
|
||||
lp->netdev->dev->name);
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
@ -2174,7 +2176,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
|
||||
wret = matchret;
|
||||
#ifdef ISDN_DEBUG_NET_ICALL
|
||||
printk(KERN_DEBUG "n_fi: if='%s', l.msn=%s, l.flags=%d, l.dstate=%d\n",
|
||||
lp->name, lp->msn, lp->flags, lp->dialstate);
|
||||
p->dev->name, lp->msn, lp->flags, lp->dialstate);
|
||||
#endif
|
||||
if ((!matchret) && /* EAZ is matching */
|
||||
(((!(lp->flags & ISDN_NET_CONNECTED)) && /* but not connected */
|
||||
@ -2277,7 +2279,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
|
||||
* */
|
||||
if (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF) {
|
||||
printk(KERN_INFO "incoming call, interface %s `stopped' -> rejected\n",
|
||||
lp->name);
|
||||
p->dev->name);
|
||||
return 3;
|
||||
}
|
||||
/*
|
||||
@ -2286,7 +2288,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
|
||||
*/
|
||||
if (!isdn_net_device_started(p)) {
|
||||
printk(KERN_INFO "%s: incoming call, interface down -> rejected\n",
|
||||
lp->name);
|
||||
p->dev->name);
|
||||
return 3;
|
||||
}
|
||||
/* Interface is up, now see if it's a slave. If so, see if
|
||||
@ -2294,8 +2296,8 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
|
||||
*/
|
||||
if (lp->master) {
|
||||
isdn_net_local *mlp = (isdn_net_local *) lp->master->priv;
|
||||
printk(KERN_DEBUG "ICALLslv: %s\n", lp->name);
|
||||
printk(KERN_DEBUG "master=%s\n", mlp->name);
|
||||
printk(KERN_DEBUG "ICALLslv: %s\n", p->dev->name);
|
||||
printk(KERN_DEBUG "master=%s\n", lp->master->name);
|
||||
if (mlp->flags & ISDN_NET_CONNECTED) {
|
||||
printk(KERN_DEBUG "master online\n");
|
||||
/* Master is online, find parent-slave (master if first slave) */
|
||||
@ -2322,11 +2324,11 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
|
||||
* */
|
||||
if (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF) {
|
||||
printk(KERN_INFO "incoming call for callback, interface %s `off' -> rejected\n",
|
||||
lp->name);
|
||||
p->dev->name);
|
||||
return 3;
|
||||
}
|
||||
printk(KERN_DEBUG "%s: call from %s -> %s, start callback\n",
|
||||
lp->name, nr, eaz);
|
||||
p->dev->name, nr, eaz);
|
||||
if (lp->phone[1]) {
|
||||
/* Grab a free ISDN-Channel */
|
||||
spin_lock_irqsave(&dev->lock, flags);
|
||||
@ -2340,7 +2342,8 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
|
||||
lp->msn)
|
||||
) < 0) {
|
||||
|
||||
printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n", lp->name);
|
||||
printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n",
|
||||
p->dev->name);
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
@ -2361,11 +2364,12 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
|
||||
/* Initiate dialing by returning 2 or 4 */
|
||||
return (lp->flags & ISDN_NET_CBHUP) ? 2 : 4;
|
||||
} else
|
||||
printk(KERN_WARNING "isdn_net: %s: No phone number\n", lp->name);
|
||||
printk(KERN_WARNING "isdn_net: %s: No phone number\n",
|
||||
p->dev->name);
|
||||
return 0;
|
||||
} else {
|
||||
printk(KERN_DEBUG "%s: call from %s -> %s accepted\n", lp->name, nr,
|
||||
eaz);
|
||||
printk(KERN_DEBUG "%s: call from %s -> %s accepted\n",
|
||||
p->dev->name, nr, eaz);
|
||||
/* if this interface is dialing, it does it probably on a different
|
||||
device, so free this device */
|
||||
if ((lp->dialstate == 4) || (lp->dialstate == 12)) {
|
||||
@ -2424,7 +2428,7 @@ isdn_net_findif(char *name)
|
||||
isdn_net_dev *p = dev->netdev;
|
||||
|
||||
while (p) {
|
||||
if (!strcmp(p->local->name, name))
|
||||
if (!strcmp(p->dev->name, name))
|
||||
return p;
|
||||
p = (isdn_net_dev *) p->next;
|
||||
}
|
||||
@ -2453,7 +2457,8 @@ isdn_net_force_dial_lp(isdn_net_local * lp)
|
||||
lp->pre_device,
|
||||
lp->pre_channel,
|
||||
lp->msn)) < 0) {
|
||||
printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n", lp->name);
|
||||
printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n",
|
||||
lp->netdev->dev->name);
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
return -EAGAIN;
|
||||
}
|
||||
@ -2556,7 +2561,7 @@ isdn_net_new(char *name, struct net_device *master)
|
||||
return NULL;
|
||||
}
|
||||
if (name == NULL)
|
||||
name = " ";
|
||||
return NULL;
|
||||
if (!(netdev = kzalloc(sizeof(isdn_net_dev), GFP_KERNEL))) {
|
||||
printk(KERN_WARNING "isdn_net: Could not allocate net-device\n");
|
||||
return NULL;
|
||||
@ -2568,7 +2573,6 @@ isdn_net_new(char *name, struct net_device *master)
|
||||
return NULL;
|
||||
}
|
||||
netdev->local = netdev->dev->priv;
|
||||
strcpy(netdev->local->name, netdev->dev->name);
|
||||
netdev->dev->init = isdn_net_init;
|
||||
if (master) {
|
||||
/* Device shall be a slave */
|
||||
@ -2673,7 +2677,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
|
||||
#endif
|
||||
if (isdn_net_device_started(p)) {
|
||||
printk(KERN_WARNING "%s: cannot change encap when if is up\n",
|
||||
lp->name);
|
||||
p->dev->name);
|
||||
return -EBUSY;
|
||||
}
|
||||
#ifdef CONFIG_ISDN_X25
|
||||
@ -2698,7 +2702,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
|
||||
case ISDN_NET_ENCAP_SYNCPPP:
|
||||
#ifndef CONFIG_ISDN_PPP
|
||||
printk(KERN_WARNING "%s: SyncPPP support not configured\n",
|
||||
lp->name);
|
||||
p->dev->name);
|
||||
return -EINVAL;
|
||||
#else
|
||||
p->dev->type = ARPHRD_PPP; /* change ARP type */
|
||||
@ -2709,7 +2713,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
|
||||
case ISDN_NET_ENCAP_X25IFACE:
|
||||
#ifndef CONFIG_ISDN_X25
|
||||
printk(KERN_WARNING "%s: isdn-x25 support not configured\n",
|
||||
p->local->name);
|
||||
p->dev->name);
|
||||
return -EINVAL;
|
||||
#else
|
||||
p->dev->type = ARPHRD_X25; /* change ARP type */
|
||||
@ -2725,7 +2729,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
|
||||
break;
|
||||
printk(KERN_WARNING
|
||||
"%s: encapsulation protocol %d not supported\n",
|
||||
p->local->name, cfg->p_encap);
|
||||
p->dev->name, cfg->p_encap);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (strlen(cfg->drvid)) {
|
||||
@ -2902,13 +2906,18 @@ isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
|
||||
cfg->pppbind = lp->pppbind;
|
||||
cfg->dialtimeout = lp->dialtimeout >= 0 ? lp->dialtimeout / HZ : -1;
|
||||
cfg->dialwait = lp->dialwait / HZ;
|
||||
if (lp->slave)
|
||||
strcpy(cfg->slave, ((isdn_net_local *) lp->slave->priv)->name);
|
||||
else
|
||||
if (lp->slave) {
|
||||
if (strlen(lp->slave->name) > 8)
|
||||
strcpy(cfg->slave, "too-long");
|
||||
else
|
||||
strcpy(cfg->slave, lp->slave->name);
|
||||
} else
|
||||
cfg->slave[0] = '\0';
|
||||
if (lp->master)
|
||||
strcpy(cfg->master, ((isdn_net_local *) lp->master->priv)->name);
|
||||
else
|
||||
if (lp->master) {
|
||||
if (strlen(lp->master->name) > 8)
|
||||
strcpy(cfg->master, "too-long");
|
||||
strcpy(cfg->master, lp->master->name);
|
||||
} else
|
||||
cfg->master[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
@ -2978,7 +2987,8 @@ isdn_net_getpeer(isdn_net_ioctl_phone *phone, isdn_net_ioctl_phone __user *peer)
|
||||
isdn_net_dev *p = isdn_net_findif(phone->name);
|
||||
int ch, dv, idx;
|
||||
|
||||
if (!p) return -ENODEV;
|
||||
if (!p)
|
||||
return -ENODEV;
|
||||
/*
|
||||
* Theoretical race: while this executes, the remote number might
|
||||
* become invalid (hang up) or change (new connection), resulting
|
||||
@ -2987,14 +2997,18 @@ isdn_net_getpeer(isdn_net_ioctl_phone *phone, isdn_net_ioctl_phone __user *peer)
|
||||
*/
|
||||
ch = p->local->isdn_channel;
|
||||
dv = p->local->isdn_device;
|
||||
if(ch<0 && dv<0) return -ENOTCONN;
|
||||
if(ch < 0 && dv < 0)
|
||||
return -ENOTCONN;
|
||||
idx = isdn_dc2minor(dv, ch);
|
||||
if (idx<0) return -ENODEV;
|
||||
if (idx <0 )
|
||||
return -ENODEV;
|
||||
/* for pre-bound channels, we need this extra check */
|
||||
if ( strncmp(dev->num[idx],"???",3) == 0 ) return -ENOTCONN;
|
||||
strncpy(phone->phone,dev->num[idx],ISDN_MSNLEN);
|
||||
phone->outgoing=USG_OUTGOING(dev->usage[idx]);
|
||||
if ( copy_to_user(peer,phone,sizeof(*peer)) ) return -EFAULT;
|
||||
if (strncmp(dev->num[idx], "???", 3) == 0)
|
||||
return -ENOTCONN;
|
||||
strncpy(phone->phone, dev->num[idx], ISDN_MSNLEN);
|
||||
phone->outgoing = USG_OUTGOING(dev->usage[idx]);
|
||||
if (copy_to_user(peer, phone, sizeof(*peer)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
@ -3113,18 +3127,18 @@ isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q)
|
||||
dev->netdev = p->next;
|
||||
if (p->local->slave) {
|
||||
/* If this interface has a slave, remove it also */
|
||||
char *slavename = ((isdn_net_local *) (p->local->slave->priv))->name;
|
||||
char *slavename = p->local->slave->name;
|
||||
isdn_net_dev *n = dev->netdev;
|
||||
q = NULL;
|
||||
while (n) {
|
||||
if (!strcmp(n->local->name, slavename)) {
|
||||
if (!strcmp(n->dev->name, slavename)) {
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
isdn_net_realrm(n, q);
|
||||
spin_lock_irqsave(&dev->lock, flags);
|
||||
break;
|
||||
}
|
||||
q = n;
|
||||
n = (isdn_net_dev *) n->next;
|
||||
n = (isdn_net_dev *)n->next;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
@ -3152,7 +3166,7 @@ isdn_net_rm(char *name)
|
||||
p = dev->netdev;
|
||||
q = NULL;
|
||||
while (p) {
|
||||
if (!strcmp(p->local->name, name)) {
|
||||
if (!strcmp(p->dev->name, name)) {
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
return (isdn_net_realrm(p, q));
|
||||
}
|
||||
|
@ -190,9 +190,11 @@ isdn_ppp_bind(isdn_net_local * lp)
|
||||
retval = -1;
|
||||
goto out;
|
||||
}
|
||||
unit = isdn_ppp_if_get_unit(lp->name); /* get unit number from interface name .. ugly! */
|
||||
/* get unit number from interface name .. ugly! */
|
||||
unit = isdn_ppp_if_get_unit(lp->netdev->dev->name);
|
||||
if (unit < 0) {
|
||||
printk(KERN_ERR "isdn_ppp_bind: illegal interface name %s.\n", lp->name);
|
||||
printk(KERN_ERR "isdn_ppp_bind: illegal interface name %s.\n",
|
||||
lp->netdev->dev->name);
|
||||
retval = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -507,7 +509,8 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
|
||||
case PPPIOCGIFNAME:
|
||||
if(!lp)
|
||||
return -EINVAL;
|
||||
if ((r = set_arg(argp, lp->name, strlen(lp->name))))
|
||||
if ((r = set_arg(argp, lp->netdev->dev->name,
|
||||
strlen(lp->netdev->dev->name))))
|
||||
return r;
|
||||
break;
|
||||
case PPPIOCGMPFLAGS: /* get configuration flags */
|
||||
|
@ -265,17 +265,16 @@ static __net_init int loopback_net_init(struct net *net)
|
||||
if (err)
|
||||
goto out_free_netdev;
|
||||
|
||||
err = 0;
|
||||
net->loopback_dev = dev;
|
||||
return 0;
|
||||
|
||||
out:
|
||||
if (err)
|
||||
panic("loopback: Failed to register netdevice: %d\n", err);
|
||||
return err;
|
||||
|
||||
out_free_netdev:
|
||||
free_netdev(dev);
|
||||
goto out;
|
||||
out:
|
||||
if (net == &init_net)
|
||||
panic("loopback: Failed to register netdevice: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
static __net_exit void loopback_net_exit(struct net *net)
|
||||
|
@ -6123,19 +6123,19 @@ static int __devinit niu_pci_probe_sprom(struct niu *np)
|
||||
val = nr64(ESPC_PHY_TYPE);
|
||||
switch (np->port) {
|
||||
case 0:
|
||||
val = (val & ESPC_PHY_TYPE_PORT0) >>
|
||||
val8 = (val & ESPC_PHY_TYPE_PORT0) >>
|
||||
ESPC_PHY_TYPE_PORT0_SHIFT;
|
||||
break;
|
||||
case 1:
|
||||
val = (val & ESPC_PHY_TYPE_PORT1) >>
|
||||
val8 = (val & ESPC_PHY_TYPE_PORT1) >>
|
||||
ESPC_PHY_TYPE_PORT1_SHIFT;
|
||||
break;
|
||||
case 2:
|
||||
val = (val & ESPC_PHY_TYPE_PORT2) >>
|
||||
val8 = (val & ESPC_PHY_TYPE_PORT2) >>
|
||||
ESPC_PHY_TYPE_PORT2_SHIFT;
|
||||
break;
|
||||
case 3:
|
||||
val = (val & ESPC_PHY_TYPE_PORT3) >>
|
||||
val8 = (val & ESPC_PHY_TYPE_PORT3) >>
|
||||
ESPC_PHY_TYPE_PORT3_SHIFT;
|
||||
break;
|
||||
default:
|
||||
@ -6143,9 +6143,9 @@ static int __devinit niu_pci_probe_sprom(struct niu *np)
|
||||
np->port);
|
||||
return -EINVAL;
|
||||
}
|
||||
niudbg(PROBE, "SPROM: PHY type %llx\n", (unsigned long long) val);
|
||||
niudbg(PROBE, "SPROM: PHY type %x\n", val8);
|
||||
|
||||
switch (val) {
|
||||
switch (val8) {
|
||||
case ESPC_PHY_TYPE_1G_COPPER:
|
||||
/* 1G copper, MII */
|
||||
np->flags &= ~(NIU_FLAGS_FIBER |
|
||||
@ -6175,8 +6175,7 @@ static int __devinit niu_pci_probe_sprom(struct niu *np)
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(np->device, PFX "Bogus SPROM phy type %llu\n",
|
||||
(unsigned long long) val);
|
||||
dev_err(np->device, PFX "Bogus SPROM phy type %u\n", val8);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -6213,7 +6212,7 @@ static int __devinit niu_pci_probe_sprom(struct niu *np)
|
||||
val = nr64(ESPC_MOD_STR_LEN);
|
||||
niudbg(PROBE, "SPROM: MOD_STR_LEN[%llu]\n",
|
||||
(unsigned long long) val);
|
||||
if (val > 8 * 4)
|
||||
if (val >= 8 * 4)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < val; i += 4) {
|
||||
@ -6229,7 +6228,7 @@ static int __devinit niu_pci_probe_sprom(struct niu *np)
|
||||
val = nr64(ESPC_BD_MOD_STR_LEN);
|
||||
niudbg(PROBE, "SPROM: BD_MOD_STR_LEN[%llu]\n",
|
||||
(unsigned long long) val);
|
||||
if (val > 4 * 4)
|
||||
if (val >= 4 * 4)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < val; i += 4) {
|
||||
|
@ -64,8 +64,8 @@
|
||||
|
||||
#define DRV_MODULE_NAME "tg3"
|
||||
#define PFX DRV_MODULE_NAME ": "
|
||||
#define DRV_MODULE_VERSION "3.83"
|
||||
#define DRV_MODULE_RELDATE "October 10, 2007"
|
||||
#define DRV_MODULE_VERSION "3.84"
|
||||
#define DRV_MODULE_RELDATE "October 12, 2007"
|
||||
|
||||
#define TG3_DEF_MAC_MODE 0
|
||||
#define TG3_DEF_RX_MODE 0
|
||||
@ -5056,6 +5056,12 @@ static void tg3_restore_pci_state(struct tg3 *tp)
|
||||
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_COMMAND, tp->pci_cmd);
|
||||
|
||||
if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) {
|
||||
pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
|
||||
tp->pci_cacheline_sz);
|
||||
pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER,
|
||||
tp->pci_lat_timer);
|
||||
}
|
||||
/* Make sure PCI-X relaxed ordering bit is clear. */
|
||||
if (tp->pcix_cap) {
|
||||
u16 pcix_cmd;
|
||||
|
@ -107,7 +107,7 @@ struct __fdb_entry
|
||||
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
|
||||
extern struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
|
||||
struct sk_buff *skb);
|
||||
extern int (*br_should_route_hook)(struct sk_buff **pskb);
|
||||
extern int (*br_should_route_hook)(struct sk_buff *skb);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -286,7 +286,6 @@ typedef struct {
|
||||
/* Local interface-data */
|
||||
typedef struct isdn_net_local_s {
|
||||
ulong magic;
|
||||
char name[10]; /* Name of device */
|
||||
struct net_device_stats stats; /* Ethernet Statistics */
|
||||
int isdn_device; /* Index to isdn-device */
|
||||
int isdn_channel; /* Index to isdn-channel */
|
||||
|
@ -51,7 +51,7 @@ struct sk_buff;
|
||||
struct net_device;
|
||||
|
||||
typedef unsigned int nf_hookfn(unsigned int hooknum,
|
||||
struct sk_buff **skb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *));
|
||||
@ -183,7 +183,7 @@ void nf_log_packet(int pf,
|
||||
struct nf_loginfo *li,
|
||||
const char *fmt, ...);
|
||||
|
||||
int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
|
||||
int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
|
||||
struct net_device *indev, struct net_device *outdev,
|
||||
int (*okfn)(struct sk_buff *), int thresh);
|
||||
|
||||
@ -195,7 +195,7 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
|
||||
* value indicates the packet has been consumed by the hook.
|
||||
*/
|
||||
static inline int nf_hook_thresh(int pf, unsigned int hook,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
struct net_device *indev,
|
||||
struct net_device *outdev,
|
||||
int (*okfn)(struct sk_buff *), int thresh,
|
||||
@ -207,14 +207,14 @@ static inline int nf_hook_thresh(int pf, unsigned int hook,
|
||||
if (list_empty(&nf_hooks[pf][hook]))
|
||||
return 1;
|
||||
#endif
|
||||
return nf_hook_slow(pf, hook, pskb, indev, outdev, okfn, thresh);
|
||||
return nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh);
|
||||
}
|
||||
|
||||
static inline int nf_hook(int pf, unsigned int hook, struct sk_buff **pskb,
|
||||
static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb,
|
||||
struct net_device *indev, struct net_device *outdev,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return nf_hook_thresh(pf, hook, pskb, indev, outdev, okfn, INT_MIN, 1);
|
||||
return nf_hook_thresh(pf, hook, skb, indev, outdev, okfn, INT_MIN, 1);
|
||||
}
|
||||
|
||||
/* Activate hook; either okfn or kfree_skb called, unless a hook
|
||||
@ -241,13 +241,13 @@ static inline int nf_hook(int pf, unsigned int hook, struct sk_buff **pskb,
|
||||
|
||||
#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \
|
||||
({int __ret; \
|
||||
if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, thresh, 1)) == 1)\
|
||||
if ((__ret=nf_hook_thresh(pf, hook, (skb), indev, outdev, okfn, thresh, 1)) == 1)\
|
||||
__ret = (okfn)(skb); \
|
||||
__ret;})
|
||||
|
||||
#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) \
|
||||
({int __ret; \
|
||||
if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, INT_MIN, cond)) == 1)\
|
||||
if ((__ret=nf_hook_thresh(pf, hook, (skb), indev, outdev, okfn, INT_MIN, cond)) == 1)\
|
||||
__ret = (okfn)(skb); \
|
||||
__ret;})
|
||||
|
||||
@ -287,7 +287,7 @@ extern void nf_invalidate_cache(int pf);
|
||||
/* Call this before modifying an existing packet: ensures it is
|
||||
modifiable and linear to the point you care about (writable_len).
|
||||
Returns true or false. */
|
||||
extern int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len);
|
||||
extern int skb_make_writable(struct sk_buff *skb, unsigned int writable_len);
|
||||
|
||||
static inline void nf_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
|
||||
{
|
||||
@ -317,7 +317,7 @@ struct nf_afinfo {
|
||||
unsigned int dataoff, u_int8_t protocol);
|
||||
void (*saveroute)(const struct sk_buff *skb,
|
||||
struct nf_info *info);
|
||||
int (*reroute)(struct sk_buff **skb,
|
||||
int (*reroute)(struct sk_buff *skb,
|
||||
const struct nf_info *info);
|
||||
int route_key_size;
|
||||
};
|
||||
@ -371,15 +371,15 @@ extern struct proc_dir_entry *proc_net_netfilter;
|
||||
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
|
||||
#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
|
||||
static inline int nf_hook_thresh(int pf, unsigned int hook,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
struct net_device *indev,
|
||||
struct net_device *outdev,
|
||||
int (*okfn)(struct sk_buff *), int thresh,
|
||||
int cond)
|
||||
{
|
||||
return okfn(*pskb);
|
||||
return okfn(skb);
|
||||
}
|
||||
static inline int nf_hook(int pf, unsigned int hook, struct sk_buff **pskb,
|
||||
static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb,
|
||||
struct net_device *indev, struct net_device *outdev,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define _NF_CONNTRACK_AMANDA_H
|
||||
/* AMANDA tracking. */
|
||||
|
||||
extern unsigned int (*nf_nat_amanda_hook)(struct sk_buff **pskb,
|
||||
extern unsigned int (*nf_nat_amanda_hook)(struct sk_buff *skb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int matchoff,
|
||||
unsigned int matchlen,
|
||||
|
@ -32,7 +32,7 @@ struct nf_conntrack_expect;
|
||||
|
||||
/* For NAT to hook in when we find a packet which describes what other
|
||||
* connection we should expect. */
|
||||
extern unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
|
||||
extern unsigned int (*nf_nat_ftp_hook)(struct sk_buff *skb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
enum nf_ct_ftp_type type,
|
||||
unsigned int matchoff,
|
||||
|
@ -36,27 +36,27 @@ extern void nf_conntrack_h245_expect(struct nf_conn *new,
|
||||
struct nf_conntrack_expect *this);
|
||||
extern void nf_conntrack_q931_expect(struct nf_conn *new,
|
||||
struct nf_conntrack_expect *this);
|
||||
extern int (*set_h245_addr_hook) (struct sk_buff **pskb,
|
||||
extern int (*set_h245_addr_hook) (struct sk_buff *skb,
|
||||
unsigned char **data, int dataoff,
|
||||
H245_TransportAddress *taddr,
|
||||
union nf_conntrack_address *addr,
|
||||
__be16 port);
|
||||
extern int (*set_h225_addr_hook) (struct sk_buff **pskb,
|
||||
extern int (*set_h225_addr_hook) (struct sk_buff *skb,
|
||||
unsigned char **data, int dataoff,
|
||||
TransportAddress *taddr,
|
||||
union nf_conntrack_address *addr,
|
||||
__be16 port);
|
||||
extern int (*set_sig_addr_hook) (struct sk_buff **pskb,
|
||||
extern int (*set_sig_addr_hook) (struct sk_buff *skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data,
|
||||
TransportAddress *taddr, int count);
|
||||
extern int (*set_ras_addr_hook) (struct sk_buff **pskb,
|
||||
extern int (*set_ras_addr_hook) (struct sk_buff *skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data,
|
||||
TransportAddress *taddr, int count);
|
||||
extern int (*nat_rtp_rtcp_hook) (struct sk_buff **pskb,
|
||||
extern int (*nat_rtp_rtcp_hook) (struct sk_buff *skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data, int dataoff,
|
||||
@ -64,24 +64,24 @@ extern int (*nat_rtp_rtcp_hook) (struct sk_buff **pskb,
|
||||
__be16 port, __be16 rtp_port,
|
||||
struct nf_conntrack_expect *rtp_exp,
|
||||
struct nf_conntrack_expect *rtcp_exp);
|
||||
extern int (*nat_t120_hook) (struct sk_buff **pskb, struct nf_conn *ct,
|
||||
extern int (*nat_t120_hook) (struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data, int dataoff,
|
||||
H245_TransportAddress *taddr, __be16 port,
|
||||
struct nf_conntrack_expect *exp);
|
||||
extern int (*nat_h245_hook) (struct sk_buff **pskb, struct nf_conn *ct,
|
||||
extern int (*nat_h245_hook) (struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data, int dataoff,
|
||||
TransportAddress *taddr, __be16 port,
|
||||
struct nf_conntrack_expect *exp);
|
||||
extern int (*nat_callforwarding_hook) (struct sk_buff **pskb,
|
||||
extern int (*nat_callforwarding_hook) (struct sk_buff *skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data, int dataoff,
|
||||
TransportAddress *taddr,
|
||||
__be16 port,
|
||||
struct nf_conntrack_expect *exp);
|
||||
extern int (*nat_q931_hook) (struct sk_buff **pskb, struct nf_conn *ct,
|
||||
extern int (*nat_q931_hook) (struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data, TransportAddress *taddr,
|
||||
int idx, __be16 port,
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#define IRC_PORT 6667
|
||||
|
||||
extern unsigned int (*nf_nat_irc_hook)(struct sk_buff **pskb,
|
||||
extern unsigned int (*nf_nat_irc_hook)(struct sk_buff *skb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int matchoff,
|
||||
unsigned int matchlen,
|
||||
|
@ -301,13 +301,13 @@ struct nf_conn;
|
||||
struct nf_conntrack_expect;
|
||||
|
||||
extern int
|
||||
(*nf_nat_pptp_hook_outbound)(struct sk_buff **pskb,
|
||||
(*nf_nat_pptp_hook_outbound)(struct sk_buff *skb,
|
||||
struct nf_conn *ct, enum ip_conntrack_info ctinfo,
|
||||
struct PptpControlHeader *ctlh,
|
||||
union pptp_ctrl_union *pptpReq);
|
||||
|
||||
extern int
|
||||
(*nf_nat_pptp_hook_inbound)(struct sk_buff **pskb,
|
||||
(*nf_nat_pptp_hook_inbound)(struct sk_buff *skb,
|
||||
struct nf_conn *ct, enum ip_conntrack_info ctinfo,
|
||||
struct PptpControlHeader *ctlh,
|
||||
union pptp_ctrl_union *pptpReq);
|
||||
|
@ -21,11 +21,11 @@ enum sip_header_pos {
|
||||
POS_SDP_HEADER,
|
||||
};
|
||||
|
||||
extern unsigned int (*nf_nat_sip_hook)(struct sk_buff **pskb,
|
||||
extern unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
struct nf_conn *ct,
|
||||
const char **dptr);
|
||||
extern unsigned int (*nf_nat_sdp_hook)(struct sk_buff **pskb,
|
||||
extern unsigned int (*nf_nat_sdp_hook)(struct sk_buff *skb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
struct nf_conntrack_expect *exp,
|
||||
const char *dptr);
|
||||
|
@ -13,7 +13,7 @@ struct tftphdr {
|
||||
#define TFTP_OPCODE_ACK 4
|
||||
#define TFTP_OPCODE_ERROR 5
|
||||
|
||||
extern unsigned int (*nf_nat_tftp_hook)(struct sk_buff **pskb,
|
||||
extern unsigned int (*nf_nat_tftp_hook)(struct sk_buff *skb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
struct nf_conntrack_expect *exp);
|
||||
|
||||
|
@ -191,7 +191,7 @@ struct xt_target
|
||||
/* Returns verdict. Argument order changed since 2.6.9, as this
|
||||
must now handle non-linear skbs, using skb_copy_bits and
|
||||
skb_ip_make_writable. */
|
||||
unsigned int (*target)(struct sk_buff **pskb,
|
||||
unsigned int (*target)(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
|
@ -287,7 +287,7 @@ struct arpt_error
|
||||
extern int arpt_register_table(struct arpt_table *table,
|
||||
const struct arpt_replace *repl);
|
||||
extern void arpt_unregister_table(struct arpt_table *table);
|
||||
extern unsigned int arpt_do_table(struct sk_buff **pskb,
|
||||
extern unsigned int arpt_do_table(struct sk_buff *skb,
|
||||
unsigned int hook,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
|
@ -237,7 +237,7 @@ struct ebt_target
|
||||
struct list_head list;
|
||||
const char name[EBT_FUNCTION_MAXNAMELEN];
|
||||
/* returns one of the standard verdicts */
|
||||
int (*target)(struct sk_buff **pskb, unsigned int hooknr,
|
||||
int (*target)(struct sk_buff *skb, unsigned int hooknr,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
const void *targetdata, unsigned int datalen);
|
||||
/* 0 == let it in */
|
||||
@ -294,7 +294,7 @@ extern int ebt_register_watcher(struct ebt_watcher *watcher);
|
||||
extern void ebt_unregister_watcher(struct ebt_watcher *watcher);
|
||||
extern int ebt_register_target(struct ebt_target *target);
|
||||
extern void ebt_unregister_target(struct ebt_target *target);
|
||||
extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff **pskb,
|
||||
extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
struct ebt_table *table);
|
||||
|
||||
|
@ -75,8 +75,8 @@ enum nf_ip_hook_priorities {
|
||||
#define SO_ORIGINAL_DST 80
|
||||
|
||||
#ifdef __KERNEL__
|
||||
extern int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type);
|
||||
extern int ip_xfrm_me_harder(struct sk_buff **pskb);
|
||||
extern int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type);
|
||||
extern int ip_xfrm_me_harder(struct sk_buff *skb);
|
||||
extern __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
|
||||
unsigned int dataoff, u_int8_t protocol);
|
||||
#endif /*__KERNEL__*/
|
||||
|
@ -337,7 +337,7 @@ struct ipt_error
|
||||
.target.errorname = "ERROR", \
|
||||
}
|
||||
|
||||
extern unsigned int ipt_do_table(struct sk_buff **pskb,
|
||||
extern unsigned int ipt_do_table(struct sk_buff *skb,
|
||||
unsigned int hook,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
|
@ -336,7 +336,7 @@ extern void ip6t_init(void) __init;
|
||||
extern int ip6t_register_table(struct xt_table *table,
|
||||
const struct ip6t_replace *repl);
|
||||
extern void ip6t_unregister_table(struct xt_table *table);
|
||||
extern unsigned int ip6t_do_table(struct sk_buff **pskb,
|
||||
extern unsigned int ip6t_do_table(struct sk_buff *skb,
|
||||
unsigned int hook,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
|
@ -357,6 +357,7 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size,
|
||||
}
|
||||
|
||||
extern void kfree_skbmem(struct sk_buff *skb);
|
||||
extern struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src);
|
||||
extern struct sk_buff *skb_clone(struct sk_buff *skb,
|
||||
gfp_t priority);
|
||||
extern struct sk_buff *skb_copy(const struct sk_buff *skb,
|
||||
|
@ -315,7 +315,7 @@ struct tcp_sock {
|
||||
*/
|
||||
u32 snd_ssthresh; /* Slow start size threshold */
|
||||
u32 snd_cwnd; /* Sending congestion window */
|
||||
u16 snd_cwnd_cnt; /* Linear increase counter */
|
||||
u32 snd_cwnd_cnt; /* Linear increase counter */
|
||||
u32 snd_cwnd_clamp; /* Do not allow snd_cwnd to grow above this */
|
||||
u32 snd_cwnd_used;
|
||||
u32 snd_cwnd_stamp;
|
||||
|
60
include/net/inet_frag.h
Normal file
60
include/net/inet_frag.h
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef __NET_FRAG_H__
|
||||
#define __NET_FRAG_H__
|
||||
|
||||
struct inet_frag_queue {
|
||||
struct hlist_node list;
|
||||
struct list_head lru_list; /* lru list member */
|
||||
spinlock_t lock;
|
||||
atomic_t refcnt;
|
||||
struct timer_list timer; /* when will this queue expire? */
|
||||
struct sk_buff *fragments; /* list of received fragments */
|
||||
ktime_t stamp;
|
||||
int len; /* total length of orig datagram */
|
||||
int meat;
|
||||
__u8 last_in; /* first/last segment arrived? */
|
||||
|
||||
#define COMPLETE 4
|
||||
#define FIRST_IN 2
|
||||
#define LAST_IN 1
|
||||
};
|
||||
|
||||
#define INETFRAGS_HASHSZ 64
|
||||
|
||||
struct inet_frags_ctl {
|
||||
int high_thresh;
|
||||
int low_thresh;
|
||||
int timeout;
|
||||
int secret_interval;
|
||||
};
|
||||
|
||||
struct inet_frags {
|
||||
struct list_head lru_list;
|
||||
struct hlist_head hash[INETFRAGS_HASHSZ];
|
||||
rwlock_t lock;
|
||||
u32 rnd;
|
||||
int nqueues;
|
||||
int qsize;
|
||||
atomic_t mem;
|
||||
struct timer_list secret_timer;
|
||||
struct inet_frags_ctl *ctl;
|
||||
|
||||
unsigned int (*hashfn)(struct inet_frag_queue *);
|
||||
void (*destructor)(struct inet_frag_queue *);
|
||||
void (*skb_free)(struct sk_buff *);
|
||||
};
|
||||
|
||||
void inet_frags_init(struct inet_frags *);
|
||||
void inet_frags_fini(struct inet_frags *);
|
||||
|
||||
void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
|
||||
void inet_frag_destroy(struct inet_frag_queue *q,
|
||||
struct inet_frags *f, int *work);
|
||||
int inet_frag_evictor(struct inet_frags *f);
|
||||
|
||||
static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
|
||||
{
|
||||
if (atomic_dec_and_test(&q->refcnt))
|
||||
inet_frag_destroy(q, f, NULL);
|
||||
}
|
||||
|
||||
#endif
|
@ -160,6 +160,7 @@ DECLARE_SNMP_STAT(struct ipstats_mib, ip_statistics);
|
||||
#define IP_INC_STATS(field) SNMP_INC_STATS(ip_statistics, field)
|
||||
#define IP_INC_STATS_BH(field) SNMP_INC_STATS_BH(ip_statistics, field)
|
||||
#define IP_INC_STATS_USER(field) SNMP_INC_STATS_USER(ip_statistics, field)
|
||||
#define IP_ADD_STATS_BH(field, val) SNMP_ADD_STATS_BH(ip_statistics, field, val)
|
||||
DECLARE_SNMP_STAT(struct linux_mib, net_statistics);
|
||||
#define NET_INC_STATS(field) SNMP_INC_STATS(net_statistics, field)
|
||||
#define NET_INC_STATS_BH(field) SNMP_INC_STATS_BH(net_statistics, field)
|
||||
@ -177,10 +178,8 @@ extern int sysctl_ip_default_ttl;
|
||||
extern int sysctl_ip_nonlocal_bind;
|
||||
|
||||
/* From ip_fragment.c */
|
||||
extern int sysctl_ipfrag_high_thresh;
|
||||
extern int sysctl_ipfrag_low_thresh;
|
||||
extern int sysctl_ipfrag_time;
|
||||
extern int sysctl_ipfrag_secret_interval;
|
||||
struct inet_frags_ctl;
|
||||
extern struct inet_frags_ctl ip4_frags_ctl;
|
||||
extern int sysctl_ipfrag_max_dist;
|
||||
|
||||
/* From inetpeer.c */
|
||||
@ -332,9 +331,9 @@ enum ip_defrag_users
|
||||
IP_DEFRAG_VS_FWD
|
||||
};
|
||||
|
||||
struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user);
|
||||
extern int ip_frag_nqueues;
|
||||
extern atomic_t ip_frag_mem;
|
||||
int ip_defrag(struct sk_buff *skb, u32 user);
|
||||
int ip_frag_mem(void);
|
||||
int ip_frag_nqueues(void);
|
||||
|
||||
/*
|
||||
* Functions provided by ip_forward.c
|
||||
|
@ -464,10 +464,10 @@ struct ip_vs_protocol {
|
||||
unsigned int proto_off,
|
||||
int inverse);
|
||||
|
||||
int (*snat_handler)(struct sk_buff **pskb,
|
||||
int (*snat_handler)(struct sk_buff *skb,
|
||||
struct ip_vs_protocol *pp, struct ip_vs_conn *cp);
|
||||
|
||||
int (*dnat_handler)(struct sk_buff **pskb,
|
||||
int (*dnat_handler)(struct sk_buff *skb,
|
||||
struct ip_vs_protocol *pp, struct ip_vs_conn *cp);
|
||||
|
||||
int (*csum_check)(struct sk_buff *skb, struct ip_vs_protocol *pp);
|
||||
@ -654,11 +654,11 @@ struct ip_vs_app
|
||||
|
||||
/* output hook: return false if can't linearize. diff set for TCP. */
|
||||
int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *,
|
||||
struct sk_buff **, int *diff);
|
||||
struct sk_buff *, int *diff);
|
||||
|
||||
/* input hook: return false if can't linearize. diff set for TCP. */
|
||||
int (*pkt_in)(struct ip_vs_app *, struct ip_vs_conn *,
|
||||
struct sk_buff **, int *diff);
|
||||
struct sk_buff *, int *diff);
|
||||
|
||||
/* ip_vs_app initializer */
|
||||
int (*init_conn)(struct ip_vs_app *, struct ip_vs_conn *);
|
||||
@ -832,8 +832,8 @@ register_ip_vs_app_inc(struct ip_vs_app *app, __u16 proto, __u16 port);
|
||||
extern int ip_vs_app_inc_get(struct ip_vs_app *inc);
|
||||
extern void ip_vs_app_inc_put(struct ip_vs_app *inc);
|
||||
|
||||
extern int ip_vs_app_pkt_out(struct ip_vs_conn *, struct sk_buff **pskb);
|
||||
extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff **pskb);
|
||||
extern int ip_vs_app_pkt_out(struct ip_vs_conn *, struct sk_buff *skb);
|
||||
extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff *skb);
|
||||
extern int ip_vs_skb_replace(struct sk_buff *skb, gfp_t pri,
|
||||
char *o_buf, int o_len, char *n_buf, int n_len);
|
||||
extern int ip_vs_app_init(void);
|
||||
@ -984,7 +984,6 @@ static inline char ip_vs_fwd_tag(struct ip_vs_conn *cp)
|
||||
return fwd;
|
||||
}
|
||||
|
||||
extern int ip_vs_make_skb_writable(struct sk_buff **pskb, int len);
|
||||
extern void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
|
||||
struct ip_vs_conn *cp, int dir);
|
||||
|
||||
|
@ -120,12 +120,21 @@ extern int sysctl_mld_max_msf;
|
||||
SNMP_INC_STATS##modifier(statname##_statistics, (field)); \
|
||||
})
|
||||
|
||||
#define _DEVADD(statname, modifier, idev, field, val) \
|
||||
({ \
|
||||
struct inet6_dev *_idev = (idev); \
|
||||
if (likely(_idev != NULL)) \
|
||||
SNMP_ADD_STATS##modifier((_idev)->stats.statname, (field), (val)); \
|
||||
SNMP_ADD_STATS##modifier(statname##_statistics, (field), (val));\
|
||||
})
|
||||
|
||||
/* MIBs */
|
||||
DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics);
|
||||
|
||||
#define IP6_INC_STATS(idev,field) _DEVINC(ipv6, , idev, field)
|
||||
#define IP6_INC_STATS_BH(idev,field) _DEVINC(ipv6, _BH, idev, field)
|
||||
#define IP6_INC_STATS_USER(idev,field) _DEVINC(ipv6, _USER, idev, field)
|
||||
#define IP6_ADD_STATS_BH(idev,field,val) _DEVADD(ipv6, _BH, idev, field, val)
|
||||
|
||||
DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics);
|
||||
DECLARE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics);
|
||||
@ -240,7 +249,7 @@ extern int ip6_ra_control(struct sock *sk, int sel,
|
||||
void (*destructor)(struct sock *));
|
||||
|
||||
|
||||
extern int ipv6_parse_hopopts(struct sk_buff **skbp);
|
||||
extern int ipv6_parse_hopopts(struct sk_buff *skb);
|
||||
|
||||
extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
|
||||
extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
|
||||
@ -252,8 +261,8 @@ struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
|
||||
|
||||
extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb);
|
||||
|
||||
extern int ip6_frag_nqueues;
|
||||
extern atomic_t ip6_frag_mem;
|
||||
int ip6_frag_nqueues(void);
|
||||
int ip6_frag_mem(void);
|
||||
|
||||
#define IPV6_FRAG_TIMEOUT (60*HZ) /* 60 seconds */
|
||||
|
||||
@ -565,10 +574,8 @@ extern int inet6_hash_connect(struct inet_timewait_death_row *death_row,
|
||||
/*
|
||||
* reassembly.c
|
||||
*/
|
||||
extern int sysctl_ip6frag_high_thresh;
|
||||
extern int sysctl_ip6frag_low_thresh;
|
||||
extern int sysctl_ip6frag_time;
|
||||
extern int sysctl_ip6frag_secret_interval;
|
||||
struct inet_frags_ctl;
|
||||
extern struct inet_frags_ctl ip6_frags_ctl;
|
||||
|
||||
extern const struct proto_ops inet6_stream_ops;
|
||||
extern const struct proto_ops inet6_dgram_ops;
|
||||
|
@ -15,8 +15,7 @@ extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
|
||||
struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *));
|
||||
|
||||
extern unsigned int nf_ct_frag6_timeout;
|
||||
extern unsigned int nf_ct_frag6_low_thresh;
|
||||
extern unsigned int nf_ct_frag6_high_thresh;
|
||||
struct inet_frags_ctl;
|
||||
extern struct inet_frags_ctl nf_frags_ctl;
|
||||
|
||||
#endif /* _NF_CONNTRACK_IPV6_H*/
|
||||
|
@ -22,7 +22,7 @@
|
||||
of connection tracking. */
|
||||
extern unsigned int nf_conntrack_in(int pf,
|
||||
unsigned int hooknum,
|
||||
struct sk_buff **pskb);
|
||||
struct sk_buff *skb);
|
||||
|
||||
extern int nf_conntrack_init(void);
|
||||
extern void nf_conntrack_cleanup(void);
|
||||
@ -60,17 +60,17 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
|
||||
extern struct nf_conntrack_tuple_hash *
|
||||
nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple);
|
||||
|
||||
extern int __nf_conntrack_confirm(struct sk_buff **pskb);
|
||||
extern int __nf_conntrack_confirm(struct sk_buff *skb);
|
||||
|
||||
/* Confirm a connection: returns NF_DROP if packet must be dropped. */
|
||||
static inline int nf_conntrack_confirm(struct sk_buff **pskb)
|
||||
static inline int nf_conntrack_confirm(struct sk_buff *skb)
|
||||
{
|
||||
struct nf_conn *ct = (struct nf_conn *)(*pskb)->nfct;
|
||||
struct nf_conn *ct = (struct nf_conn *)skb->nfct;
|
||||
int ret = NF_ACCEPT;
|
||||
|
||||
if (ct) {
|
||||
if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
|
||||
ret = __nf_conntrack_confirm(pskb);
|
||||
ret = __nf_conntrack_confirm(skb);
|
||||
nf_ct_deliver_cached_events(ct);
|
||||
}
|
||||
return ret;
|
||||
|
@ -29,7 +29,7 @@ struct nf_conntrack_helper
|
||||
|
||||
/* Function to call when data passes; return verdict, or -1 to
|
||||
invalidate. */
|
||||
int (*help)(struct sk_buff **pskb,
|
||||
int (*help)(struct sk_buff *skb,
|
||||
unsigned int protoff,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info conntrackinfo);
|
||||
|
@ -10,12 +10,12 @@
|
||||
extern unsigned int nf_nat_packet(struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int hooknum,
|
||||
struct sk_buff **pskb);
|
||||
struct sk_buff *skb);
|
||||
|
||||
extern int nf_nat_icmp_reply_translation(struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int hooknum,
|
||||
struct sk_buff **pskb);
|
||||
struct sk_buff *skb);
|
||||
|
||||
static inline int nf_nat_initialized(struct nf_conn *ct,
|
||||
enum nf_nat_manip_type manip)
|
||||
|
@ -7,21 +7,21 @@
|
||||
struct sk_buff;
|
||||
|
||||
/* These return true or false. */
|
||||
extern int nf_nat_mangle_tcp_packet(struct sk_buff **skb,
|
||||
extern int nf_nat_mangle_tcp_packet(struct sk_buff *skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int match_offset,
|
||||
unsigned int match_len,
|
||||
const char *rep_buffer,
|
||||
unsigned int rep_len);
|
||||
extern int nf_nat_mangle_udp_packet(struct sk_buff **skb,
|
||||
extern int nf_nat_mangle_udp_packet(struct sk_buff *skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int match_offset,
|
||||
unsigned int match_len,
|
||||
const char *rep_buffer,
|
||||
unsigned int rep_len);
|
||||
extern int nf_nat_seq_adjust(struct sk_buff **pskb,
|
||||
extern int nf_nat_seq_adjust(struct sk_buff *skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo);
|
||||
|
||||
|
@ -18,7 +18,7 @@ struct nf_nat_protocol
|
||||
|
||||
/* Translate a packet to the target according to manip type.
|
||||
Return true if succeeded. */
|
||||
int (*manip_pkt)(struct sk_buff **pskb,
|
||||
int (*manip_pkt)(struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype);
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
extern int nf_nat_rule_init(void) __init;
|
||||
extern void nf_nat_rule_cleanup(void);
|
||||
extern int nf_nat_rule_find(struct sk_buff **pskb,
|
||||
extern int nf_nat_rule_find(struct sk_buff *skb,
|
||||
unsigned int hooknum,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
|
@ -45,7 +45,7 @@ struct net_protocol {
|
||||
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
|
||||
struct inet6_protocol
|
||||
{
|
||||
int (*handler)(struct sk_buff **skb);
|
||||
int (*handler)(struct sk_buff *skb);
|
||||
|
||||
void (*err_handler)(struct sk_buff *skb,
|
||||
struct inet6_skb_parm *opt,
|
||||
|
@ -1051,7 +1051,7 @@ extern int xfrm4_output(struct sk_buff *skb);
|
||||
extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
|
||||
extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
|
||||
extern int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi);
|
||||
extern int xfrm6_rcv(struct sk_buff **pskb);
|
||||
extern int xfrm6_rcv(struct sk_buff *skb);
|
||||
extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
|
||||
xfrm_address_t *saddr, u8 proto);
|
||||
extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#include "br_private.h"
|
||||
|
||||
int (*br_should_route_hook) (struct sk_buff **pskb) = NULL;
|
||||
int (*br_should_route_hook)(struct sk_buff *skb);
|
||||
|
||||
static struct llc_sap *br_stp_sap;
|
||||
|
||||
|
@ -126,6 +126,10 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
|
||||
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
|
||||
goto drop;
|
||||
|
||||
skb = skb_share_check(skb, GFP_ATOMIC);
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
if (unlikely(is_link_local(dest))) {
|
||||
/* Pause frames shouldn't be passed up by driver anyway */
|
||||
if (skb->protocol == htons(ETH_P_PAUSE))
|
||||
@ -145,7 +149,7 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
|
||||
case BR_STATE_FORWARDING:
|
||||
|
||||
if (br_should_route_hook) {
|
||||
if (br_should_route_hook(&skb))
|
||||
if (br_should_route_hook(skb))
|
||||
return skb;
|
||||
dest = eth_hdr(skb)->h_dest;
|
||||
}
|
||||
|
@ -503,18 +503,14 @@ inhdr_error:
|
||||
* receiving device) to make netfilter happy, the REDIRECT
|
||||
* target in particular. Save the original destination IP
|
||||
* address to be able to detect DNAT afterwards. */
|
||||
static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
|
||||
static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
struct iphdr *iph;
|
||||
struct sk_buff *skb = *pskb;
|
||||
__u32 len = nf_bridge_encap_header_len(skb);
|
||||
|
||||
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
|
||||
return NF_STOLEN;
|
||||
|
||||
if (unlikely(!pskb_may_pull(skb, len)))
|
||||
goto out;
|
||||
|
||||
@ -584,13 +580,11 @@ out:
|
||||
* took place when the packet entered the bridge), but we
|
||||
* register an IPv4 PRE_ROUTING 'sabotage' hook that will
|
||||
* prevent this from happening. */
|
||||
static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff **pskb,
|
||||
static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
struct sk_buff *skb = *pskb;
|
||||
|
||||
if (skb->dst == (struct dst_entry *)&__fake_rtable) {
|
||||
dst_release(skb->dst);
|
||||
skb->dst = NULL;
|
||||
@ -625,12 +619,11 @@ static int br_nf_forward_finish(struct sk_buff *skb)
|
||||
* but we are still able to filter on the 'real' indev/outdev
|
||||
* because of the physdev module. For ARP, indev and outdev are the
|
||||
* bridge ports. */
|
||||
static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
|
||||
static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
struct sk_buff *skb = *pskb;
|
||||
struct nf_bridge_info *nf_bridge;
|
||||
struct net_device *parent;
|
||||
int pf;
|
||||
@ -648,7 +641,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
|
||||
else
|
||||
pf = PF_INET6;
|
||||
|
||||
nf_bridge_pull_encap_header(*pskb);
|
||||
nf_bridge_pull_encap_header(skb);
|
||||
|
||||
nf_bridge = skb->nf_bridge;
|
||||
if (skb->pkt_type == PACKET_OTHERHOST) {
|
||||
@ -666,12 +659,11 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
|
||||
return NF_STOLEN;
|
||||
}
|
||||
|
||||
static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
|
||||
static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
struct sk_buff *skb = *pskb;
|
||||
struct net_device **d = (struct net_device **)(skb->cb);
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
@ -682,12 +674,12 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
|
||||
if (skb->protocol != htons(ETH_P_ARP)) {
|
||||
if (!IS_VLAN_ARP(skb))
|
||||
return NF_ACCEPT;
|
||||
nf_bridge_pull_encap_header(*pskb);
|
||||
nf_bridge_pull_encap_header(skb);
|
||||
}
|
||||
|
||||
if (arp_hdr(skb)->ar_pln != 4) {
|
||||
if (IS_VLAN_ARP(skb))
|
||||
nf_bridge_push_encap_header(*pskb);
|
||||
nf_bridge_push_encap_header(skb);
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
*d = (struct net_device *)in;
|
||||
@ -709,13 +701,12 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
|
||||
* NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor
|
||||
* will be executed.
|
||||
*/
|
||||
static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
|
||||
static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
struct net_device *realindev;
|
||||
struct sk_buff *skb = *pskb;
|
||||
struct nf_bridge_info *nf_bridge;
|
||||
|
||||
if (!skb->nf_bridge)
|
||||
@ -752,13 +743,12 @@ static int br_nf_dev_queue_xmit(struct sk_buff *skb)
|
||||
}
|
||||
|
||||
/* PF_BRIDGE/POST_ROUTING ********************************************/
|
||||
static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
|
||||
static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
struct sk_buff *skb = *pskb;
|
||||
struct nf_bridge_info *nf_bridge = (*pskb)->nf_bridge;
|
||||
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
|
||||
struct net_device *realoutdev = bridge_parent(skb->dev);
|
||||
int pf;
|
||||
|
||||
@ -828,13 +818,13 @@ print_error:
|
||||
/* IP/SABOTAGE *****************************************************/
|
||||
/* Don't hand locally destined packets to PF_INET(6)/PRE_ROUTING
|
||||
* for the second time. */
|
||||
static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb,
|
||||
static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
if ((*pskb)->nf_bridge &&
|
||||
!((*pskb)->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) {
|
||||
if (skb->nf_bridge &&
|
||||
!(skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) {
|
||||
return NF_STOP;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <net/arp.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static int ebt_target_reply(struct sk_buff **pskb, unsigned int hooknr,
|
||||
static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
const void *data, unsigned int datalen)
|
||||
{
|
||||
@ -23,7 +23,6 @@ static int ebt_target_reply(struct sk_buff **pskb, unsigned int hooknr,
|
||||
__be32 _sip, *siptr, _dip, *diptr;
|
||||
struct arphdr _ah, *ap;
|
||||
unsigned char _sha[ETH_ALEN], *shp;
|
||||
struct sk_buff *skb = *pskb;
|
||||
|
||||
ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
|
||||
if (ap == NULL)
|
||||
|
@ -8,29 +8,22 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_bridge/ebtables.h>
|
||||
#include <linux/netfilter_bridge/ebt_nat.h>
|
||||
#include <linux/module.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
static int ebt_target_dnat(struct sk_buff **pskb, unsigned int hooknr,
|
||||
static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
const void *data, unsigned int datalen)
|
||||
{
|
||||
struct ebt_nat_info *info = (struct ebt_nat_info *)data;
|
||||
|
||||
if (skb_shared(*pskb) || skb_cloned(*pskb)) {
|
||||
struct sk_buff *nskb;
|
||||
if (skb_make_writable(skb, 0))
|
||||
return NF_DROP;
|
||||
|
||||
nskb = skb_copy(*pskb, GFP_ATOMIC);
|
||||
if (!nskb)
|
||||
return NF_DROP;
|
||||
if ((*pskb)->sk)
|
||||
skb_set_owner_w(nskb, (*pskb)->sk);
|
||||
kfree_skb(*pskb);
|
||||
*pskb = nskb;
|
||||
}
|
||||
memcpy(eth_hdr(*pskb)->h_dest, info->mac, ETH_ALEN);
|
||||
memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN);
|
||||
return info->target;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <linux/netfilter_bridge/ebt_mark_t.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static int ebt_target_mark(struct sk_buff **pskb, unsigned int hooknr,
|
||||
static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
const void *data, unsigned int datalen)
|
||||
{
|
||||
@ -25,13 +25,13 @@ static int ebt_target_mark(struct sk_buff **pskb, unsigned int hooknr,
|
||||
int action = info->target & -16;
|
||||
|
||||
if (action == MARK_SET_VALUE)
|
||||
(*pskb)->mark = info->mark;
|
||||
skb->mark = info->mark;
|
||||
else if (action == MARK_OR_VALUE)
|
||||
(*pskb)->mark |= info->mark;
|
||||
skb->mark |= info->mark;
|
||||
else if (action == MARK_AND_VALUE)
|
||||
(*pskb)->mark &= info->mark;
|
||||
skb->mark &= info->mark;
|
||||
else
|
||||
(*pskb)->mark ^= info->mark;
|
||||
skb->mark ^= info->mark;
|
||||
|
||||
return info->target | ~EBT_VERDICT_BITS;
|
||||
}
|
||||
|
@ -8,35 +8,28 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_bridge/ebtables.h>
|
||||
#include <linux/netfilter_bridge/ebt_redirect.h>
|
||||
#include <linux/module.h>
|
||||
#include <net/sock.h>
|
||||
#include "../br_private.h"
|
||||
|
||||
static int ebt_target_redirect(struct sk_buff **pskb, unsigned int hooknr,
|
||||
static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
const void *data, unsigned int datalen)
|
||||
{
|
||||
struct ebt_redirect_info *info = (struct ebt_redirect_info *)data;
|
||||
|
||||
if (skb_shared(*pskb) || skb_cloned(*pskb)) {
|
||||
struct sk_buff *nskb;
|
||||
if (skb_make_writable(skb, 0))
|
||||
return NF_DROP;
|
||||
|
||||
nskb = skb_copy(*pskb, GFP_ATOMIC);
|
||||
if (!nskb)
|
||||
return NF_DROP;
|
||||
if ((*pskb)->sk)
|
||||
skb_set_owner_w(nskb, (*pskb)->sk);
|
||||
kfree_skb(*pskb);
|
||||
*pskb = nskb;
|
||||
}
|
||||
if (hooknr != NF_BR_BROUTING)
|
||||
memcpy(eth_hdr(*pskb)->h_dest,
|
||||
memcpy(eth_hdr(skb)->h_dest,
|
||||
in->br_port->br->dev->dev_addr, ETH_ALEN);
|
||||
else
|
||||
memcpy(eth_hdr(*pskb)->h_dest, in->dev_addr, ETH_ALEN);
|
||||
(*pskb)->pkt_type = PACKET_HOST;
|
||||
memcpy(eth_hdr(skb)->h_dest, in->dev_addr, ETH_ALEN);
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
return info->target;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_bridge/ebtables.h>
|
||||
#include <linux/netfilter_bridge/ebt_nat.h>
|
||||
#include <linux/module.h>
|
||||
@ -15,34 +16,26 @@
|
||||
#include <linux/if_arp.h>
|
||||
#include <net/arp.h>
|
||||
|
||||
static int ebt_target_snat(struct sk_buff **pskb, unsigned int hooknr,
|
||||
static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
const void *data, unsigned int datalen)
|
||||
{
|
||||
struct ebt_nat_info *info = (struct ebt_nat_info *) data;
|
||||
|
||||
if (skb_shared(*pskb) || skb_cloned(*pskb)) {
|
||||
struct sk_buff *nskb;
|
||||
if (skb_make_writable(skb, 0))
|
||||
return NF_DROP;
|
||||
|
||||
nskb = skb_copy(*pskb, GFP_ATOMIC);
|
||||
if (!nskb)
|
||||
return NF_DROP;
|
||||
if ((*pskb)->sk)
|
||||
skb_set_owner_w(nskb, (*pskb)->sk);
|
||||
kfree_skb(*pskb);
|
||||
*pskb = nskb;
|
||||
}
|
||||
memcpy(eth_hdr(*pskb)->h_source, info->mac, ETH_ALEN);
|
||||
memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN);
|
||||
if (!(info->target & NAT_ARP_BIT) &&
|
||||
eth_hdr(*pskb)->h_proto == htons(ETH_P_ARP)) {
|
||||
eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
|
||||
struct arphdr _ah, *ap;
|
||||
|
||||
ap = skb_header_pointer(*pskb, 0, sizeof(_ah), &_ah);
|
||||
ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
|
||||
if (ap == NULL)
|
||||
return EBT_DROP;
|
||||
if (ap->ar_hln != ETH_ALEN)
|
||||
goto out;
|
||||
if (skb_store_bits(*pskb, sizeof(_ah), info->mac,ETH_ALEN))
|
||||
if (skb_store_bits(skb, sizeof(_ah), info->mac,ETH_ALEN))
|
||||
return EBT_DROP;
|
||||
}
|
||||
out:
|
||||
|
@ -51,11 +51,11 @@ static struct ebt_table broute_table =
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int ebt_broute(struct sk_buff **pskb)
|
||||
static int ebt_broute(struct sk_buff *skb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ebt_do_table(NF_BR_BROUTING, pskb, (*pskb)->dev, NULL,
|
||||
ret = ebt_do_table(NF_BR_BROUTING, skb, skb->dev, NULL,
|
||||
&broute_table);
|
||||
if (ret == NF_DROP)
|
||||
return 1; /* route it */
|
||||
|
@ -61,10 +61,10 @@ static struct ebt_table frame_filter =
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
ebt_hook (unsigned int hook, struct sk_buff **pskb, const struct net_device *in,
|
||||
ebt_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in,
|
||||
const struct net_device *out, int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ebt_do_table(hook, pskb, in, out, &frame_filter);
|
||||
return ebt_do_table(hook, skb, in, out, &frame_filter);
|
||||
}
|
||||
|
||||
static struct nf_hook_ops ebt_ops_filter[] = {
|
||||
|
@ -61,17 +61,17 @@ static struct ebt_table frame_nat =
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
ebt_nat_dst(unsigned int hook, struct sk_buff **pskb, const struct net_device *in
|
||||
ebt_nat_dst(unsigned int hook, struct sk_buff *skb, const struct net_device *in
|
||||
, const struct net_device *out, int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ebt_do_table(hook, pskb, in, out, &frame_nat);
|
||||
return ebt_do_table(hook, skb, in, out, &frame_nat);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ebt_nat_src(unsigned int hook, struct sk_buff **pskb, const struct net_device *in
|
||||
ebt_nat_src(unsigned int hook, struct sk_buff *skb, const struct net_device *in
|
||||
, const struct net_device *out, int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ebt_do_table(hook, pskb, in, out, &frame_nat);
|
||||
return ebt_do_table(hook, skb, in, out, &frame_nat);
|
||||
}
|
||||
|
||||
static struct nf_hook_ops ebt_ops_nat[] = {
|
||||
|
@ -142,7 +142,7 @@ static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h,
|
||||
}
|
||||
|
||||
/* Do some firewalling */
|
||||
unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
|
||||
unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
struct ebt_table *table)
|
||||
{
|
||||
@ -172,19 +172,19 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
|
||||
base = private->entries;
|
||||
i = 0;
|
||||
while (i < nentries) {
|
||||
if (ebt_basic_match(point, eth_hdr(*pskb), in, out))
|
||||
if (ebt_basic_match(point, eth_hdr(skb), in, out))
|
||||
goto letscontinue;
|
||||
|
||||
if (EBT_MATCH_ITERATE(point, ebt_do_match, *pskb, in, out) != 0)
|
||||
if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, in, out) != 0)
|
||||
goto letscontinue;
|
||||
|
||||
/* increase counter */
|
||||
(*(counter_base + i)).pcnt++;
|
||||
(*(counter_base + i)).bcnt+=(**pskb).len;
|
||||
(*(counter_base + i)).bcnt += skb->len;
|
||||
|
||||
/* these should only watch: not modify, nor tell us
|
||||
what to do with the packet */
|
||||
EBT_WATCHER_ITERATE(point, ebt_do_watcher, *pskb, hook, in,
|
||||
EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, hook, in,
|
||||
out);
|
||||
|
||||
t = (struct ebt_entry_target *)
|
||||
@ -193,7 +193,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
|
||||
if (!t->u.target->target)
|
||||
verdict = ((struct ebt_standard_target *)t)->verdict;
|
||||
else
|
||||
verdict = t->u.target->target(pskb, hook,
|
||||
verdict = t->u.target->target(skb, hook,
|
||||
in, out, t->data, t->target_size);
|
||||
if (verdict == EBT_ACCEPT) {
|
||||
read_unlock_bh(&table->lock);
|
||||
|
@ -1362,22 +1362,21 @@ int skb_checksum_help(struct sk_buff *skb)
|
||||
goto out_set_summed;
|
||||
}
|
||||
|
||||
if (skb_cloned(skb)) {
|
||||
offset = skb->csum_start - skb_headroom(skb);
|
||||
BUG_ON(offset >= skb_headlen(skb));
|
||||
csum = skb_checksum(skb, offset, skb->len - offset, 0);
|
||||
|
||||
offset += skb->csum_offset;
|
||||
BUG_ON(offset + sizeof(__sum16) > skb_headlen(skb));
|
||||
|
||||
if (skb_cloned(skb) &&
|
||||
!skb_clone_writable(skb, offset + sizeof(__sum16))) {
|
||||
ret = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
offset = skb->csum_start - skb_headroom(skb);
|
||||
BUG_ON(offset > (int)skb->len);
|
||||
csum = skb_checksum(skb, offset, skb->len-offset, 0);
|
||||
|
||||
offset = skb_headlen(skb) - offset;
|
||||
BUG_ON(offset <= 0);
|
||||
BUG_ON(skb->csum_offset + 2 > offset);
|
||||
|
||||
*(__sum16 *)(skb->head + skb->csum_start + skb->csum_offset) =
|
||||
csum_fold(csum);
|
||||
*(__sum16 *)(skb->data + offset) = csum_fold(csum);
|
||||
out_set_summed:
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
out:
|
||||
@ -1949,28 +1948,52 @@ static int ing_filter(struct sk_buff *skb)
|
||||
struct Qdisc *q;
|
||||
struct net_device *dev = skb->dev;
|
||||
int result = TC_ACT_OK;
|
||||
u32 ttl = G_TC_RTTL(skb->tc_verd);
|
||||
|
||||
if (dev->qdisc_ingress) {
|
||||
__u32 ttl = (__u32) G_TC_RTTL(skb->tc_verd);
|
||||
if (MAX_RED_LOOP < ttl++) {
|
||||
printk(KERN_WARNING "Redir loop detected Dropping packet (%d->%d)\n",
|
||||
skb->iif, skb->dev->ifindex);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
skb->tc_verd = SET_TC_RTTL(skb->tc_verd,ttl);
|
||||
|
||||
skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS);
|
||||
|
||||
spin_lock(&dev->ingress_lock);
|
||||
if ((q = dev->qdisc_ingress) != NULL)
|
||||
result = q->enqueue(skb, q);
|
||||
spin_unlock(&dev->ingress_lock);
|
||||
|
||||
if (MAX_RED_LOOP < ttl++) {
|
||||
printk(KERN_WARNING
|
||||
"Redir loop detected Dropping packet (%d->%d)\n",
|
||||
skb->iif, dev->ifindex);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
skb->tc_verd = SET_TC_RTTL(skb->tc_verd, ttl);
|
||||
skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_INGRESS);
|
||||
|
||||
spin_lock(&dev->ingress_lock);
|
||||
if ((q = dev->qdisc_ingress) != NULL)
|
||||
result = q->enqueue(skb, q);
|
||||
spin_unlock(&dev->ingress_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline struct sk_buff *handle_ing(struct sk_buff *skb,
|
||||
struct packet_type **pt_prev,
|
||||
int *ret, struct net_device *orig_dev)
|
||||
{
|
||||
if (!skb->dev->qdisc_ingress)
|
||||
goto out;
|
||||
|
||||
if (*pt_prev) {
|
||||
*ret = deliver_skb(skb, *pt_prev, orig_dev);
|
||||
*pt_prev = NULL;
|
||||
} else {
|
||||
/* Huh? Why does turning on AF_PACKET affect this? */
|
||||
skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
|
||||
}
|
||||
|
||||
switch (ing_filter(skb)) {
|
||||
case TC_ACT_SHOT:
|
||||
case TC_ACT_STOLEN:
|
||||
kfree_skb(skb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
skb->tc_verd = 0;
|
||||
return skb;
|
||||
}
|
||||
#endif
|
||||
|
||||
int netif_receive_skb(struct sk_buff *skb)
|
||||
@ -2021,21 +2044,9 @@ int netif_receive_skb(struct sk_buff *skb)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
if (pt_prev) {
|
||||
ret = deliver_skb(skb, pt_prev, orig_dev);
|
||||
pt_prev = NULL; /* noone else should process this after*/
|
||||
} else {
|
||||
skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
|
||||
}
|
||||
|
||||
ret = ing_filter(skb);
|
||||
|
||||
if (ret == TC_ACT_SHOT || (ret == TC_ACT_STOLEN)) {
|
||||
kfree_skb(skb);
|
||||
skb = handle_ing(skb, &pt_prev, &ret, orig_dev);
|
||||
if (!skb)
|
||||
goto out;
|
||||
}
|
||||
|
||||
skb->tc_verd = 0;
|
||||
ncls:
|
||||
#endif
|
||||
|
||||
|
@ -481,6 +481,8 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, const void *pkey,
|
||||
if (!creat)
|
||||
goto out;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
n = kmalloc(sizeof(*n) + key_len, GFP_KERNEL);
|
||||
if (!n)
|
||||
goto out;
|
||||
|
@ -362,6 +362,97 @@ void kfree_skb(struct sk_buff *skb)
|
||||
__kfree_skb(skb);
|
||||
}
|
||||
|
||||
static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
|
||||
{
|
||||
new->tstamp = old->tstamp;
|
||||
new->dev = old->dev;
|
||||
new->transport_header = old->transport_header;
|
||||
new->network_header = old->network_header;
|
||||
new->mac_header = old->mac_header;
|
||||
new->dst = dst_clone(old->dst);
|
||||
#ifdef CONFIG_INET
|
||||
new->sp = secpath_get(old->sp);
|
||||
#endif
|
||||
memcpy(new->cb, old->cb, sizeof(old->cb));
|
||||
new->csum_start = old->csum_start;
|
||||
new->csum_offset = old->csum_offset;
|
||||
new->local_df = old->local_df;
|
||||
new->pkt_type = old->pkt_type;
|
||||
new->ip_summed = old->ip_summed;
|
||||
skb_copy_queue_mapping(new, old);
|
||||
new->priority = old->priority;
|
||||
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
|
||||
new->ipvs_property = old->ipvs_property;
|
||||
#endif
|
||||
new->protocol = old->protocol;
|
||||
new->mark = old->mark;
|
||||
__nf_copy(new, old);
|
||||
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
|
||||
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
|
||||
new->nf_trace = old->nf_trace;
|
||||
#endif
|
||||
#ifdef CONFIG_NET_SCHED
|
||||
new->tc_index = old->tc_index;
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
new->tc_verd = old->tc_verd;
|
||||
#endif
|
||||
#endif
|
||||
skb_copy_secmark(new, old);
|
||||
}
|
||||
|
||||
static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
|
||||
{
|
||||
#define C(x) n->x = skb->x
|
||||
|
||||
n->next = n->prev = NULL;
|
||||
n->sk = NULL;
|
||||
__copy_skb_header(n, skb);
|
||||
|
||||
C(len);
|
||||
C(data_len);
|
||||
C(mac_len);
|
||||
n->cloned = 1;
|
||||
n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
|
||||
n->nohdr = 0;
|
||||
n->destructor = NULL;
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
/* FIXME What is this and why don't we do it in copy_skb_header? */
|
||||
n->tc_verd = SET_TC_VERD(n->tc_verd,0);
|
||||
n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
|
||||
n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
|
||||
C(iif);
|
||||
#endif
|
||||
C(truesize);
|
||||
atomic_set(&n->users, 1);
|
||||
C(head);
|
||||
C(data);
|
||||
C(tail);
|
||||
C(end);
|
||||
|
||||
atomic_inc(&(skb_shinfo(skb)->dataref));
|
||||
skb->cloned = 1;
|
||||
|
||||
return n;
|
||||
#undef C
|
||||
}
|
||||
|
||||
/**
|
||||
* skb_morph - morph one skb into another
|
||||
* @dst: the skb to receive the contents
|
||||
* @src: the skb to supply the contents
|
||||
*
|
||||
* This is identical to skb_clone except that the target skb is
|
||||
* supplied by the user.
|
||||
*
|
||||
* The target skb is returned upon exit.
|
||||
*/
|
||||
struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src)
|
||||
{
|
||||
skb_release_data(dst);
|
||||
return __skb_clone(dst, src);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(skb_morph);
|
||||
|
||||
/**
|
||||
* skb_clone - duplicate an sk_buff
|
||||
* @skb: buffer to clone
|
||||
@ -393,66 +484,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
|
||||
n->fclone = SKB_FCLONE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
#define C(x) n->x = skb->x
|
||||
|
||||
n->next = n->prev = NULL;
|
||||
n->sk = NULL;
|
||||
C(tstamp);
|
||||
C(dev);
|
||||
C(transport_header);
|
||||
C(network_header);
|
||||
C(mac_header);
|
||||
C(dst);
|
||||
dst_clone(skb->dst);
|
||||
C(sp);
|
||||
#ifdef CONFIG_INET
|
||||
secpath_get(skb->sp);
|
||||
#endif
|
||||
memcpy(n->cb, skb->cb, sizeof(skb->cb));
|
||||
C(len);
|
||||
C(data_len);
|
||||
C(mac_len);
|
||||
C(csum);
|
||||
C(local_df);
|
||||
n->cloned = 1;
|
||||
n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
|
||||
n->nohdr = 0;
|
||||
C(pkt_type);
|
||||
C(ip_summed);
|
||||
skb_copy_queue_mapping(n, skb);
|
||||
C(priority);
|
||||
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
|
||||
C(ipvs_property);
|
||||
#endif
|
||||
C(protocol);
|
||||
n->destructor = NULL;
|
||||
C(mark);
|
||||
__nf_copy(n, skb);
|
||||
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
|
||||
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
|
||||
C(nf_trace);
|
||||
#endif
|
||||
#ifdef CONFIG_NET_SCHED
|
||||
C(tc_index);
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
n->tc_verd = SET_TC_VERD(skb->tc_verd,0);
|
||||
n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
|
||||
n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
|
||||
C(iif);
|
||||
#endif
|
||||
#endif
|
||||
skb_copy_secmark(n, skb);
|
||||
C(truesize);
|
||||
atomic_set(&n->users, 1);
|
||||
C(head);
|
||||
C(data);
|
||||
C(tail);
|
||||
C(end);
|
||||
|
||||
atomic_inc(&(skb_shinfo(skb)->dataref));
|
||||
skb->cloned = 1;
|
||||
|
||||
return n;
|
||||
return __skb_clone(n, skb);
|
||||
}
|
||||
|
||||
static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
|
||||
@ -463,50 +495,15 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
|
||||
*/
|
||||
unsigned long offset = new->data - old->data;
|
||||
#endif
|
||||
new->sk = NULL;
|
||||
new->dev = old->dev;
|
||||
skb_copy_queue_mapping(new, old);
|
||||
new->priority = old->priority;
|
||||
new->protocol = old->protocol;
|
||||
new->dst = dst_clone(old->dst);
|
||||
#ifdef CONFIG_INET
|
||||
new->sp = secpath_get(old->sp);
|
||||
#endif
|
||||
new->csum_start = old->csum_start;
|
||||
new->csum_offset = old->csum_offset;
|
||||
new->ip_summed = old->ip_summed;
|
||||
new->transport_header = old->transport_header;
|
||||
new->network_header = old->network_header;
|
||||
new->mac_header = old->mac_header;
|
||||
|
||||
__copy_skb_header(new, old);
|
||||
|
||||
#ifndef NET_SKBUFF_DATA_USES_OFFSET
|
||||
/* {transport,network,mac}_header are relative to skb->head */
|
||||
new->transport_header += offset;
|
||||
new->network_header += offset;
|
||||
new->mac_header += offset;
|
||||
#endif
|
||||
memcpy(new->cb, old->cb, sizeof(old->cb));
|
||||
new->local_df = old->local_df;
|
||||
new->fclone = SKB_FCLONE_UNAVAILABLE;
|
||||
new->pkt_type = old->pkt_type;
|
||||
new->tstamp = old->tstamp;
|
||||
new->destructor = NULL;
|
||||
new->mark = old->mark;
|
||||
__nf_copy(new, old);
|
||||
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
|
||||
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
|
||||
new->nf_trace = old->nf_trace;
|
||||
#endif
|
||||
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
|
||||
new->ipvs_property = old->ipvs_property;
|
||||
#endif
|
||||
#ifdef CONFIG_NET_SCHED
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
new->tc_verd = old->tc_verd;
|
||||
#endif
|
||||
new->tc_index = old->tc_index;
|
||||
#endif
|
||||
skb_copy_secmark(new, old);
|
||||
atomic_set(&new->users, 1);
|
||||
skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
|
||||
skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
|
||||
skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
|
||||
@ -685,7 +682,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
|
||||
skb->transport_header += off;
|
||||
skb->network_header += off;
|
||||
skb->mac_header += off;
|
||||
skb->csum_start += off;
|
||||
skb->csum_start += nhead;
|
||||
skb->cloned = 0;
|
||||
skb->hdr_len = 0;
|
||||
skb->nohdr = 0;
|
||||
|
@ -767,10 +767,9 @@ discard:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dccp_v6_rcv(struct sk_buff **pskb)
|
||||
static int dccp_v6_rcv(struct sk_buff *skb)
|
||||
{
|
||||
const struct dccp_hdr *dh;
|
||||
struct sk_buff *skb = *pskb;
|
||||
struct sock *sk;
|
||||
int min_cov;
|
||||
|
||||
|
@ -88,12 +88,12 @@ static void dnrmg_send_peer(struct sk_buff *skb)
|
||||
|
||||
|
||||
static unsigned int dnrmg_hook(unsigned int hook,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
dnrmg_send_peer(*pskb);
|
||||
dnrmg_send_peer(skb);
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,8 @@ obj-y := route.o inetpeer.o protocol.o \
|
||||
tcp_minisocks.o tcp_cong.o \
|
||||
datagram.o raw.o udp.o udplite.o \
|
||||
arp.o icmp.o devinet.o af_inet.o igmp.o \
|
||||
sysctl_net_ipv4.o fib_frontend.o fib_semantics.o
|
||||
sysctl_net_ipv4.o fib_frontend.o fib_semantics.o \
|
||||
inet_fragment.o
|
||||
|
||||
obj-$(CONFIG_IP_FIB_HASH) += fib_hash.o
|
||||
obj-$(CONFIG_IP_FIB_TRIE) += fib_trie.o
|
||||
|
174
net/ipv4/inet_fragment.c
Normal file
174
net/ipv4/inet_fragment.c
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* inet fragments management
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Pavel Emelyanov <xemul@openvz.org>
|
||||
* Started as consolidation of ipv4/ip_fragment.c,
|
||||
* ipv6/reassembly. and ipv6 nf conntrack reassembly
|
||||
*/
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
#include <net/inet_frag.h>
|
||||
|
||||
static void inet_frag_secret_rebuild(unsigned long dummy)
|
||||
{
|
||||
struct inet_frags *f = (struct inet_frags *)dummy;
|
||||
unsigned long now = jiffies;
|
||||
int i;
|
||||
|
||||
write_lock(&f->lock);
|
||||
get_random_bytes(&f->rnd, sizeof(u32));
|
||||
for (i = 0; i < INETFRAGS_HASHSZ; i++) {
|
||||
struct inet_frag_queue *q;
|
||||
struct hlist_node *p, *n;
|
||||
|
||||
hlist_for_each_entry_safe(q, p, n, &f->hash[i], list) {
|
||||
unsigned int hval = f->hashfn(q);
|
||||
|
||||
if (hval != i) {
|
||||
hlist_del(&q->list);
|
||||
|
||||
/* Relink to new hash chain. */
|
||||
hlist_add_head(&q->list, &f->hash[hval]);
|
||||
}
|
||||
}
|
||||
}
|
||||
write_unlock(&f->lock);
|
||||
|
||||
mod_timer(&f->secret_timer, now + f->ctl->secret_interval);
|
||||
}
|
||||
|
||||
void inet_frags_init(struct inet_frags *f)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < INETFRAGS_HASHSZ; i++)
|
||||
INIT_HLIST_HEAD(&f->hash[i]);
|
||||
|
||||
INIT_LIST_HEAD(&f->lru_list);
|
||||
rwlock_init(&f->lock);
|
||||
|
||||
f->rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
|
||||
(jiffies ^ (jiffies >> 6)));
|
||||
|
||||
f->nqueues = 0;
|
||||
atomic_set(&f->mem, 0);
|
||||
|
||||
init_timer(&f->secret_timer);
|
||||
f->secret_timer.function = inet_frag_secret_rebuild;
|
||||
f->secret_timer.data = (unsigned long)f;
|
||||
f->secret_timer.expires = jiffies + f->ctl->secret_interval;
|
||||
add_timer(&f->secret_timer);
|
||||
}
|
||||
EXPORT_SYMBOL(inet_frags_init);
|
||||
|
||||
void inet_frags_fini(struct inet_frags *f)
|
||||
{
|
||||
del_timer(&f->secret_timer);
|
||||
}
|
||||
EXPORT_SYMBOL(inet_frags_fini);
|
||||
|
||||
static inline void fq_unlink(struct inet_frag_queue *fq, struct inet_frags *f)
|
||||
{
|
||||
write_lock(&f->lock);
|
||||
hlist_del(&fq->list);
|
||||
list_del(&fq->lru_list);
|
||||
f->nqueues--;
|
||||
write_unlock(&f->lock);
|
||||
}
|
||||
|
||||
void inet_frag_kill(struct inet_frag_queue *fq, struct inet_frags *f)
|
||||
{
|
||||
if (del_timer(&fq->timer))
|
||||
atomic_dec(&fq->refcnt);
|
||||
|
||||
if (!(fq->last_in & COMPLETE)) {
|
||||
fq_unlink(fq, f);
|
||||
atomic_dec(&fq->refcnt);
|
||||
fq->last_in |= COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(inet_frag_kill);
|
||||
|
||||
static inline void frag_kfree_skb(struct inet_frags *f, struct sk_buff *skb,
|
||||
int *work)
|
||||
{
|
||||
if (work)
|
||||
*work -= skb->truesize;
|
||||
|
||||
atomic_sub(skb->truesize, &f->mem);
|
||||
if (f->skb_free)
|
||||
f->skb_free(skb);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f,
|
||||
int *work)
|
||||
{
|
||||
struct sk_buff *fp;
|
||||
|
||||
BUG_TRAP(q->last_in & COMPLETE);
|
||||
BUG_TRAP(del_timer(&q->timer) == 0);
|
||||
|
||||
/* Release all fragment data. */
|
||||
fp = q->fragments;
|
||||
while (fp) {
|
||||
struct sk_buff *xp = fp->next;
|
||||
|
||||
frag_kfree_skb(f, fp, work);
|
||||
fp = xp;
|
||||
}
|
||||
|
||||
if (work)
|
||||
*work -= f->qsize;
|
||||
atomic_sub(f->qsize, &f->mem);
|
||||
|
||||
f->destructor(q);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(inet_frag_destroy);
|
||||
|
||||
int inet_frag_evictor(struct inet_frags *f)
|
||||
{
|
||||
struct inet_frag_queue *q;
|
||||
int work, evicted = 0;
|
||||
|
||||
work = atomic_read(&f->mem) - f->ctl->low_thresh;
|
||||
while (work > 0) {
|
||||
read_lock(&f->lock);
|
||||
if (list_empty(&f->lru_list)) {
|
||||
read_unlock(&f->lock);
|
||||
break;
|
||||
}
|
||||
|
||||
q = list_first_entry(&f->lru_list,
|
||||
struct inet_frag_queue, lru_list);
|
||||
atomic_inc(&q->refcnt);
|
||||
read_unlock(&f->lock);
|
||||
|
||||
spin_lock(&q->lock);
|
||||
if (!(q->last_in & COMPLETE))
|
||||
inet_frag_kill(q, f);
|
||||
spin_unlock(&q->lock);
|
||||
|
||||
if (atomic_dec_and_test(&q->refcnt))
|
||||
inet_frag_destroy(q, f, &work);
|
||||
evicted++;
|
||||
}
|
||||
|
||||
return evicted;
|
||||
}
|
||||
EXPORT_SYMBOL(inet_frag_evictor);
|
@ -40,7 +40,7 @@
|
||||
#include <net/route.h>
|
||||
#include <net/xfrm.h>
|
||||
|
||||
static inline int ip_forward_finish(struct sk_buff *skb)
|
||||
static int ip_forward_finish(struct sk_buff *skb)
|
||||
{
|
||||
struct ip_options * opt = &(IPCB(skb)->opt);
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <net/icmp.h>
|
||||
#include <net/checksum.h>
|
||||
#include <net/inetpeer.h>
|
||||
#include <net/inet_frag.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/inet.h>
|
||||
@ -49,21 +50,8 @@
|
||||
* as well. Or notify me, at least. --ANK
|
||||
*/
|
||||
|
||||
/* Fragment cache limits. We will commit 256K at one time. Should we
|
||||
* cross that limit we will prune down to 192K. This should cope with
|
||||
* even the most extreme cases without allowing an attacker to measurably
|
||||
* harm machine performance.
|
||||
*/
|
||||
int sysctl_ipfrag_high_thresh __read_mostly = 256*1024;
|
||||
int sysctl_ipfrag_low_thresh __read_mostly = 192*1024;
|
||||
|
||||
int sysctl_ipfrag_max_dist __read_mostly = 64;
|
||||
|
||||
/* Important NOTE! Fragment queue must be destroyed before MSL expires.
|
||||
* RFC791 is wrong proposing to prolongate timer each fragment arrival by TTL.
|
||||
*/
|
||||
int sysctl_ipfrag_time __read_mostly = IP_FRAG_TIME;
|
||||
|
||||
struct ipfrag_skb_cb
|
||||
{
|
||||
struct inet_skb_parm h;
|
||||
@ -74,153 +62,102 @@ struct ipfrag_skb_cb
|
||||
|
||||
/* Describe an entry in the "incomplete datagrams" queue. */
|
||||
struct ipq {
|
||||
struct hlist_node list;
|
||||
struct list_head lru_list; /* lru list member */
|
||||
struct inet_frag_queue q;
|
||||
|
||||
u32 user;
|
||||
__be32 saddr;
|
||||
__be32 daddr;
|
||||
__be16 id;
|
||||
u8 protocol;
|
||||
u8 last_in;
|
||||
#define COMPLETE 4
|
||||
#define FIRST_IN 2
|
||||
#define LAST_IN 1
|
||||
|
||||
struct sk_buff *fragments; /* linked list of received fragments */
|
||||
int len; /* total length of original datagram */
|
||||
int meat;
|
||||
spinlock_t lock;
|
||||
atomic_t refcnt;
|
||||
struct timer_list timer; /* when will this queue expire? */
|
||||
ktime_t stamp;
|
||||
int iif;
|
||||
unsigned int rid;
|
||||
struct inet_peer *peer;
|
||||
};
|
||||
|
||||
/* Hash table. */
|
||||
struct inet_frags_ctl ip4_frags_ctl __read_mostly = {
|
||||
/*
|
||||
* Fragment cache limits. We will commit 256K at one time. Should we
|
||||
* cross that limit we will prune down to 192K. This should cope with
|
||||
* even the most extreme cases without allowing an attacker to
|
||||
* measurably harm machine performance.
|
||||
*/
|
||||
.high_thresh = 256 * 1024,
|
||||
.low_thresh = 192 * 1024,
|
||||
|
||||
#define IPQ_HASHSZ 64
|
||||
/*
|
||||
* Important NOTE! Fragment queue must be destroyed before MSL expires.
|
||||
* RFC791 is wrong proposing to prolongate timer each fragment arrival
|
||||
* by TTL.
|
||||
*/
|
||||
.timeout = IP_FRAG_TIME,
|
||||
.secret_interval = 10 * 60 * HZ,
|
||||
};
|
||||
|
||||
/* Per-bucket lock is easy to add now. */
|
||||
static struct hlist_head ipq_hash[IPQ_HASHSZ];
|
||||
static DEFINE_RWLOCK(ipfrag_lock);
|
||||
static u32 ipfrag_hash_rnd;
|
||||
static LIST_HEAD(ipq_lru_list);
|
||||
int ip_frag_nqueues = 0;
|
||||
static struct inet_frags ip4_frags;
|
||||
|
||||
static __inline__ void __ipq_unlink(struct ipq *qp)
|
||||
int ip_frag_nqueues(void)
|
||||
{
|
||||
hlist_del(&qp->list);
|
||||
list_del(&qp->lru_list);
|
||||
ip_frag_nqueues--;
|
||||
return ip4_frags.nqueues;
|
||||
}
|
||||
|
||||
static __inline__ void ipq_unlink(struct ipq *ipq)
|
||||
int ip_frag_mem(void)
|
||||
{
|
||||
write_lock(&ipfrag_lock);
|
||||
__ipq_unlink(ipq);
|
||||
write_unlock(&ipfrag_lock);
|
||||
return atomic_read(&ip4_frags.mem);
|
||||
}
|
||||
|
||||
static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
|
||||
struct net_device *dev);
|
||||
|
||||
static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
|
||||
{
|
||||
return jhash_3words((__force u32)id << 16 | prot,
|
||||
(__force u32)saddr, (__force u32)daddr,
|
||||
ipfrag_hash_rnd) & (IPQ_HASHSZ - 1);
|
||||
ip4_frags.rnd) & (INETFRAGS_HASHSZ - 1);
|
||||
}
|
||||
|
||||
static struct timer_list ipfrag_secret_timer;
|
||||
int sysctl_ipfrag_secret_interval __read_mostly = 10 * 60 * HZ;
|
||||
|
||||
static void ipfrag_secret_rebuild(unsigned long dummy)
|
||||
static unsigned int ip4_hashfn(struct inet_frag_queue *q)
|
||||
{
|
||||
unsigned long now = jiffies;
|
||||
int i;
|
||||
struct ipq *ipq;
|
||||
|
||||
write_lock(&ipfrag_lock);
|
||||
get_random_bytes(&ipfrag_hash_rnd, sizeof(u32));
|
||||
for (i = 0; i < IPQ_HASHSZ; i++) {
|
||||
struct ipq *q;
|
||||
struct hlist_node *p, *n;
|
||||
|
||||
hlist_for_each_entry_safe(q, p, n, &ipq_hash[i], list) {
|
||||
unsigned int hval = ipqhashfn(q->id, q->saddr,
|
||||
q->daddr, q->protocol);
|
||||
|
||||
if (hval != i) {
|
||||
hlist_del(&q->list);
|
||||
|
||||
/* Relink to new hash chain. */
|
||||
hlist_add_head(&q->list, &ipq_hash[hval]);
|
||||
}
|
||||
}
|
||||
}
|
||||
write_unlock(&ipfrag_lock);
|
||||
|
||||
mod_timer(&ipfrag_secret_timer, now + sysctl_ipfrag_secret_interval);
|
||||
ipq = container_of(q, struct ipq, q);
|
||||
return ipqhashfn(ipq->id, ipq->saddr, ipq->daddr, ipq->protocol);
|
||||
}
|
||||
|
||||
atomic_t ip_frag_mem = ATOMIC_INIT(0); /* Memory used for fragments */
|
||||
|
||||
/* Memory Tracking Functions. */
|
||||
static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
|
||||
{
|
||||
if (work)
|
||||
*work -= skb->truesize;
|
||||
atomic_sub(skb->truesize, &ip_frag_mem);
|
||||
atomic_sub(skb->truesize, &ip4_frags.mem);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
static __inline__ void frag_free_queue(struct ipq *qp, int *work)
|
||||
static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
|
||||
{
|
||||
if (work)
|
||||
*work -= sizeof(struct ipq);
|
||||
atomic_sub(sizeof(struct ipq), &ip_frag_mem);
|
||||
struct ipq *qp;
|
||||
|
||||
qp = container_of(q, struct ipq, q);
|
||||
if (qp->peer)
|
||||
inet_putpeer(qp->peer);
|
||||
kfree(qp);
|
||||
}
|
||||
|
||||
static __inline__ struct ipq *frag_alloc_queue(void)
|
||||
{
|
||||
struct ipq *qp = kmalloc(sizeof(struct ipq), GFP_ATOMIC);
|
||||
struct ipq *qp = kzalloc(sizeof(struct ipq), GFP_ATOMIC);
|
||||
|
||||
if (!qp)
|
||||
return NULL;
|
||||
atomic_add(sizeof(struct ipq), &ip_frag_mem);
|
||||
atomic_add(sizeof(struct ipq), &ip4_frags.mem);
|
||||
return qp;
|
||||
}
|
||||
|
||||
|
||||
/* Destruction primitives. */
|
||||
|
||||
/* Complete destruction of ipq. */
|
||||
static void ip_frag_destroy(struct ipq *qp, int *work)
|
||||
static __inline__ void ipq_put(struct ipq *ipq)
|
||||
{
|
||||
struct sk_buff *fp;
|
||||
|
||||
BUG_TRAP(qp->last_in&COMPLETE);
|
||||
BUG_TRAP(del_timer(&qp->timer) == 0);
|
||||
|
||||
if (qp->peer)
|
||||
inet_putpeer(qp->peer);
|
||||
|
||||
/* Release all fragment data. */
|
||||
fp = qp->fragments;
|
||||
while (fp) {
|
||||
struct sk_buff *xp = fp->next;
|
||||
|
||||
frag_kfree_skb(fp, work);
|
||||
fp = xp;
|
||||
}
|
||||
|
||||
/* Finally, release the queue descriptor itself. */
|
||||
frag_free_queue(qp, work);
|
||||
}
|
||||
|
||||
static __inline__ void ipq_put(struct ipq *ipq, int *work)
|
||||
{
|
||||
if (atomic_dec_and_test(&ipq->refcnt))
|
||||
ip_frag_destroy(ipq, work);
|
||||
inet_frag_put(&ipq->q, &ip4_frags);
|
||||
}
|
||||
|
||||
/* Kill ipq entry. It is not destroyed immediately,
|
||||
@ -228,14 +165,7 @@ static __inline__ void ipq_put(struct ipq *ipq, int *work)
|
||||
*/
|
||||
static void ipq_kill(struct ipq *ipq)
|
||||
{
|
||||
if (del_timer(&ipq->timer))
|
||||
atomic_dec(&ipq->refcnt);
|
||||
|
||||
if (!(ipq->last_in & COMPLETE)) {
|
||||
ipq_unlink(ipq);
|
||||
atomic_dec(&ipq->refcnt);
|
||||
ipq->last_in |= COMPLETE;
|
||||
}
|
||||
inet_frag_kill(&ipq->q, &ip4_frags);
|
||||
}
|
||||
|
||||
/* Memory limiting on fragments. Evictor trashes the oldest
|
||||
@ -243,33 +173,11 @@ static void ipq_kill(struct ipq *ipq)
|
||||
*/
|
||||
static void ip_evictor(void)
|
||||
{
|
||||
struct ipq *qp;
|
||||
struct list_head *tmp;
|
||||
int work;
|
||||
int evicted;
|
||||
|
||||
work = atomic_read(&ip_frag_mem) - sysctl_ipfrag_low_thresh;
|
||||
if (work <= 0)
|
||||
return;
|
||||
|
||||
while (work > 0) {
|
||||
read_lock(&ipfrag_lock);
|
||||
if (list_empty(&ipq_lru_list)) {
|
||||
read_unlock(&ipfrag_lock);
|
||||
return;
|
||||
}
|
||||
tmp = ipq_lru_list.next;
|
||||
qp = list_entry(tmp, struct ipq, lru_list);
|
||||
atomic_inc(&qp->refcnt);
|
||||
read_unlock(&ipfrag_lock);
|
||||
|
||||
spin_lock(&qp->lock);
|
||||
if (!(qp->last_in&COMPLETE))
|
||||
ipq_kill(qp);
|
||||
spin_unlock(&qp->lock);
|
||||
|
||||
ipq_put(qp, &work);
|
||||
IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
|
||||
}
|
||||
evicted = inet_frag_evictor(&ip4_frags);
|
||||
if (evicted)
|
||||
IP_ADD_STATS_BH(IPSTATS_MIB_REASMFAILS, evicted);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -279,9 +187,9 @@ static void ip_expire(unsigned long arg)
|
||||
{
|
||||
struct ipq *qp = (struct ipq *) arg;
|
||||
|
||||
spin_lock(&qp->lock);
|
||||
spin_lock(&qp->q.lock);
|
||||
|
||||
if (qp->last_in & COMPLETE)
|
||||
if (qp->q.last_in & COMPLETE)
|
||||
goto out;
|
||||
|
||||
ipq_kill(qp);
|
||||
@ -289,8 +197,8 @@ static void ip_expire(unsigned long arg)
|
||||
IP_INC_STATS_BH(IPSTATS_MIB_REASMTIMEOUT);
|
||||
IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
|
||||
|
||||
if ((qp->last_in&FIRST_IN) && qp->fragments != NULL) {
|
||||
struct sk_buff *head = qp->fragments;
|
||||
if ((qp->q.last_in&FIRST_IN) && qp->q.fragments != NULL) {
|
||||
struct sk_buff *head = qp->q.fragments;
|
||||
/* Send an ICMP "Fragment Reassembly Timeout" message. */
|
||||
if ((head->dev = dev_get_by_index(&init_net, qp->iif)) != NULL) {
|
||||
icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
|
||||
@ -298,8 +206,8 @@ static void ip_expire(unsigned long arg)
|
||||
}
|
||||
}
|
||||
out:
|
||||
spin_unlock(&qp->lock);
|
||||
ipq_put(qp, NULL);
|
||||
spin_unlock(&qp->q.lock);
|
||||
ipq_put(qp);
|
||||
}
|
||||
|
||||
/* Creation primitives. */
|
||||
@ -312,7 +220,7 @@ static struct ipq *ip_frag_intern(struct ipq *qp_in)
|
||||
#endif
|
||||
unsigned int hash;
|
||||
|
||||
write_lock(&ipfrag_lock);
|
||||
write_lock(&ip4_frags.lock);
|
||||
hash = ipqhashfn(qp_in->id, qp_in->saddr, qp_in->daddr,
|
||||
qp_in->protocol);
|
||||
#ifdef CONFIG_SMP
|
||||
@ -320,31 +228,31 @@ static struct ipq *ip_frag_intern(struct ipq *qp_in)
|
||||
* such entry could be created on other cpu, while we
|
||||
* promoted read lock to write lock.
|
||||
*/
|
||||
hlist_for_each_entry(qp, n, &ipq_hash[hash], list) {
|
||||
hlist_for_each_entry(qp, n, &ip4_frags.hash[hash], q.list) {
|
||||
if (qp->id == qp_in->id &&
|
||||
qp->saddr == qp_in->saddr &&
|
||||
qp->daddr == qp_in->daddr &&
|
||||
qp->protocol == qp_in->protocol &&
|
||||
qp->user == qp_in->user) {
|
||||
atomic_inc(&qp->refcnt);
|
||||
write_unlock(&ipfrag_lock);
|
||||
qp_in->last_in |= COMPLETE;
|
||||
ipq_put(qp_in, NULL);
|
||||
atomic_inc(&qp->q.refcnt);
|
||||
write_unlock(&ip4_frags.lock);
|
||||
qp_in->q.last_in |= COMPLETE;
|
||||
ipq_put(qp_in);
|
||||
return qp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
qp = qp_in;
|
||||
|
||||
if (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time))
|
||||
atomic_inc(&qp->refcnt);
|
||||
if (!mod_timer(&qp->q.timer, jiffies + ip4_frags_ctl.timeout))
|
||||
atomic_inc(&qp->q.refcnt);
|
||||
|
||||
atomic_inc(&qp->refcnt);
|
||||
hlist_add_head(&qp->list, &ipq_hash[hash]);
|
||||
INIT_LIST_HEAD(&qp->lru_list);
|
||||
list_add_tail(&qp->lru_list, &ipq_lru_list);
|
||||
ip_frag_nqueues++;
|
||||
write_unlock(&ipfrag_lock);
|
||||
atomic_inc(&qp->q.refcnt);
|
||||
hlist_add_head(&qp->q.list, &ip4_frags.hash[hash]);
|
||||
INIT_LIST_HEAD(&qp->q.lru_list);
|
||||
list_add_tail(&qp->q.lru_list, &ip4_frags.lru_list);
|
||||
ip4_frags.nqueues++;
|
||||
write_unlock(&ip4_frags.lock);
|
||||
return qp;
|
||||
}
|
||||
|
||||
@ -357,23 +265,18 @@ static struct ipq *ip_frag_create(struct iphdr *iph, u32 user)
|
||||
goto out_nomem;
|
||||
|
||||
qp->protocol = iph->protocol;
|
||||
qp->last_in = 0;
|
||||
qp->id = iph->id;
|
||||
qp->saddr = iph->saddr;
|
||||
qp->daddr = iph->daddr;
|
||||
qp->user = user;
|
||||
qp->len = 0;
|
||||
qp->meat = 0;
|
||||
qp->fragments = NULL;
|
||||
qp->iif = 0;
|
||||
qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;
|
||||
|
||||
/* Initialize a timer for this entry. */
|
||||
init_timer(&qp->timer);
|
||||
qp->timer.data = (unsigned long) qp; /* pointer to queue */
|
||||
qp->timer.function = ip_expire; /* expire function */
|
||||
spin_lock_init(&qp->lock);
|
||||
atomic_set(&qp->refcnt, 1);
|
||||
init_timer(&qp->q.timer);
|
||||
qp->q.timer.data = (unsigned long) qp; /* pointer to queue */
|
||||
qp->q.timer.function = ip_expire; /* expire function */
|
||||
spin_lock_init(&qp->q.lock);
|
||||
atomic_set(&qp->q.refcnt, 1);
|
||||
|
||||
return ip_frag_intern(qp);
|
||||
|
||||
@ -395,20 +298,20 @@ static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
|
||||
struct ipq *qp;
|
||||
struct hlist_node *n;
|
||||
|
||||
read_lock(&ipfrag_lock);
|
||||
read_lock(&ip4_frags.lock);
|
||||
hash = ipqhashfn(id, saddr, daddr, protocol);
|
||||
hlist_for_each_entry(qp, n, &ipq_hash[hash], list) {
|
||||
hlist_for_each_entry(qp, n, &ip4_frags.hash[hash], q.list) {
|
||||
if (qp->id == id &&
|
||||
qp->saddr == saddr &&
|
||||
qp->daddr == daddr &&
|
||||
qp->protocol == protocol &&
|
||||
qp->user == user) {
|
||||
atomic_inc(&qp->refcnt);
|
||||
read_unlock(&ipfrag_lock);
|
||||
atomic_inc(&qp->q.refcnt);
|
||||
read_unlock(&ip4_frags.lock);
|
||||
return qp;
|
||||
}
|
||||
}
|
||||
read_unlock(&ipfrag_lock);
|
||||
read_unlock(&ip4_frags.lock);
|
||||
|
||||
return ip_frag_create(iph, user);
|
||||
}
|
||||
@ -429,7 +332,7 @@ static inline int ip_frag_too_far(struct ipq *qp)
|
||||
end = atomic_inc_return(&peer->rid);
|
||||
qp->rid = end;
|
||||
|
||||
rc = qp->fragments && (end - start) > max;
|
||||
rc = qp->q.fragments && (end - start) > max;
|
||||
|
||||
if (rc) {
|
||||
IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
|
||||
@ -442,39 +345,42 @@ static int ip_frag_reinit(struct ipq *qp)
|
||||
{
|
||||
struct sk_buff *fp;
|
||||
|
||||
if (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time)) {
|
||||
atomic_inc(&qp->refcnt);
|
||||
if (!mod_timer(&qp->q.timer, jiffies + ip4_frags_ctl.timeout)) {
|
||||
atomic_inc(&qp->q.refcnt);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
fp = qp->fragments;
|
||||
fp = qp->q.fragments;
|
||||
do {
|
||||
struct sk_buff *xp = fp->next;
|
||||
frag_kfree_skb(fp, NULL);
|
||||
fp = xp;
|
||||
} while (fp);
|
||||
|
||||
qp->last_in = 0;
|
||||
qp->len = 0;
|
||||
qp->meat = 0;
|
||||
qp->fragments = NULL;
|
||||
qp->q.last_in = 0;
|
||||
qp->q.len = 0;
|
||||
qp->q.meat = 0;
|
||||
qp->q.fragments = NULL;
|
||||
qp->iif = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add new segment to existing queue. */
|
||||
static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
||||
static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
||||
{
|
||||
struct sk_buff *prev, *next;
|
||||
struct net_device *dev;
|
||||
int flags, offset;
|
||||
int ihl, end;
|
||||
int err = -ENOENT;
|
||||
|
||||
if (qp->last_in & COMPLETE)
|
||||
if (qp->q.last_in & COMPLETE)
|
||||
goto err;
|
||||
|
||||
if (!(IPCB(skb)->flags & IPSKB_FRAG_COMPLETE) &&
|
||||
unlikely(ip_frag_too_far(qp)) && unlikely(ip_frag_reinit(qp))) {
|
||||
unlikely(ip_frag_too_far(qp)) &&
|
||||
unlikely(err = ip_frag_reinit(qp))) {
|
||||
ipq_kill(qp);
|
||||
goto err;
|
||||
}
|
||||
@ -487,36 +393,40 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
||||
|
||||
/* Determine the position of this fragment. */
|
||||
end = offset + skb->len - ihl;
|
||||
err = -EINVAL;
|
||||
|
||||
/* Is this the final fragment? */
|
||||
if ((flags & IP_MF) == 0) {
|
||||
/* If we already have some bits beyond end
|
||||
* or have different end, the segment is corrrupted.
|
||||
*/
|
||||
if (end < qp->len ||
|
||||
((qp->last_in & LAST_IN) && end != qp->len))
|
||||
if (end < qp->q.len ||
|
||||
((qp->q.last_in & LAST_IN) && end != qp->q.len))
|
||||
goto err;
|
||||
qp->last_in |= LAST_IN;
|
||||
qp->len = end;
|
||||
qp->q.last_in |= LAST_IN;
|
||||
qp->q.len = end;
|
||||
} else {
|
||||
if (end&7) {
|
||||
end &= ~7;
|
||||
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
}
|
||||
if (end > qp->len) {
|
||||
if (end > qp->q.len) {
|
||||
/* Some bits beyond end -> corruption. */
|
||||
if (qp->last_in & LAST_IN)
|
||||
if (qp->q.last_in & LAST_IN)
|
||||
goto err;
|
||||
qp->len = end;
|
||||
qp->q.len = end;
|
||||
}
|
||||
}
|
||||
if (end == offset)
|
||||
goto err;
|
||||
|
||||
err = -ENOMEM;
|
||||
if (pskb_pull(skb, ihl) == NULL)
|
||||
goto err;
|
||||
if (pskb_trim_rcsum(skb, end-offset))
|
||||
|
||||
err = pskb_trim_rcsum(skb, end - offset);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
/* Find out which fragments are in front and at the back of us
|
||||
@ -524,7 +434,7 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
||||
* this fragment, right?
|
||||
*/
|
||||
prev = NULL;
|
||||
for (next = qp->fragments; next != NULL; next = next->next) {
|
||||
for (next = qp->q.fragments; next != NULL; next = next->next) {
|
||||
if (FRAG_CB(next)->offset >= offset)
|
||||
break; /* bingo! */
|
||||
prev = next;
|
||||
@ -539,8 +449,10 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
||||
|
||||
if (i > 0) {
|
||||
offset += i;
|
||||
err = -EINVAL;
|
||||
if (end <= offset)
|
||||
goto err;
|
||||
err = -ENOMEM;
|
||||
if (!pskb_pull(skb, i))
|
||||
goto err;
|
||||
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
|
||||
@ -548,6 +460,8 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
||||
}
|
||||
}
|
||||
|
||||
err = -ENOMEM;
|
||||
|
||||
while (next && FRAG_CB(next)->offset < end) {
|
||||
int i = end - FRAG_CB(next)->offset; /* overlap is 'i' bytes */
|
||||
|
||||
@ -558,7 +472,7 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
||||
if (!pskb_pull(next, i))
|
||||
goto err;
|
||||
FRAG_CB(next)->offset += i;
|
||||
qp->meat -= i;
|
||||
qp->q.meat -= i;
|
||||
if (next->ip_summed != CHECKSUM_UNNECESSARY)
|
||||
next->ip_summed = CHECKSUM_NONE;
|
||||
break;
|
||||
@ -573,9 +487,9 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
||||
if (prev)
|
||||
prev->next = next;
|
||||
else
|
||||
qp->fragments = next;
|
||||
qp->q.fragments = next;
|
||||
|
||||
qp->meat -= free_it->len;
|
||||
qp->q.meat -= free_it->len;
|
||||
frag_kfree_skb(free_it, NULL);
|
||||
}
|
||||
}
|
||||
@ -587,50 +501,77 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
||||
if (prev)
|
||||
prev->next = skb;
|
||||
else
|
||||
qp->fragments = skb;
|
||||
qp->q.fragments = skb;
|
||||
|
||||
if (skb->dev)
|
||||
qp->iif = skb->dev->ifindex;
|
||||
skb->dev = NULL;
|
||||
qp->stamp = skb->tstamp;
|
||||
qp->meat += skb->len;
|
||||
atomic_add(skb->truesize, &ip_frag_mem);
|
||||
dev = skb->dev;
|
||||
if (dev) {
|
||||
qp->iif = dev->ifindex;
|
||||
skb->dev = NULL;
|
||||
}
|
||||
qp->q.stamp = skb->tstamp;
|
||||
qp->q.meat += skb->len;
|
||||
atomic_add(skb->truesize, &ip4_frags.mem);
|
||||
if (offset == 0)
|
||||
qp->last_in |= FIRST_IN;
|
||||
qp->q.last_in |= FIRST_IN;
|
||||
|
||||
write_lock(&ipfrag_lock);
|
||||
list_move_tail(&qp->lru_list, &ipq_lru_list);
|
||||
write_unlock(&ipfrag_lock);
|
||||
if (qp->q.last_in == (FIRST_IN | LAST_IN) && qp->q.meat == qp->q.len)
|
||||
return ip_frag_reasm(qp, prev, dev);
|
||||
|
||||
return;
|
||||
write_lock(&ip4_frags.lock);
|
||||
list_move_tail(&qp->q.lru_list, &ip4_frags.lru_list);
|
||||
write_unlock(&ip4_frags.lock);
|
||||
return -EINPROGRESS;
|
||||
|
||||
err:
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Build a new IP datagram from all its fragments. */
|
||||
|
||||
static struct sk_buff *ip_frag_reasm(struct ipq *qp, struct net_device *dev)
|
||||
static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
|
||||
struct net_device *dev)
|
||||
{
|
||||
struct iphdr *iph;
|
||||
struct sk_buff *fp, *head = qp->fragments;
|
||||
struct sk_buff *fp, *head = qp->q.fragments;
|
||||
int len;
|
||||
int ihlen;
|
||||
int err;
|
||||
|
||||
ipq_kill(qp);
|
||||
|
||||
/* Make the one we just received the head. */
|
||||
if (prev) {
|
||||
head = prev->next;
|
||||
fp = skb_clone(head, GFP_ATOMIC);
|
||||
|
||||
if (!fp)
|
||||
goto out_nomem;
|
||||
|
||||
fp->next = head->next;
|
||||
prev->next = fp;
|
||||
|
||||
skb_morph(head, qp->q.fragments);
|
||||
head->next = qp->q.fragments->next;
|
||||
|
||||
kfree_skb(qp->q.fragments);
|
||||
qp->q.fragments = head;
|
||||
}
|
||||
|
||||
BUG_TRAP(head != NULL);
|
||||
BUG_TRAP(FRAG_CB(head)->offset == 0);
|
||||
|
||||
/* Allocate a new buffer for the datagram. */
|
||||
ihlen = ip_hdrlen(head);
|
||||
len = ihlen + qp->len;
|
||||
len = ihlen + qp->q.len;
|
||||
|
||||
err = -E2BIG;
|
||||
if (len > 65535)
|
||||
goto out_oversize;
|
||||
|
||||
/* Head of list must not be cloned. */
|
||||
err = -ENOMEM;
|
||||
if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC))
|
||||
goto out_nomem;
|
||||
|
||||
@ -654,12 +595,12 @@ static struct sk_buff *ip_frag_reasm(struct ipq *qp, struct net_device *dev)
|
||||
head->len -= clone->len;
|
||||
clone->csum = 0;
|
||||
clone->ip_summed = head->ip_summed;
|
||||
atomic_add(clone->truesize, &ip_frag_mem);
|
||||
atomic_add(clone->truesize, &ip4_frags.mem);
|
||||
}
|
||||
|
||||
skb_shinfo(head)->frag_list = head->next;
|
||||
skb_push(head, head->data - skb_network_header(head));
|
||||
atomic_sub(head->truesize, &ip_frag_mem);
|
||||
atomic_sub(head->truesize, &ip4_frags.mem);
|
||||
|
||||
for (fp=head->next; fp; fp = fp->next) {
|
||||
head->data_len += fp->len;
|
||||
@ -669,19 +610,19 @@ static struct sk_buff *ip_frag_reasm(struct ipq *qp, struct net_device *dev)
|
||||
else if (head->ip_summed == CHECKSUM_COMPLETE)
|
||||
head->csum = csum_add(head->csum, fp->csum);
|
||||
head->truesize += fp->truesize;
|
||||
atomic_sub(fp->truesize, &ip_frag_mem);
|
||||
atomic_sub(fp->truesize, &ip4_frags.mem);
|
||||
}
|
||||
|
||||
head->next = NULL;
|
||||
head->dev = dev;
|
||||
head->tstamp = qp->stamp;
|
||||
head->tstamp = qp->q.stamp;
|
||||
|
||||
iph = ip_hdr(head);
|
||||
iph->frag_off = 0;
|
||||
iph->tot_len = htons(len);
|
||||
IP_INC_STATS_BH(IPSTATS_MIB_REASMOKS);
|
||||
qp->fragments = NULL;
|
||||
return head;
|
||||
qp->q.fragments = NULL;
|
||||
return 0;
|
||||
|
||||
out_nomem:
|
||||
LIMIT_NETDEBUG(KERN_ERR "IP: queue_glue: no memory for gluing "
|
||||
@ -694,54 +635,46 @@ out_oversize:
|
||||
NIPQUAD(qp->saddr));
|
||||
out_fail:
|
||||
IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
|
||||
return NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Process an incoming IP datagram fragment. */
|
||||
struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user)
|
||||
int ip_defrag(struct sk_buff *skb, u32 user)
|
||||
{
|
||||
struct ipq *qp;
|
||||
struct net_device *dev;
|
||||
|
||||
IP_INC_STATS_BH(IPSTATS_MIB_REASMREQDS);
|
||||
|
||||
/* Start by cleaning up the memory. */
|
||||
if (atomic_read(&ip_frag_mem) > sysctl_ipfrag_high_thresh)
|
||||
if (atomic_read(&ip4_frags.mem) > ip4_frags_ctl.high_thresh)
|
||||
ip_evictor();
|
||||
|
||||
dev = skb->dev;
|
||||
|
||||
/* Lookup (or create) queue header */
|
||||
if ((qp = ip_find(ip_hdr(skb), user)) != NULL) {
|
||||
struct sk_buff *ret = NULL;
|
||||
int ret;
|
||||
|
||||
spin_lock(&qp->lock);
|
||||
spin_lock(&qp->q.lock);
|
||||
|
||||
ip_frag_queue(qp, skb);
|
||||
ret = ip_frag_queue(qp, skb);
|
||||
|
||||
if (qp->last_in == (FIRST_IN|LAST_IN) &&
|
||||
qp->meat == qp->len)
|
||||
ret = ip_frag_reasm(qp, dev);
|
||||
|
||||
spin_unlock(&qp->lock);
|
||||
ipq_put(qp, NULL);
|
||||
spin_unlock(&qp->q.lock);
|
||||
ipq_put(qp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
|
||||
kfree_skb(skb);
|
||||
return NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void __init ipfrag_init(void)
|
||||
{
|
||||
ipfrag_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
|
||||
(jiffies ^ (jiffies >> 6)));
|
||||
|
||||
init_timer(&ipfrag_secret_timer);
|
||||
ipfrag_secret_timer.function = ipfrag_secret_rebuild;
|
||||
ipfrag_secret_timer.expires = jiffies + sysctl_ipfrag_secret_interval;
|
||||
add_timer(&ipfrag_secret_timer);
|
||||
ip4_frags.ctl = &ip4_frags_ctl;
|
||||
ip4_frags.hashfn = ip4_hashfn;
|
||||
ip4_frags.destructor = ip4_frag_free;
|
||||
ip4_frags.skb_free = NULL;
|
||||
ip4_frags.qsize = sizeof(struct ipq);
|
||||
inet_frags_init(&ip4_frags);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(ip_defrag);
|
||||
|
@ -172,8 +172,7 @@ int ip_call_ra_chain(struct sk_buff *skb)
|
||||
(!sk->sk_bound_dev_if ||
|
||||
sk->sk_bound_dev_if == skb->dev->ifindex)) {
|
||||
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
|
||||
skb = ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN);
|
||||
if (skb == NULL) {
|
||||
if (ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN)) {
|
||||
read_unlock(&ip_ra_lock);
|
||||
return 1;
|
||||
}
|
||||
@ -196,7 +195,7 @@ int ip_call_ra_chain(struct sk_buff *skb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ip_local_deliver_finish(struct sk_buff *skb)
|
||||
static int ip_local_deliver_finish(struct sk_buff *skb)
|
||||
{
|
||||
__skb_pull(skb, ip_hdrlen(skb));
|
||||
|
||||
@ -265,8 +264,7 @@ int ip_local_deliver(struct sk_buff *skb)
|
||||
*/
|
||||
|
||||
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
|
||||
skb = ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER);
|
||||
if (!skb)
|
||||
if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -326,7 +324,7 @@ drop:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int ip_rcv_finish(struct sk_buff *skb)
|
||||
static int ip_rcv_finish(struct sk_buff *skb)
|
||||
{
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
struct rtable *rt;
|
||||
|
@ -202,7 +202,7 @@ static inline int ip_skb_dst_mtu(struct sk_buff *skb)
|
||||
skb->dst->dev->mtu : dst_mtu(skb->dst);
|
||||
}
|
||||
|
||||
static inline int ip_finish_output(struct sk_buff *skb)
|
||||
static int ip_finish_output(struct sk_buff *skb)
|
||||
{
|
||||
#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
|
||||
/* Policy lookup after SNAT yielded a new policy */
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/protocol.h>
|
||||
#include <net/tcp.h>
|
||||
@ -328,18 +329,18 @@ static inline void vs_seq_update(struct ip_vs_conn *cp, struct ip_vs_seq *vseq,
|
||||
spin_unlock(&cp->lock);
|
||||
}
|
||||
|
||||
static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb,
|
||||
static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, struct sk_buff *skb,
|
||||
struct ip_vs_app *app)
|
||||
{
|
||||
int diff;
|
||||
const unsigned int tcp_offset = ip_hdrlen(*pskb);
|
||||
const unsigned int tcp_offset = ip_hdrlen(skb);
|
||||
struct tcphdr *th;
|
||||
__u32 seq;
|
||||
|
||||
if (!ip_vs_make_skb_writable(pskb, tcp_offset + sizeof(*th)))
|
||||
if (!skb_make_writable(skb, tcp_offset + sizeof(*th)))
|
||||
return 0;
|
||||
|
||||
th = (struct tcphdr *)(skb_network_header(*pskb) + tcp_offset);
|
||||
th = (struct tcphdr *)(skb_network_header(skb) + tcp_offset);
|
||||
|
||||
/*
|
||||
* Remember seq number in case this pkt gets resized
|
||||
@ -360,7 +361,7 @@ static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb,
|
||||
if (app->pkt_out == NULL)
|
||||
return 1;
|
||||
|
||||
if (!app->pkt_out(app, cp, pskb, &diff))
|
||||
if (!app->pkt_out(app, cp, skb, &diff))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@ -378,7 +379,7 @@ static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb,
|
||||
* called by ipvs packet handler, assumes previously checked cp!=NULL
|
||||
* returns false if it can't handle packet (oom)
|
||||
*/
|
||||
int ip_vs_app_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb)
|
||||
int ip_vs_app_pkt_out(struct ip_vs_conn *cp, struct sk_buff *skb)
|
||||
{
|
||||
struct ip_vs_app *app;
|
||||
|
||||
@ -391,7 +392,7 @@ int ip_vs_app_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb)
|
||||
|
||||
/* TCP is complicated */
|
||||
if (cp->protocol == IPPROTO_TCP)
|
||||
return app_tcp_pkt_out(cp, pskb, app);
|
||||
return app_tcp_pkt_out(cp, skb, app);
|
||||
|
||||
/*
|
||||
* Call private output hook function
|
||||
@ -399,22 +400,22 @@ int ip_vs_app_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb)
|
||||
if (app->pkt_out == NULL)
|
||||
return 1;
|
||||
|
||||
return app->pkt_out(app, cp, pskb, NULL);
|
||||
return app->pkt_out(app, cp, skb, NULL);
|
||||
}
|
||||
|
||||
|
||||
static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb,
|
||||
static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, struct sk_buff *skb,
|
||||
struct ip_vs_app *app)
|
||||
{
|
||||
int diff;
|
||||
const unsigned int tcp_offset = ip_hdrlen(*pskb);
|
||||
const unsigned int tcp_offset = ip_hdrlen(skb);
|
||||
struct tcphdr *th;
|
||||
__u32 seq;
|
||||
|
||||
if (!ip_vs_make_skb_writable(pskb, tcp_offset + sizeof(*th)))
|
||||
if (!skb_make_writable(skb, tcp_offset + sizeof(*th)))
|
||||
return 0;
|
||||
|
||||
th = (struct tcphdr *)(skb_network_header(*pskb) + tcp_offset);
|
||||
th = (struct tcphdr *)(skb_network_header(skb) + tcp_offset);
|
||||
|
||||
/*
|
||||
* Remember seq number in case this pkt gets resized
|
||||
@ -435,7 +436,7 @@ static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb,
|
||||
if (app->pkt_in == NULL)
|
||||
return 1;
|
||||
|
||||
if (!app->pkt_in(app, cp, pskb, &diff))
|
||||
if (!app->pkt_in(app, cp, skb, &diff))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@ -453,7 +454,7 @@ static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb,
|
||||
* called by ipvs packet handler, assumes previously checked cp!=NULL.
|
||||
* returns false if can't handle packet (oom).
|
||||
*/
|
||||
int ip_vs_app_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb)
|
||||
int ip_vs_app_pkt_in(struct ip_vs_conn *cp, struct sk_buff *skb)
|
||||
{
|
||||
struct ip_vs_app *app;
|
||||
|
||||
@ -466,7 +467,7 @@ int ip_vs_app_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb)
|
||||
|
||||
/* TCP is complicated */
|
||||
if (cp->protocol == IPPROTO_TCP)
|
||||
return app_tcp_pkt_in(cp, pskb, app);
|
||||
return app_tcp_pkt_in(cp, skb, app);
|
||||
|
||||
/*
|
||||
* Call private input hook function
|
||||
@ -474,7 +475,7 @@ int ip_vs_app_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb)
|
||||
if (app->pkt_in == NULL)
|
||||
return 1;
|
||||
|
||||
return app->pkt_in(app, cp, pskb, NULL);
|
||||
return app->pkt_in(app, cp, skb, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,7 +58,6 @@ EXPORT_SYMBOL(ip_vs_conn_put);
|
||||
#ifdef CONFIG_IP_VS_DEBUG
|
||||
EXPORT_SYMBOL(ip_vs_get_debug_level);
|
||||
#endif
|
||||
EXPORT_SYMBOL(ip_vs_make_skb_writable);
|
||||
|
||||
|
||||
/* ID used in ICMP lookups */
|
||||
@ -163,42 +162,6 @@ ip_vs_set_state(struct ip_vs_conn *cp, int direction,
|
||||
}
|
||||
|
||||
|
||||
int ip_vs_make_skb_writable(struct sk_buff **pskb, int writable_len)
|
||||
{
|
||||
struct sk_buff *skb = *pskb;
|
||||
|
||||
/* skb is already used, better copy skb and its payload */
|
||||
if (unlikely(skb_shared(skb) || skb->sk))
|
||||
goto copy_skb;
|
||||
|
||||
/* skb data is already used, copy it */
|
||||
if (unlikely(skb_cloned(skb)))
|
||||
goto copy_data;
|
||||
|
||||
return pskb_may_pull(skb, writable_len);
|
||||
|
||||
copy_data:
|
||||
if (unlikely(writable_len > skb->len))
|
||||
return 0;
|
||||
return !pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
|
||||
|
||||
copy_skb:
|
||||
if (unlikely(writable_len > skb->len))
|
||||
return 0;
|
||||
skb = skb_copy(skb, GFP_ATOMIC);
|
||||
if (!skb)
|
||||
return 0;
|
||||
BUG_ON(skb_is_nonlinear(skb));
|
||||
|
||||
/* Rest of kernel will get very unhappy if we pass it a
|
||||
suddenly-orphaned skbuff */
|
||||
if ((*pskb)->sk)
|
||||
skb_set_owner_w(skb, (*pskb)->sk);
|
||||
kfree_skb(*pskb);
|
||||
*pskb = skb;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* IPVS persistent scheduling function
|
||||
* It creates a connection entry according to its template if exists,
|
||||
@ -525,12 +488,12 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
|
||||
* for VS/NAT.
|
||||
*/
|
||||
static unsigned int ip_vs_post_routing(unsigned int hooknum,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
if (!((*pskb)->ipvs_property))
|
||||
if (!skb->ipvs_property)
|
||||
return NF_ACCEPT;
|
||||
/* The packet was sent from IPVS, exit this chain */
|
||||
return NF_STOP;
|
||||
@ -541,13 +504,14 @@ __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
|
||||
return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
|
||||
}
|
||||
|
||||
static inline struct sk_buff *
|
||||
ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
|
||||
static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
|
||||
{
|
||||
skb = ip_defrag(skb, user);
|
||||
if (skb)
|
||||
int err = ip_defrag(skb, user);
|
||||
|
||||
if (!err)
|
||||
ip_send_check(ip_hdr(skb));
|
||||
return skb;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -605,9 +569,8 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
|
||||
* Currently handles error types - unreachable, quench, ttl exceeded.
|
||||
* (Only used in VS/NAT)
|
||||
*/
|
||||
static int ip_vs_out_icmp(struct sk_buff **pskb, int *related)
|
||||
static int ip_vs_out_icmp(struct sk_buff *skb, int *related)
|
||||
{
|
||||
struct sk_buff *skb = *pskb;
|
||||
struct iphdr *iph;
|
||||
struct icmphdr _icmph, *ic;
|
||||
struct iphdr _ciph, *cih; /* The ip header contained within the ICMP */
|
||||
@ -619,10 +582,8 @@ static int ip_vs_out_icmp(struct sk_buff **pskb, int *related)
|
||||
|
||||
/* reassemble IP fragments */
|
||||
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
|
||||
skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT);
|
||||
if (!skb)
|
||||
if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT))
|
||||
return NF_STOLEN;
|
||||
*pskb = skb;
|
||||
}
|
||||
|
||||
iph = ip_hdr(skb);
|
||||
@ -690,9 +651,8 @@ static int ip_vs_out_icmp(struct sk_buff **pskb, int *related)
|
||||
|
||||
if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol)
|
||||
offset += 2 * sizeof(__u16);
|
||||
if (!ip_vs_make_skb_writable(pskb, offset))
|
||||
if (!skb_make_writable(skb, offset))
|
||||
goto out;
|
||||
skb = *pskb;
|
||||
|
||||
ip_vs_nat_icmp(skb, pp, cp, 1);
|
||||
|
||||
@ -724,11 +684,10 @@ static inline int is_tcp_reset(const struct sk_buff *skb)
|
||||
* rewrite addresses of the packet and send it on its way...
|
||||
*/
|
||||
static unsigned int
|
||||
ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
|
||||
ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
struct sk_buff *skb = *pskb;
|
||||
struct iphdr *iph;
|
||||
struct ip_vs_protocol *pp;
|
||||
struct ip_vs_conn *cp;
|
||||
@ -741,11 +700,10 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
|
||||
|
||||
iph = ip_hdr(skb);
|
||||
if (unlikely(iph->protocol == IPPROTO_ICMP)) {
|
||||
int related, verdict = ip_vs_out_icmp(pskb, &related);
|
||||
int related, verdict = ip_vs_out_icmp(skb, &related);
|
||||
|
||||
if (related)
|
||||
return verdict;
|
||||
skb = *pskb;
|
||||
iph = ip_hdr(skb);
|
||||
}
|
||||
|
||||
@ -756,11 +714,9 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
|
||||
/* reassemble IP fragments */
|
||||
if (unlikely(iph->frag_off & htons(IP_MF|IP_OFFSET) &&
|
||||
!pp->dont_defrag)) {
|
||||
skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT);
|
||||
if (!skb)
|
||||
if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT))
|
||||
return NF_STOLEN;
|
||||
iph = ip_hdr(skb);
|
||||
*pskb = skb;
|
||||
}
|
||||
|
||||
ihl = iph->ihl << 2;
|
||||
@ -802,13 +758,12 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
|
||||
|
||||
IP_VS_DBG_PKT(11, pp, skb, 0, "Outgoing packet");
|
||||
|
||||
if (!ip_vs_make_skb_writable(pskb, ihl))
|
||||
if (!skb_make_writable(skb, ihl))
|
||||
goto drop;
|
||||
|
||||
/* mangle the packet */
|
||||
if (pp->snat_handler && !pp->snat_handler(pskb, pp, cp))
|
||||
if (pp->snat_handler && !pp->snat_handler(skb, pp, cp))
|
||||
goto drop;
|
||||
skb = *pskb;
|
||||
ip_hdr(skb)->saddr = cp->vaddr;
|
||||
ip_send_check(ip_hdr(skb));
|
||||
|
||||
@ -818,9 +773,8 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
|
||||
* if it came from this machine itself. So re-compute
|
||||
* the routing information.
|
||||
*/
|
||||
if (ip_route_me_harder(pskb, RTN_LOCAL) != 0)
|
||||
if (ip_route_me_harder(skb, RTN_LOCAL) != 0)
|
||||
goto drop;
|
||||
skb = *pskb;
|
||||
|
||||
IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT");
|
||||
|
||||
@ -835,7 +789,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
|
||||
|
||||
drop:
|
||||
ip_vs_conn_put(cp);
|
||||
kfree_skb(*pskb);
|
||||
kfree_skb(skb);
|
||||
return NF_STOLEN;
|
||||
}
|
||||
|
||||
@ -847,9 +801,8 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
|
||||
* Currently handles error types - unreachable, quench, ttl exceeded.
|
||||
*/
|
||||
static int
|
||||
ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
|
||||
ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
|
||||
{
|
||||
struct sk_buff *skb = *pskb;
|
||||
struct iphdr *iph;
|
||||
struct icmphdr _icmph, *ic;
|
||||
struct iphdr _ciph, *cih; /* The ip header contained within the ICMP */
|
||||
@ -861,12 +814,9 @@ ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
|
||||
|
||||
/* reassemble IP fragments */
|
||||
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
|
||||
skb = ip_vs_gather_frags(skb,
|
||||
hooknum == NF_IP_LOCAL_IN ?
|
||||
IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD);
|
||||
if (!skb)
|
||||
if (ip_vs_gather_frags(skb, hooknum == NF_IP_LOCAL_IN ?
|
||||
IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD))
|
||||
return NF_STOLEN;
|
||||
*pskb = skb;
|
||||
}
|
||||
|
||||
iph = ip_hdr(skb);
|
||||
@ -945,11 +895,10 @@ ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
|
||||
* and send it on its way...
|
||||
*/
|
||||
static unsigned int
|
||||
ip_vs_in(unsigned int hooknum, struct sk_buff **pskb,
|
||||
ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
struct sk_buff *skb = *pskb;
|
||||
struct iphdr *iph;
|
||||
struct ip_vs_protocol *pp;
|
||||
struct ip_vs_conn *cp;
|
||||
@ -971,11 +920,10 @@ ip_vs_in(unsigned int hooknum, struct sk_buff **pskb,
|
||||
|
||||
iph = ip_hdr(skb);
|
||||
if (unlikely(iph->protocol == IPPROTO_ICMP)) {
|
||||
int related, verdict = ip_vs_in_icmp(pskb, &related, hooknum);
|
||||
int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
|
||||
|
||||
if (related)
|
||||
return verdict;
|
||||
skb = *pskb;
|
||||
iph = ip_hdr(skb);
|
||||
}
|
||||
|
||||
@ -1056,16 +1004,16 @@ ip_vs_in(unsigned int hooknum, struct sk_buff **pskb,
|
||||
* and send them to ip_vs_in_icmp.
|
||||
*/
|
||||
static unsigned int
|
||||
ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff **pskb,
|
||||
ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
int r;
|
||||
|
||||
if (ip_hdr(*pskb)->protocol != IPPROTO_ICMP)
|
||||
if (ip_hdr(skb)->protocol != IPPROTO_ICMP)
|
||||
return NF_ACCEPT;
|
||||
|
||||
return ip_vs_in_icmp(pskb, &r, hooknum);
|
||||
return ip_vs_in_icmp(skb, &r, hooknum);
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <net/protocol.h>
|
||||
#include <net/tcp.h>
|
||||
#include <asm/unaligned.h>
|
||||
@ -135,7 +136,7 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit,
|
||||
* xxx,xxx,xxx,xxx is the server address, ppp,ppp is the server port number.
|
||||
*/
|
||||
static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
|
||||
struct sk_buff **pskb, int *diff)
|
||||
struct sk_buff *skb, int *diff)
|
||||
{
|
||||
struct iphdr *iph;
|
||||
struct tcphdr *th;
|
||||
@ -155,14 +156,14 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
|
||||
return 1;
|
||||
|
||||
/* Linear packets are much easier to deal with. */
|
||||
if (!ip_vs_make_skb_writable(pskb, (*pskb)->len))
|
||||
if (!skb_make_writable(skb, skb->len))
|
||||
return 0;
|
||||
|
||||
if (cp->app_data == &ip_vs_ftp_pasv) {
|
||||
iph = ip_hdr(*pskb);
|
||||
iph = ip_hdr(skb);
|
||||
th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
|
||||
data = (char *)th + (th->doff << 2);
|
||||
data_limit = skb_tail_pointer(*pskb);
|
||||
data_limit = skb_tail_pointer(skb);
|
||||
|
||||
if (ip_vs_ftp_get_addrport(data, data_limit,
|
||||
SERVER_STRING,
|
||||
@ -213,7 +214,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
|
||||
memcpy(start, buf, buf_len);
|
||||
ret = 1;
|
||||
} else {
|
||||
ret = !ip_vs_skb_replace(*pskb, GFP_ATOMIC, start,
|
||||
ret = !ip_vs_skb_replace(skb, GFP_ATOMIC, start,
|
||||
end-start, buf, buf_len);
|
||||
}
|
||||
|
||||
@ -238,7 +239,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
|
||||
* the client.
|
||||
*/
|
||||
static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
|
||||
struct sk_buff **pskb, int *diff)
|
||||
struct sk_buff *skb, int *diff)
|
||||
{
|
||||
struct iphdr *iph;
|
||||
struct tcphdr *th;
|
||||
@ -256,20 +257,20 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
|
||||
return 1;
|
||||
|
||||
/* Linear packets are much easier to deal with. */
|
||||
if (!ip_vs_make_skb_writable(pskb, (*pskb)->len))
|
||||
if (!skb_make_writable(skb, skb->len))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Detecting whether it is passive
|
||||
*/
|
||||
iph = ip_hdr(*pskb);
|
||||
iph = ip_hdr(skb);
|
||||
th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
|
||||
|
||||
/* Since there may be OPTIONS in the TCP packet and the HLEN is
|
||||
the length of the header in 32-bit multiples, it is accurate
|
||||
to calculate data address by th+HLEN*4 */
|
||||
data = data_start = (char *)th + (th->doff << 2);
|
||||
data_limit = skb_tail_pointer(*pskb);
|
||||
data_limit = skb_tail_pointer(skb);
|
||||
|
||||
while (data <= data_limit - 6) {
|
||||
if (strnicmp(data, "PASV\r\n", 6) == 0) {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <linux/tcp.h> /* for tcphdr */
|
||||
#include <net/ip.h>
|
||||
#include <net/tcp.h> /* for csum_tcpudp_magic */
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
|
||||
#include <net/ip_vs.h>
|
||||
@ -122,27 +123,27 @@ tcp_fast_csum_update(struct tcphdr *tcph, __be32 oldip, __be32 newip,
|
||||
|
||||
|
||||
static int
|
||||
tcp_snat_handler(struct sk_buff **pskb,
|
||||
tcp_snat_handler(struct sk_buff *skb,
|
||||
struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
|
||||
{
|
||||
struct tcphdr *tcph;
|
||||
const unsigned int tcphoff = ip_hdrlen(*pskb);
|
||||
const unsigned int tcphoff = ip_hdrlen(skb);
|
||||
|
||||
/* csum_check requires unshared skb */
|
||||
if (!ip_vs_make_skb_writable(pskb, tcphoff+sizeof(*tcph)))
|
||||
if (!skb_make_writable(skb, tcphoff+sizeof(*tcph)))
|
||||
return 0;
|
||||
|
||||
if (unlikely(cp->app != NULL)) {
|
||||
/* Some checks before mangling */
|
||||
if (pp->csum_check && !pp->csum_check(*pskb, pp))
|
||||
if (pp->csum_check && !pp->csum_check(skb, pp))
|
||||
return 0;
|
||||
|
||||
/* Call application helper if needed */
|
||||
if (!ip_vs_app_pkt_out(cp, pskb))
|
||||
if (!ip_vs_app_pkt_out(cp, skb))
|
||||
return 0;
|
||||
}
|
||||
|
||||
tcph = (void *)ip_hdr(*pskb) + tcphoff;
|
||||
tcph = (void *)ip_hdr(skb) + tcphoff;
|
||||
tcph->source = cp->vport;
|
||||
|
||||
/* Adjust TCP checksums */
|
||||
@ -150,17 +151,15 @@ tcp_snat_handler(struct sk_buff **pskb,
|
||||
/* Only port and addr are changed, do fast csum update */
|
||||
tcp_fast_csum_update(tcph, cp->daddr, cp->vaddr,
|
||||
cp->dport, cp->vport);
|
||||
if ((*pskb)->ip_summed == CHECKSUM_COMPLETE)
|
||||
(*pskb)->ip_summed = CHECKSUM_NONE;
|
||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
} else {
|
||||
/* full checksum calculation */
|
||||
tcph->check = 0;
|
||||
(*pskb)->csum = skb_checksum(*pskb, tcphoff,
|
||||
(*pskb)->len - tcphoff, 0);
|
||||
skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0);
|
||||
tcph->check = csum_tcpudp_magic(cp->vaddr, cp->caddr,
|
||||
(*pskb)->len - tcphoff,
|
||||
cp->protocol,
|
||||
(*pskb)->csum);
|
||||
skb->len - tcphoff,
|
||||
cp->protocol, skb->csum);
|
||||
IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
|
||||
pp->name, tcph->check,
|
||||
(char*)&(tcph->check) - (char*)tcph);
|
||||
@ -170,30 +169,30 @@ tcp_snat_handler(struct sk_buff **pskb,
|
||||
|
||||
|
||||
static int
|
||||
tcp_dnat_handler(struct sk_buff **pskb,
|
||||
tcp_dnat_handler(struct sk_buff *skb,
|
||||
struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
|
||||
{
|
||||
struct tcphdr *tcph;
|
||||
const unsigned int tcphoff = ip_hdrlen(*pskb);
|
||||
const unsigned int tcphoff = ip_hdrlen(skb);
|
||||
|
||||
/* csum_check requires unshared skb */
|
||||
if (!ip_vs_make_skb_writable(pskb, tcphoff+sizeof(*tcph)))
|
||||
if (!skb_make_writable(skb, tcphoff+sizeof(*tcph)))
|
||||
return 0;
|
||||
|
||||
if (unlikely(cp->app != NULL)) {
|
||||
/* Some checks before mangling */
|
||||
if (pp->csum_check && !pp->csum_check(*pskb, pp))
|
||||
if (pp->csum_check && !pp->csum_check(skb, pp))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Attempt ip_vs_app call.
|
||||
* It will fix ip_vs_conn and iph ack_seq stuff
|
||||
*/
|
||||
if (!ip_vs_app_pkt_in(cp, pskb))
|
||||
if (!ip_vs_app_pkt_in(cp, skb))
|
||||
return 0;
|
||||
}
|
||||
|
||||
tcph = (void *)ip_hdr(*pskb) + tcphoff;
|
||||
tcph = (void *)ip_hdr(skb) + tcphoff;
|
||||
tcph->dest = cp->dport;
|
||||
|
||||
/*
|
||||
@ -203,18 +202,16 @@ tcp_dnat_handler(struct sk_buff **pskb,
|
||||
/* Only port and addr are changed, do fast csum update */
|
||||
tcp_fast_csum_update(tcph, cp->vaddr, cp->daddr,
|
||||
cp->vport, cp->dport);
|
||||
if ((*pskb)->ip_summed == CHECKSUM_COMPLETE)
|
||||
(*pskb)->ip_summed = CHECKSUM_NONE;
|
||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
} else {
|
||||
/* full checksum calculation */
|
||||
tcph->check = 0;
|
||||
(*pskb)->csum = skb_checksum(*pskb, tcphoff,
|
||||
(*pskb)->len - tcphoff, 0);
|
||||
skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0);
|
||||
tcph->check = csum_tcpudp_magic(cp->caddr, cp->daddr,
|
||||
(*pskb)->len - tcphoff,
|
||||
cp->protocol,
|
||||
(*pskb)->csum);
|
||||
(*pskb)->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
skb->len - tcphoff,
|
||||
cp->protocol, skb->csum);
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/udp.h>
|
||||
|
||||
@ -129,29 +130,29 @@ udp_fast_csum_update(struct udphdr *uhdr, __be32 oldip, __be32 newip,
|
||||
}
|
||||
|
||||
static int
|
||||
udp_snat_handler(struct sk_buff **pskb,
|
||||
udp_snat_handler(struct sk_buff *skb,
|
||||
struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
|
||||
{
|
||||
struct udphdr *udph;
|
||||
const unsigned int udphoff = ip_hdrlen(*pskb);
|
||||
const unsigned int udphoff = ip_hdrlen(skb);
|
||||
|
||||
/* csum_check requires unshared skb */
|
||||
if (!ip_vs_make_skb_writable(pskb, udphoff+sizeof(*udph)))
|
||||
if (!skb_make_writable(skb, udphoff+sizeof(*udph)))
|
||||
return 0;
|
||||
|
||||
if (unlikely(cp->app != NULL)) {
|
||||
/* Some checks before mangling */
|
||||
if (pp->csum_check && !pp->csum_check(*pskb, pp))
|
||||
if (pp->csum_check && !pp->csum_check(skb, pp))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Call application helper if needed
|
||||
*/
|
||||
if (!ip_vs_app_pkt_out(cp, pskb))
|
||||
if (!ip_vs_app_pkt_out(cp, skb))
|
||||
return 0;
|
||||
}
|
||||
|
||||
udph = (void *)ip_hdr(*pskb) + udphoff;
|
||||
udph = (void *)ip_hdr(skb) + udphoff;
|
||||
udph->source = cp->vport;
|
||||
|
||||
/*
|
||||
@ -161,17 +162,15 @@ udp_snat_handler(struct sk_buff **pskb,
|
||||
/* Only port and addr are changed, do fast csum update */
|
||||
udp_fast_csum_update(udph, cp->daddr, cp->vaddr,
|
||||
cp->dport, cp->vport);
|
||||
if ((*pskb)->ip_summed == CHECKSUM_COMPLETE)
|
||||
(*pskb)->ip_summed = CHECKSUM_NONE;
|
||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
} else {
|
||||
/* full checksum calculation */
|
||||
udph->check = 0;
|
||||
(*pskb)->csum = skb_checksum(*pskb, udphoff,
|
||||
(*pskb)->len - udphoff, 0);
|
||||
skb->csum = skb_checksum(skb, udphoff, skb->len - udphoff, 0);
|
||||
udph->check = csum_tcpudp_magic(cp->vaddr, cp->caddr,
|
||||
(*pskb)->len - udphoff,
|
||||
cp->protocol,
|
||||
(*pskb)->csum);
|
||||
skb->len - udphoff,
|
||||
cp->protocol, skb->csum);
|
||||
if (udph->check == 0)
|
||||
udph->check = CSUM_MANGLED_0;
|
||||
IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
|
||||
@ -183,30 +182,30 @@ udp_snat_handler(struct sk_buff **pskb,
|
||||
|
||||
|
||||
static int
|
||||
udp_dnat_handler(struct sk_buff **pskb,
|
||||
udp_dnat_handler(struct sk_buff *skb,
|
||||
struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
|
||||
{
|
||||
struct udphdr *udph;
|
||||
unsigned int udphoff = ip_hdrlen(*pskb);
|
||||
unsigned int udphoff = ip_hdrlen(skb);
|
||||
|
||||
/* csum_check requires unshared skb */
|
||||
if (!ip_vs_make_skb_writable(pskb, udphoff+sizeof(*udph)))
|
||||
if (!skb_make_writable(skb, udphoff+sizeof(*udph)))
|
||||
return 0;
|
||||
|
||||
if (unlikely(cp->app != NULL)) {
|
||||
/* Some checks before mangling */
|
||||
if (pp->csum_check && !pp->csum_check(*pskb, pp))
|
||||
if (pp->csum_check && !pp->csum_check(skb, pp))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Attempt ip_vs_app call.
|
||||
* It will fix ip_vs_conn
|
||||
*/
|
||||
if (!ip_vs_app_pkt_in(cp, pskb))
|
||||
if (!ip_vs_app_pkt_in(cp, skb))
|
||||
return 0;
|
||||
}
|
||||
|
||||
udph = (void *)ip_hdr(*pskb) + udphoff;
|
||||
udph = (void *)ip_hdr(skb) + udphoff;
|
||||
udph->dest = cp->dport;
|
||||
|
||||
/*
|
||||
@ -216,20 +215,18 @@ udp_dnat_handler(struct sk_buff **pskb,
|
||||
/* Only port and addr are changed, do fast csum update */
|
||||
udp_fast_csum_update(udph, cp->vaddr, cp->daddr,
|
||||
cp->vport, cp->dport);
|
||||
if ((*pskb)->ip_summed == CHECKSUM_COMPLETE)
|
||||
(*pskb)->ip_summed = CHECKSUM_NONE;
|
||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
} else {
|
||||
/* full checksum calculation */
|
||||
udph->check = 0;
|
||||
(*pskb)->csum = skb_checksum(*pskb, udphoff,
|
||||
(*pskb)->len - udphoff, 0);
|
||||
skb->csum = skb_checksum(skb, udphoff, skb->len - udphoff, 0);
|
||||
udph->check = csum_tcpudp_magic(cp->caddr, cp->daddr,
|
||||
(*pskb)->len - udphoff,
|
||||
cp->protocol,
|
||||
(*pskb)->csum);
|
||||
skb->len - udphoff,
|
||||
cp->protocol, skb->csum);
|
||||
if (udph->check == 0)
|
||||
udph->check = CSUM_MANGLED_0;
|
||||
(*pskb)->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
||||
}
|
||||
|
||||
/* copy-on-write the packet before mangling it */
|
||||
if (!ip_vs_make_skb_writable(&skb, sizeof(struct iphdr)))
|
||||
if (!skb_make_writable(skb, sizeof(struct iphdr)))
|
||||
goto tx_error_put;
|
||||
|
||||
if (skb_cow(skb, rt->u.dst.dev->hard_header_len))
|
||||
@ -264,7 +264,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
||||
skb->dst = &rt->u.dst;
|
||||
|
||||
/* mangle the packet */
|
||||
if (pp->dnat_handler && !pp->dnat_handler(&skb, pp, cp))
|
||||
if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp))
|
||||
goto tx_error;
|
||||
ip_hdr(skb)->daddr = cp->daddr;
|
||||
ip_send_check(ip_hdr(skb));
|
||||
@ -529,7 +529,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
||||
}
|
||||
|
||||
/* copy-on-write the packet before mangling it */
|
||||
if (!ip_vs_make_skb_writable(&skb, offset))
|
||||
if (!skb_make_writable(skb, offset))
|
||||
goto tx_error_put;
|
||||
|
||||
if (skb_cow(skb, rt->u.dst.dev->hard_header_len))
|
||||
|
@ -3,14 +3,15 @@
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/route.h>
|
||||
#include <net/xfrm.h>
|
||||
#include <net/ip.h>
|
||||
|
||||
/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
|
||||
int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
|
||||
int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
|
||||
{
|
||||
const struct iphdr *iph = ip_hdr(*pskb);
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
struct rtable *rt;
|
||||
struct flowi fl = {};
|
||||
struct dst_entry *odst;
|
||||
@ -29,14 +30,14 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
|
||||
if (type == RTN_LOCAL)
|
||||
fl.nl_u.ip4_u.saddr = iph->saddr;
|
||||
fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
|
||||
fl.oif = (*pskb)->sk ? (*pskb)->sk->sk_bound_dev_if : 0;
|
||||
fl.mark = (*pskb)->mark;
|
||||
fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
|
||||
fl.mark = skb->mark;
|
||||
if (ip_route_output_key(&rt, &fl) != 0)
|
||||
return -1;
|
||||
|
||||
/* Drop old route. */
|
||||
dst_release((*pskb)->dst);
|
||||
(*pskb)->dst = &rt->u.dst;
|
||||
dst_release(skb->dst);
|
||||
skb->dst = &rt->u.dst;
|
||||
} else {
|
||||
/* non-local src, find valid iif to satisfy
|
||||
* rp-filter when calling ip_route_input. */
|
||||
@ -44,8 +45,8 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
|
||||
if (ip_route_output_key(&rt, &fl) != 0)
|
||||
return -1;
|
||||
|
||||
odst = (*pskb)->dst;
|
||||
if (ip_route_input(*pskb, iph->daddr, iph->saddr,
|
||||
odst = skb->dst;
|
||||
if (ip_route_input(skb, iph->daddr, iph->saddr,
|
||||
RT_TOS(iph->tos), rt->u.dst.dev) != 0) {
|
||||
dst_release(&rt->u.dst);
|
||||
return -1;
|
||||
@ -54,70 +55,54 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
|
||||
dst_release(odst);
|
||||
}
|
||||
|
||||
if ((*pskb)->dst->error)
|
||||
if (skb->dst->error)
|
||||
return -1;
|
||||
|
||||
#ifdef CONFIG_XFRM
|
||||
if (!(IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED) &&
|
||||
xfrm_decode_session(*pskb, &fl, AF_INET) == 0)
|
||||
if (xfrm_lookup(&(*pskb)->dst, &fl, (*pskb)->sk, 0))
|
||||
if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
|
||||
xfrm_decode_session(skb, &fl, AF_INET) == 0)
|
||||
if (xfrm_lookup(&skb->dst, &fl, skb->sk, 0))
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
/* Change in oif may mean change in hh_len. */
|
||||
hh_len = (*pskb)->dst->dev->hard_header_len;
|
||||
if (skb_headroom(*pskb) < hh_len) {
|
||||
struct sk_buff *nskb;
|
||||
|
||||
nskb = skb_realloc_headroom(*pskb, hh_len);
|
||||
if (!nskb)
|
||||
return -1;
|
||||
if ((*pskb)->sk)
|
||||
skb_set_owner_w(nskb, (*pskb)->sk);
|
||||
kfree_skb(*pskb);
|
||||
*pskb = nskb;
|
||||
}
|
||||
hh_len = skb->dst->dev->hard_header_len;
|
||||
if (skb_headroom(skb) < hh_len &&
|
||||
pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ip_route_me_harder);
|
||||
|
||||
#ifdef CONFIG_XFRM
|
||||
int ip_xfrm_me_harder(struct sk_buff **pskb)
|
||||
int ip_xfrm_me_harder(struct sk_buff *skb)
|
||||
{
|
||||
struct flowi fl;
|
||||
unsigned int hh_len;
|
||||
struct dst_entry *dst;
|
||||
|
||||
if (IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED)
|
||||
if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
|
||||
return 0;
|
||||
if (xfrm_decode_session(*pskb, &fl, AF_INET) < 0)
|
||||
if (xfrm_decode_session(skb, &fl, AF_INET) < 0)
|
||||
return -1;
|
||||
|
||||
dst = (*pskb)->dst;
|
||||
dst = skb->dst;
|
||||
if (dst->xfrm)
|
||||
dst = ((struct xfrm_dst *)dst)->route;
|
||||
dst_hold(dst);
|
||||
|
||||
if (xfrm_lookup(&dst, &fl, (*pskb)->sk, 0) < 0)
|
||||
if (xfrm_lookup(&dst, &fl, skb->sk, 0) < 0)
|
||||
return -1;
|
||||
|
||||
dst_release((*pskb)->dst);
|
||||
(*pskb)->dst = dst;
|
||||
dst_release(skb->dst);
|
||||
skb->dst = dst;
|
||||
|
||||
/* Change in oif may mean change in hh_len. */
|
||||
hh_len = (*pskb)->dst->dev->hard_header_len;
|
||||
if (skb_headroom(*pskb) < hh_len) {
|
||||
struct sk_buff *nskb;
|
||||
|
||||
nskb = skb_realloc_headroom(*pskb, hh_len);
|
||||
if (!nskb)
|
||||
return -1;
|
||||
if ((*pskb)->sk)
|
||||
skb_set_owner_w(nskb, (*pskb)->sk);
|
||||
kfree_skb(*pskb);
|
||||
*pskb = nskb;
|
||||
}
|
||||
hh_len = skb->dst->dev->hard_header_len;
|
||||
if (skb_headroom(skb) < hh_len &&
|
||||
pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ip_xfrm_me_harder);
|
||||
@ -150,17 +135,17 @@ static void nf_ip_saveroute(const struct sk_buff *skb, struct nf_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
static int nf_ip_reroute(struct sk_buff **pskb, const struct nf_info *info)
|
||||
static int nf_ip_reroute(struct sk_buff *skb, const struct nf_info *info)
|
||||
{
|
||||
const struct ip_rt_info *rt_info = nf_info_reroute(info);
|
||||
|
||||
if (info->hook == NF_IP_LOCAL_OUT) {
|
||||
const struct iphdr *iph = ip_hdr(*pskb);
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
|
||||
if (!(iph->tos == rt_info->tos
|
||||
&& iph->daddr == rt_info->daddr
|
||||
&& iph->saddr == rt_info->saddr))
|
||||
return ip_route_me_harder(pskb, RTN_UNSPEC);
|
||||
return ip_route_me_harder(skb, RTN_UNSPEC);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ static inline int arp_checkentry(const struct arpt_arp *arp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned int arpt_error(struct sk_buff **pskb,
|
||||
static unsigned int arpt_error(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -215,7 +215,7 @@ static inline struct arpt_entry *get_entry(void *base, unsigned int offset)
|
||||
return (struct arpt_entry *)(base + offset);
|
||||
}
|
||||
|
||||
unsigned int arpt_do_table(struct sk_buff **pskb,
|
||||
unsigned int arpt_do_table(struct sk_buff *skb,
|
||||
unsigned int hook,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
@ -231,9 +231,9 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
|
||||
struct xt_table_info *private;
|
||||
|
||||
/* ARP header, plus 2 device addresses, plus 2 IP addresses. */
|
||||
if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) +
|
||||
(2 * (*pskb)->dev->addr_len) +
|
||||
(2 * sizeof(u32)))))
|
||||
if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
|
||||
(2 * skb->dev->addr_len) +
|
||||
(2 * sizeof(u32)))))
|
||||
return NF_DROP;
|
||||
|
||||
indev = in ? in->name : nulldevname;
|
||||
@ -245,14 +245,14 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
|
||||
e = get_entry(table_base, private->hook_entry[hook]);
|
||||
back = get_entry(table_base, private->underflow[hook]);
|
||||
|
||||
arp = arp_hdr(*pskb);
|
||||
arp = arp_hdr(skb);
|
||||
do {
|
||||
if (arp_packet_match(arp, (*pskb)->dev, indev, outdev, &e->arp)) {
|
||||
if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) {
|
||||
struct arpt_entry_target *t;
|
||||
int hdr_len;
|
||||
|
||||
hdr_len = sizeof(*arp) + (2 * sizeof(struct in_addr)) +
|
||||
(2 * (*pskb)->dev->addr_len);
|
||||
(2 * skb->dev->addr_len);
|
||||
ADD_COUNTER(e->counters, hdr_len, 1);
|
||||
|
||||
t = arpt_get_target(e);
|
||||
@ -290,14 +290,14 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
|
||||
/* Targets which reenter must return
|
||||
* abs. verdicts
|
||||
*/
|
||||
verdict = t->u.kernel.target->target(pskb,
|
||||
verdict = t->u.kernel.target->target(skb,
|
||||
in, out,
|
||||
hook,
|
||||
t->u.kernel.target,
|
||||
t->data);
|
||||
|
||||
/* Target might have changed stuff. */
|
||||
arp = arp_hdr(*pskb);
|
||||
arp = arp_hdr(skb);
|
||||
|
||||
if (verdict == ARPT_CONTINUE)
|
||||
e = (void *)e + e->next_offset;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* module that allows mangling of the arp payload */
|
||||
#include <linux/module.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_arp/arpt_mangle.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
@ -8,7 +9,7 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
|
||||
MODULE_DESCRIPTION("arptables arp payload mangle target");
|
||||
|
||||
static unsigned int
|
||||
target(struct sk_buff **pskb,
|
||||
target(struct sk_buff *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
unsigned int hooknum, const struct xt_target *target,
|
||||
const void *targinfo)
|
||||
@ -18,47 +19,38 @@ target(struct sk_buff **pskb,
|
||||
unsigned char *arpptr;
|
||||
int pln, hln;
|
||||
|
||||
if (skb_shared(*pskb) || skb_cloned(*pskb)) {
|
||||
struct sk_buff *nskb;
|
||||
if (skb_make_writable(skb, skb->len))
|
||||
return NF_DROP;
|
||||
|
||||
nskb = skb_copy(*pskb, GFP_ATOMIC);
|
||||
if (!nskb)
|
||||
return NF_DROP;
|
||||
if ((*pskb)->sk)
|
||||
skb_set_owner_w(nskb, (*pskb)->sk);
|
||||
kfree_skb(*pskb);
|
||||
*pskb = nskb;
|
||||
}
|
||||
|
||||
arp = arp_hdr(*pskb);
|
||||
arpptr = skb_network_header(*pskb) + sizeof(*arp);
|
||||
arp = arp_hdr(skb);
|
||||
arpptr = skb_network_header(skb) + sizeof(*arp);
|
||||
pln = arp->ar_pln;
|
||||
hln = arp->ar_hln;
|
||||
/* We assume that pln and hln were checked in the match */
|
||||
if (mangle->flags & ARPT_MANGLE_SDEV) {
|
||||
if (ARPT_DEV_ADDR_LEN_MAX < hln ||
|
||||
(arpptr + hln > skb_tail_pointer(*pskb)))
|
||||
(arpptr + hln > skb_tail_pointer(skb)))
|
||||
return NF_DROP;
|
||||
memcpy(arpptr, mangle->src_devaddr, hln);
|
||||
}
|
||||
arpptr += hln;
|
||||
if (mangle->flags & ARPT_MANGLE_SIP) {
|
||||
if (ARPT_MANGLE_ADDR_LEN_MAX < pln ||
|
||||
(arpptr + pln > skb_tail_pointer(*pskb)))
|
||||
(arpptr + pln > skb_tail_pointer(skb)))
|
||||
return NF_DROP;
|
||||
memcpy(arpptr, &mangle->u_s.src_ip, pln);
|
||||
}
|
||||
arpptr += pln;
|
||||
if (mangle->flags & ARPT_MANGLE_TDEV) {
|
||||
if (ARPT_DEV_ADDR_LEN_MAX < hln ||
|
||||
(arpptr + hln > skb_tail_pointer(*pskb)))
|
||||
(arpptr + hln > skb_tail_pointer(skb)))
|
||||
return NF_DROP;
|
||||
memcpy(arpptr, mangle->tgt_devaddr, hln);
|
||||
}
|
||||
arpptr += hln;
|
||||
if (mangle->flags & ARPT_MANGLE_TIP) {
|
||||
if (ARPT_MANGLE_ADDR_LEN_MAX < pln ||
|
||||
(arpptr + pln > skb_tail_pointer(*pskb)))
|
||||
(arpptr + pln > skb_tail_pointer(skb)))
|
||||
return NF_DROP;
|
||||
memcpy(arpptr, &mangle->u_t.tgt_ip, pln);
|
||||
}
|
||||
|
@ -56,12 +56,12 @@ static struct arpt_table packet_filter = {
|
||||
|
||||
/* The work comes in here from netfilter.c */
|
||||
static unsigned int arpt_hook(unsigned int hook,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return arpt_do_table(pskb, hook, in, out, &packet_filter);
|
||||
return arpt_do_table(skb, hook, in, out, &packet_filter);
|
||||
}
|
||||
|
||||
static struct nf_hook_ops arpt_ops[] = {
|
||||
|
@ -335,6 +335,7 @@ static int
|
||||
ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
|
||||
{
|
||||
int diff;
|
||||
int err;
|
||||
struct iphdr *user_iph = (struct iphdr *)v->payload;
|
||||
|
||||
if (v->data_len < sizeof(*user_iph))
|
||||
@ -347,25 +348,18 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
|
||||
if (v->data_len > 0xFFFF)
|
||||
return -EINVAL;
|
||||
if (diff > skb_tailroom(e->skb)) {
|
||||
struct sk_buff *newskb;
|
||||
|
||||
newskb = skb_copy_expand(e->skb,
|
||||
skb_headroom(e->skb),
|
||||
diff,
|
||||
GFP_ATOMIC);
|
||||
if (newskb == NULL) {
|
||||
printk(KERN_WARNING "ip_queue: OOM "
|
||||
"in mangle, dropping packet\n");
|
||||
return -ENOMEM;
|
||||
err = pskb_expand_head(e->skb, 0,
|
||||
diff - skb_tailroom(e->skb),
|
||||
GFP_ATOMIC);
|
||||
if (err) {
|
||||
printk(KERN_WARNING "ip_queue: error "
|
||||
"in mangle, dropping packet: %d\n", -err);
|
||||
return err;
|
||||
}
|
||||
if (e->skb->sk)
|
||||
skb_set_owner_w(newskb, e->skb->sk);
|
||||
kfree_skb(e->skb);
|
||||
e->skb = newskb;
|
||||
}
|
||||
skb_put(e->skb, diff);
|
||||
}
|
||||
if (!skb_make_writable(&e->skb, v->data_len))
|
||||
if (!skb_make_writable(e->skb, v->data_len))
|
||||
return -ENOMEM;
|
||||
skb_copy_to_linear_data(e->skb, v->payload, v->data_len);
|
||||
e->skb->ip_summed = CHECKSUM_NONE;
|
||||
|
@ -169,7 +169,7 @@ ip_checkentry(const struct ipt_ip *ip)
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ipt_error(struct sk_buff **pskb,
|
||||
ipt_error(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -312,7 +312,7 @@ static void trace_packet(struct sk_buff *skb,
|
||||
|
||||
/* Returns one of the generic firewall policies, like NF_ACCEPT. */
|
||||
unsigned int
|
||||
ipt_do_table(struct sk_buff **pskb,
|
||||
ipt_do_table(struct sk_buff *skb,
|
||||
unsigned int hook,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
@ -331,8 +331,8 @@ ipt_do_table(struct sk_buff **pskb,
|
||||
struct xt_table_info *private;
|
||||
|
||||
/* Initialization */
|
||||
ip = ip_hdr(*pskb);
|
||||
datalen = (*pskb)->len - ip->ihl * 4;
|
||||
ip = ip_hdr(skb);
|
||||
datalen = skb->len - ip->ihl * 4;
|
||||
indev = in ? in->name : nulldevname;
|
||||
outdev = out ? out->name : nulldevname;
|
||||
/* We handle fragments by dealing with the first fragment as
|
||||
@ -359,7 +359,7 @@ ipt_do_table(struct sk_buff **pskb,
|
||||
struct ipt_entry_target *t;
|
||||
|
||||
if (IPT_MATCH_ITERATE(e, do_match,
|
||||
*pskb, in, out,
|
||||
skb, in, out,
|
||||
offset, &hotdrop) != 0)
|
||||
goto no_match;
|
||||
|
||||
@ -371,8 +371,8 @@ ipt_do_table(struct sk_buff **pskb,
|
||||
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
|
||||
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
|
||||
/* The packet is traced: log it */
|
||||
if (unlikely((*pskb)->nf_trace))
|
||||
trace_packet(*pskb, hook, in, out,
|
||||
if (unlikely(skb->nf_trace))
|
||||
trace_packet(skb, hook, in, out,
|
||||
table->name, private, e);
|
||||
#endif
|
||||
/* Standard target? */
|
||||
@ -410,7 +410,7 @@ ipt_do_table(struct sk_buff **pskb,
|
||||
((struct ipt_entry *)table_base)->comefrom
|
||||
= 0xeeeeeeec;
|
||||
#endif
|
||||
verdict = t->u.kernel.target->target(pskb,
|
||||
verdict = t->u.kernel.target->target(skb,
|
||||
in, out,
|
||||
hook,
|
||||
t->u.kernel.target,
|
||||
@ -428,8 +428,8 @@ ipt_do_table(struct sk_buff **pskb,
|
||||
= 0x57acc001;
|
||||
#endif
|
||||
/* Target might have changed stuff. */
|
||||
ip = ip_hdr(*pskb);
|
||||
datalen = (*pskb)->len - ip->ihl * 4;
|
||||
ip = ip_hdr(skb);
|
||||
datalen = skb->len - ip->ihl * 4;
|
||||
|
||||
if (verdict == IPT_CONTINUE)
|
||||
e = (void *)e + e->next_offset;
|
||||
|
@ -289,7 +289,7 @@ clusterip_responsible(const struct clusterip_config *config, u_int32_t hash)
|
||||
***********************************************************************/
|
||||
|
||||
static unsigned int
|
||||
target(struct sk_buff **pskb,
|
||||
target(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -305,7 +305,7 @@ target(struct sk_buff **pskb,
|
||||
* is only decremented by destroy() - and ip_tables guarantees
|
||||
* that the ->target() function isn't called after ->destroy() */
|
||||
|
||||
ct = nf_ct_get(*pskb, &ctinfo);
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
if (ct == NULL) {
|
||||
printk(KERN_ERR "CLUSTERIP: no conntrack!\n");
|
||||
/* FIXME: need to drop invalid ones, since replies
|
||||
@ -316,7 +316,7 @@ target(struct sk_buff **pskb,
|
||||
|
||||
/* special case: ICMP error handling. conntrack distinguishes between
|
||||
* error messages (RELATED) and information requests (see below) */
|
||||
if (ip_hdr(*pskb)->protocol == IPPROTO_ICMP
|
||||
if (ip_hdr(skb)->protocol == IPPROTO_ICMP
|
||||
&& (ctinfo == IP_CT_RELATED
|
||||
|| ctinfo == IP_CT_RELATED+IP_CT_IS_REPLY))
|
||||
return XT_CONTINUE;
|
||||
@ -325,7 +325,7 @@ target(struct sk_buff **pskb,
|
||||
* TIMESTAMP, INFO_REQUEST or ADDRESS type icmp packets from here
|
||||
* on, which all have an ID field [relevant for hashing]. */
|
||||
|
||||
hash = clusterip_hashfn(*pskb, cipinfo->config);
|
||||
hash = clusterip_hashfn(skb, cipinfo->config);
|
||||
|
||||
switch (ctinfo) {
|
||||
case IP_CT_NEW:
|
||||
@ -355,7 +355,7 @@ target(struct sk_buff **pskb,
|
||||
|
||||
/* despite being received via linklayer multicast, this is
|
||||
* actually a unicast IP packet. TCP doesn't like PACKET_MULTICAST */
|
||||
(*pskb)->pkt_type = PACKET_HOST;
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
@ -505,12 +505,12 @@ static void arp_print(struct arp_payload *payload)
|
||||
|
||||
static unsigned int
|
||||
arp_mangle(unsigned int hook,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
struct arphdr *arp = arp_hdr(*pskb);
|
||||
struct arphdr *arp = arp_hdr(skb);
|
||||
struct arp_payload *payload;
|
||||
struct clusterip_config *c;
|
||||
|
||||
|
@ -26,15 +26,15 @@ MODULE_DESCRIPTION("iptables ECN modification module");
|
||||
/* set ECT codepoint from IP header.
|
||||
* return false if there was an error. */
|
||||
static inline bool
|
||||
set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
|
||||
set_ect_ip(struct sk_buff *skb, const struct ipt_ECN_info *einfo)
|
||||
{
|
||||
struct iphdr *iph = ip_hdr(*pskb);
|
||||
struct iphdr *iph = ip_hdr(skb);
|
||||
|
||||
if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
|
||||
__u8 oldtos;
|
||||
if (!skb_make_writable(pskb, sizeof(struct iphdr)))
|
||||
if (!skb_make_writable(skb, sizeof(struct iphdr)))
|
||||
return false;
|
||||
iph = ip_hdr(*pskb);
|
||||
iph = ip_hdr(skb);
|
||||
oldtos = iph->tos;
|
||||
iph->tos &= ~IPT_ECN_IP_MASK;
|
||||
iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
|
||||
@ -45,14 +45,13 @@ set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
|
||||
|
||||
/* Return false if there was an error. */
|
||||
static inline bool
|
||||
set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
|
||||
set_ect_tcp(struct sk_buff *skb, const struct ipt_ECN_info *einfo)
|
||||
{
|
||||
struct tcphdr _tcph, *tcph;
|
||||
__be16 oldval;
|
||||
|
||||
/* Not enought header? */
|
||||
tcph = skb_header_pointer(*pskb, ip_hdrlen(*pskb),
|
||||
sizeof(_tcph), &_tcph);
|
||||
tcph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph);
|
||||
if (!tcph)
|
||||
return false;
|
||||
|
||||
@ -62,9 +61,9 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
|
||||
tcph->cwr == einfo->proto.tcp.cwr))
|
||||
return true;
|
||||
|
||||
if (!skb_make_writable(pskb, ip_hdrlen(*pskb) + sizeof(*tcph)))
|
||||
if (!skb_make_writable(skb, ip_hdrlen(skb) + sizeof(*tcph)))
|
||||
return false;
|
||||
tcph = (void *)ip_hdr(*pskb) + ip_hdrlen(*pskb);
|
||||
tcph = (void *)ip_hdr(skb) + ip_hdrlen(skb);
|
||||
|
||||
oldval = ((__be16 *)tcph)[6];
|
||||
if (einfo->operation & IPT_ECN_OP_SET_ECE)
|
||||
@ -72,13 +71,13 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
|
||||
if (einfo->operation & IPT_ECN_OP_SET_CWR)
|
||||
tcph->cwr = einfo->proto.tcp.cwr;
|
||||
|
||||
nf_proto_csum_replace2(&tcph->check, *pskb,
|
||||
nf_proto_csum_replace2(&tcph->check, skb,
|
||||
oldval, ((__be16 *)tcph)[6], 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
target(struct sk_buff **pskb,
|
||||
target(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -88,12 +87,12 @@ target(struct sk_buff **pskb,
|
||||
const struct ipt_ECN_info *einfo = targinfo;
|
||||
|
||||
if (einfo->operation & IPT_ECN_OP_SET_IP)
|
||||
if (!set_ect_ip(pskb, einfo))
|
||||
if (!set_ect_ip(skb, einfo))
|
||||
return NF_DROP;
|
||||
|
||||
if (einfo->operation & (IPT_ECN_OP_SET_ECE | IPT_ECN_OP_SET_CWR)
|
||||
&& ip_hdr(*pskb)->protocol == IPPROTO_TCP)
|
||||
if (!set_ect_tcp(pskb, einfo))
|
||||
&& ip_hdr(skb)->protocol == IPPROTO_TCP)
|
||||
if (!set_ect_tcp(skb, einfo))
|
||||
return NF_DROP;
|
||||
|
||||
return XT_CONTINUE;
|
||||
|
@ -418,7 +418,7 @@ ipt_log_packet(unsigned int pf,
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ipt_log_target(struct sk_buff **pskb,
|
||||
ipt_log_target(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -432,7 +432,7 @@ ipt_log_target(struct sk_buff **pskb,
|
||||
li.u.log.level = loginfo->level;
|
||||
li.u.log.logflags = loginfo->logflags;
|
||||
|
||||
ipt_log_packet(PF_INET, hooknum, *pskb, in, out, &li,
|
||||
ipt_log_packet(PF_INET, hooknum, skb, in, out, &li,
|
||||
loginfo->prefix);
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ masquerade_check(const char *tablename,
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
masquerade_target(struct sk_buff **pskb,
|
||||
masquerade_target(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -69,7 +69,7 @@ masquerade_target(struct sk_buff **pskb,
|
||||
|
||||
NF_CT_ASSERT(hooknum == NF_IP_POST_ROUTING);
|
||||
|
||||
ct = nf_ct_get(*pskb, &ctinfo);
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
nat = nfct_nat(ct);
|
||||
|
||||
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED
|
||||
@ -82,7 +82,7 @@ masquerade_target(struct sk_buff **pskb,
|
||||
return NF_ACCEPT;
|
||||
|
||||
mr = targinfo;
|
||||
rt = (struct rtable *)(*pskb)->dst;
|
||||
rt = (struct rtable *)skb->dst;
|
||||
newsrc = inet_select_addr(out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
|
||||
if (!newsrc) {
|
||||
printk("MASQUERADE: %s ate my IP address\n", out->name);
|
||||
|
@ -43,7 +43,7 @@ check(const char *tablename,
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
target(struct sk_buff **pskb,
|
||||
target(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -59,14 +59,14 @@ target(struct sk_buff **pskb,
|
||||
NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING
|
||||
|| hooknum == NF_IP_POST_ROUTING
|
||||
|| hooknum == NF_IP_LOCAL_OUT);
|
||||
ct = nf_ct_get(*pskb, &ctinfo);
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
|
||||
netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip);
|
||||
|
||||
if (hooknum == NF_IP_PRE_ROUTING || hooknum == NF_IP_LOCAL_OUT)
|
||||
new_ip = ip_hdr(*pskb)->daddr & ~netmask;
|
||||
new_ip = ip_hdr(skb)->daddr & ~netmask;
|
||||
else
|
||||
new_ip = ip_hdr(*pskb)->saddr & ~netmask;
|
||||
new_ip = ip_hdr(skb)->saddr & ~netmask;
|
||||
new_ip |= mr->range[0].min_ip & netmask;
|
||||
|
||||
newrange = ((struct nf_nat_range)
|
||||
|
@ -47,7 +47,7 @@ redirect_check(const char *tablename,
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
redirect_target(struct sk_buff **pskb,
|
||||
redirect_target(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -63,7 +63,7 @@ redirect_target(struct sk_buff **pskb,
|
||||
NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING
|
||||
|| hooknum == NF_IP_LOCAL_OUT);
|
||||
|
||||
ct = nf_ct_get(*pskb, &ctinfo);
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
|
||||
|
||||
/* Local packets: make them go to loopback */
|
||||
@ -76,7 +76,7 @@ redirect_target(struct sk_buff **pskb,
|
||||
newdst = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
indev = __in_dev_get_rcu((*pskb)->dev);
|
||||
indev = __in_dev_get_rcu(skb->dev);
|
||||
if (indev && (ifa = indev->ifa_list))
|
||||
newdst = ifa->ifa_local;
|
||||
rcu_read_unlock();
|
||||
|
@ -131,7 +131,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
|
||||
)
|
||||
addr_type = RTN_LOCAL;
|
||||
|
||||
if (ip_route_me_harder(&nskb, addr_type))
|
||||
if (ip_route_me_harder(nskb, addr_type))
|
||||
goto free_nskb;
|
||||
|
||||
nskb->ip_summed = CHECKSUM_NONE;
|
||||
@ -162,7 +162,7 @@ static inline void send_unreach(struct sk_buff *skb_in, int code)
|
||||
icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0);
|
||||
}
|
||||
|
||||
static unsigned int reject(struct sk_buff **pskb,
|
||||
static unsigned int reject(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -173,7 +173,7 @@ static unsigned int reject(struct sk_buff **pskb,
|
||||
|
||||
/* Our naive response construction doesn't deal with IP
|
||||
options, and probably shouldn't try. */
|
||||
if (ip_hdrlen(*pskb) != sizeof(struct iphdr))
|
||||
if (ip_hdrlen(skb) != sizeof(struct iphdr))
|
||||
return NF_DROP;
|
||||
|
||||
/* WARNING: This code causes reentry within iptables.
|
||||
@ -181,28 +181,28 @@ static unsigned int reject(struct sk_buff **pskb,
|
||||
must return an absolute verdict. --RR */
|
||||
switch (reject->with) {
|
||||
case IPT_ICMP_NET_UNREACHABLE:
|
||||
send_unreach(*pskb, ICMP_NET_UNREACH);
|
||||
send_unreach(skb, ICMP_NET_UNREACH);
|
||||
break;
|
||||
case IPT_ICMP_HOST_UNREACHABLE:
|
||||
send_unreach(*pskb, ICMP_HOST_UNREACH);
|
||||
send_unreach(skb, ICMP_HOST_UNREACH);
|
||||
break;
|
||||
case IPT_ICMP_PROT_UNREACHABLE:
|
||||
send_unreach(*pskb, ICMP_PROT_UNREACH);
|
||||
send_unreach(skb, ICMP_PROT_UNREACH);
|
||||
break;
|
||||
case IPT_ICMP_PORT_UNREACHABLE:
|
||||
send_unreach(*pskb, ICMP_PORT_UNREACH);
|
||||
send_unreach(skb, ICMP_PORT_UNREACH);
|
||||
break;
|
||||
case IPT_ICMP_NET_PROHIBITED:
|
||||
send_unreach(*pskb, ICMP_NET_ANO);
|
||||
send_unreach(skb, ICMP_NET_ANO);
|
||||
break;
|
||||
case IPT_ICMP_HOST_PROHIBITED:
|
||||
send_unreach(*pskb, ICMP_HOST_ANO);
|
||||
send_unreach(skb, ICMP_HOST_ANO);
|
||||
break;
|
||||
case IPT_ICMP_ADMIN_PROHIBITED:
|
||||
send_unreach(*pskb, ICMP_PKT_FILTERED);
|
||||
send_unreach(skb, ICMP_PKT_FILTERED);
|
||||
break;
|
||||
case IPT_TCP_RESET:
|
||||
send_reset(*pskb, hooknum);
|
||||
send_reset(skb, hooknum);
|
||||
case IPT_ICMP_ECHOREPLY:
|
||||
/* Doesn't happen. */
|
||||
break;
|
||||
|
@ -104,7 +104,7 @@ same_destroy(const struct xt_target *target, void *targinfo)
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
same_target(struct sk_buff **pskb,
|
||||
same_target(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -121,7 +121,7 @@ same_target(struct sk_buff **pskb,
|
||||
|
||||
NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
|
||||
hooknum == NF_IP_POST_ROUTING);
|
||||
ct = nf_ct_get(*pskb, &ctinfo);
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
|
||||
t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
|
||||
|
||||
|
@ -21,7 +21,7 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
|
||||
MODULE_DESCRIPTION("iptables TOS mangling module");
|
||||
|
||||
static unsigned int
|
||||
target(struct sk_buff **pskb,
|
||||
target(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -29,13 +29,13 @@ target(struct sk_buff **pskb,
|
||||
const void *targinfo)
|
||||
{
|
||||
const struct ipt_tos_target_info *tosinfo = targinfo;
|
||||
struct iphdr *iph = ip_hdr(*pskb);
|
||||
struct iphdr *iph = ip_hdr(skb);
|
||||
|
||||
if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
|
||||
__u8 oldtos;
|
||||
if (!skb_make_writable(pskb, sizeof(struct iphdr)))
|
||||
if (!skb_make_writable(skb, sizeof(struct iphdr)))
|
||||
return NF_DROP;
|
||||
iph = ip_hdr(*pskb);
|
||||
iph = ip_hdr(skb);
|
||||
oldtos = iph->tos;
|
||||
iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
|
||||
nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
|
||||
|
@ -20,7 +20,7 @@ MODULE_DESCRIPTION("IP tables TTL modification module");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static unsigned int
|
||||
ipt_ttl_target(struct sk_buff **pskb,
|
||||
ipt_ttl_target(struct sk_buff *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
unsigned int hooknum, const struct xt_target *target,
|
||||
const void *targinfo)
|
||||
@ -29,10 +29,10 @@ ipt_ttl_target(struct sk_buff **pskb,
|
||||
const struct ipt_TTL_info *info = targinfo;
|
||||
int new_ttl;
|
||||
|
||||
if (!skb_make_writable(pskb, (*pskb)->len))
|
||||
if (!skb_make_writable(skb, skb->len))
|
||||
return NF_DROP;
|
||||
|
||||
iph = ip_hdr(*pskb);
|
||||
iph = ip_hdr(skb);
|
||||
|
||||
switch (info->mode) {
|
||||
case IPT_TTL_SET:
|
||||
|
@ -279,7 +279,7 @@ alloc_failure:
|
||||
spin_unlock_bh(&ulog_lock);
|
||||
}
|
||||
|
||||
static unsigned int ipt_ulog_target(struct sk_buff **pskb,
|
||||
static unsigned int ipt_ulog_target(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -288,7 +288,7 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb,
|
||||
{
|
||||
struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
|
||||
|
||||
ipt_ulog_packet(hooknum, *pskb, in, out, loginfo, NULL);
|
||||
ipt_ulog_packet(hooknum, skb, in, out, loginfo, NULL);
|
||||
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
@ -62,31 +62,31 @@ static struct xt_table packet_filter = {
|
||||
/* The work comes in here from netfilter.c. */
|
||||
static unsigned int
|
||||
ipt_hook(unsigned int hook,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ipt_do_table(pskb, hook, in, out, &packet_filter);
|
||||
return ipt_do_table(skb, hook, in, out, &packet_filter);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ipt_local_out_hook(unsigned int hook,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
/* root is playing with raw sockets. */
|
||||
if ((*pskb)->len < sizeof(struct iphdr)
|
||||
|| ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
|
||||
if (skb->len < sizeof(struct iphdr) ||
|
||||
ip_hdrlen(skb) < sizeof(struct iphdr)) {
|
||||
if (net_ratelimit())
|
||||
printk("iptable_filter: ignoring short SOCK_RAW "
|
||||
"packet.\n");
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
return ipt_do_table(pskb, hook, in, out, &packet_filter);
|
||||
return ipt_do_table(skb, hook, in, out, &packet_filter);
|
||||
}
|
||||
|
||||
static struct nf_hook_ops ipt_ops[] = {
|
||||
|
@ -75,17 +75,17 @@ static struct xt_table packet_mangler = {
|
||||
/* The work comes in here from netfilter.c. */
|
||||
static unsigned int
|
||||
ipt_route_hook(unsigned int hook,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ipt_do_table(pskb, hook, in, out, &packet_mangler);
|
||||
return ipt_do_table(skb, hook, in, out, &packet_mangler);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ipt_local_hook(unsigned int hook,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
@ -97,8 +97,8 @@ ipt_local_hook(unsigned int hook,
|
||||
u_int32_t mark;
|
||||
|
||||
/* root is playing with raw sockets. */
|
||||
if ((*pskb)->len < sizeof(struct iphdr)
|
||||
|| ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
|
||||
if (skb->len < sizeof(struct iphdr)
|
||||
|| ip_hdrlen(skb) < sizeof(struct iphdr)) {
|
||||
if (net_ratelimit())
|
||||
printk("iptable_mangle: ignoring short SOCK_RAW "
|
||||
"packet.\n");
|
||||
@ -106,22 +106,22 @@ ipt_local_hook(unsigned int hook,
|
||||
}
|
||||
|
||||
/* Save things which could affect route */
|
||||
mark = (*pskb)->mark;
|
||||
iph = ip_hdr(*pskb);
|
||||
mark = skb->mark;
|
||||
iph = ip_hdr(skb);
|
||||
saddr = iph->saddr;
|
||||
daddr = iph->daddr;
|
||||
tos = iph->tos;
|
||||
|
||||
ret = ipt_do_table(pskb, hook, in, out, &packet_mangler);
|
||||
ret = ipt_do_table(skb, hook, in, out, &packet_mangler);
|
||||
/* Reroute for ANY change. */
|
||||
if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) {
|
||||
iph = ip_hdr(*pskb);
|
||||
iph = ip_hdr(skb);
|
||||
|
||||
if (iph->saddr != saddr ||
|
||||
iph->daddr != daddr ||
|
||||
(*pskb)->mark != mark ||
|
||||
skb->mark != mark ||
|
||||
iph->tos != tos)
|
||||
if (ip_route_me_harder(pskb, RTN_UNSPEC))
|
||||
if (ip_route_me_harder(skb, RTN_UNSPEC))
|
||||
ret = NF_DROP;
|
||||
}
|
||||
|
||||
|
@ -47,30 +47,30 @@ static struct xt_table packet_raw = {
|
||||
/* The work comes in here from netfilter.c. */
|
||||
static unsigned int
|
||||
ipt_hook(unsigned int hook,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ipt_do_table(pskb, hook, in, out, &packet_raw);
|
||||
return ipt_do_table(skb, hook, in, out, &packet_raw);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ipt_local_hook(unsigned int hook,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
/* root is playing with raw sockets. */
|
||||
if ((*pskb)->len < sizeof(struct iphdr) ||
|
||||
ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
|
||||
if (skb->len < sizeof(struct iphdr) ||
|
||||
ip_hdrlen(skb) < sizeof(struct iphdr)) {
|
||||
if (net_ratelimit())
|
||||
printk("iptable_raw: ignoring short SOCK_RAW"
|
||||
"packet.\n");
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
return ipt_do_table(pskb, hook, in, out, &packet_raw);
|
||||
return ipt_do_table(skb, hook, in, out, &packet_raw);
|
||||
}
|
||||
|
||||
/* 'raw' is the very first table. */
|
||||
|
@ -63,19 +63,20 @@ static int ipv4_print_conntrack(struct seq_file *s,
|
||||
}
|
||||
|
||||
/* Returns new sk_buff, or NULL */
|
||||
static struct sk_buff *
|
||||
nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
|
||||
static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
|
||||
{
|
||||
int err;
|
||||
|
||||
skb_orphan(skb);
|
||||
|
||||
local_bh_disable();
|
||||
skb = ip_defrag(skb, user);
|
||||
err = ip_defrag(skb, user);
|
||||
local_bh_enable();
|
||||
|
||||
if (skb)
|
||||
if (!err)
|
||||
ip_send_check(ip_hdr(skb));
|
||||
|
||||
return skb;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
|
||||
@ -99,17 +100,17 @@ static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
|
||||
}
|
||||
|
||||
static unsigned int ipv4_confirm(unsigned int hooknum,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
/* We've seen it coming out the other side: confirm it */
|
||||
return nf_conntrack_confirm(pskb);
|
||||
return nf_conntrack_confirm(skb);
|
||||
}
|
||||
|
||||
static unsigned int ipv4_conntrack_help(unsigned int hooknum,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
@ -120,7 +121,7 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
|
||||
struct nf_conntrack_helper *helper;
|
||||
|
||||
/* This is where we call the helper: as the packet goes out. */
|
||||
ct = nf_ct_get(*pskb, &ctinfo);
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
|
||||
return NF_ACCEPT;
|
||||
|
||||
@ -131,56 +132,55 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
|
||||
helper = rcu_dereference(help->helper);
|
||||
if (!helper)
|
||||
return NF_ACCEPT;
|
||||
return helper->help(pskb, skb_network_offset(*pskb) + ip_hdrlen(*pskb),
|
||||
return helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb),
|
||||
ct, ctinfo);
|
||||
}
|
||||
|
||||
static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
/* Previously seen (loopback)? Ignore. Do this before
|
||||
fragment check. */
|
||||
if ((*pskb)->nfct)
|
||||
if (skb->nfct)
|
||||
return NF_ACCEPT;
|
||||
|
||||
/* Gather fragments. */
|
||||
if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) {
|
||||
*pskb = nf_ct_ipv4_gather_frags(*pskb,
|
||||
hooknum == NF_IP_PRE_ROUTING ?
|
||||
IP_DEFRAG_CONNTRACK_IN :
|
||||
IP_DEFRAG_CONNTRACK_OUT);
|
||||
if (!*pskb)
|
||||
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
|
||||
if (nf_ct_ipv4_gather_frags(skb,
|
||||
hooknum == NF_IP_PRE_ROUTING ?
|
||||
IP_DEFRAG_CONNTRACK_IN :
|
||||
IP_DEFRAG_CONNTRACK_OUT))
|
||||
return NF_STOLEN;
|
||||
}
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
static unsigned int ipv4_conntrack_in(unsigned int hooknum,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return nf_conntrack_in(PF_INET, hooknum, pskb);
|
||||
return nf_conntrack_in(PF_INET, hooknum, skb);
|
||||
}
|
||||
|
||||
static unsigned int ipv4_conntrack_local(unsigned int hooknum,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
/* root is playing with raw sockets. */
|
||||
if ((*pskb)->len < sizeof(struct iphdr)
|
||||
|| ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
|
||||
if (skb->len < sizeof(struct iphdr) ||
|
||||
ip_hdrlen(skb) < sizeof(struct iphdr)) {
|
||||
if (net_ratelimit())
|
||||
printk("ipt_hook: happy cracking.\n");
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
return nf_conntrack_in(PF_INET, hooknum, pskb);
|
||||
return nf_conntrack_in(PF_INET, hooknum, skb);
|
||||
}
|
||||
|
||||
/* Connection tracking may drop packets, but never alters them, so
|
||||
|
@ -24,7 +24,7 @@ MODULE_DESCRIPTION("Amanda NAT helper");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ip_nat_amanda");
|
||||
|
||||
static unsigned int help(struct sk_buff **pskb,
|
||||
static unsigned int help(struct sk_buff *skb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int matchoff,
|
||||
unsigned int matchlen,
|
||||
@ -53,7 +53,7 @@ static unsigned int help(struct sk_buff **pskb,
|
||||
return NF_DROP;
|
||||
|
||||
sprintf(buffer, "%u", port);
|
||||
ret = nf_nat_mangle_udp_packet(pskb, exp->master, ctinfo,
|
||||
ret = nf_nat_mangle_udp_packet(skb, exp->master, ctinfo,
|
||||
matchoff, matchlen,
|
||||
buffer, strlen(buffer));
|
||||
if (ret != NF_ACCEPT)
|
||||
|
@ -349,7 +349,7 @@ EXPORT_SYMBOL(nf_nat_setup_info);
|
||||
/* Returns true if succeeded. */
|
||||
static int
|
||||
manip_pkt(u_int16_t proto,
|
||||
struct sk_buff **pskb,
|
||||
struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *target,
|
||||
enum nf_nat_manip_type maniptype)
|
||||
@ -357,19 +357,19 @@ manip_pkt(u_int16_t proto,
|
||||
struct iphdr *iph;
|
||||
struct nf_nat_protocol *p;
|
||||
|
||||
if (!skb_make_writable(pskb, iphdroff + sizeof(*iph)))
|
||||
if (!skb_make_writable(skb, iphdroff + sizeof(*iph)))
|
||||
return 0;
|
||||
|
||||
iph = (void *)(*pskb)->data + iphdroff;
|
||||
iph = (void *)skb->data + iphdroff;
|
||||
|
||||
/* Manipulate protcol part. */
|
||||
|
||||
/* rcu_read_lock()ed by nf_hook_slow */
|
||||
p = __nf_nat_proto_find(proto);
|
||||
if (!p->manip_pkt(pskb, iphdroff, target, maniptype))
|
||||
if (!p->manip_pkt(skb, iphdroff, target, maniptype))
|
||||
return 0;
|
||||
|
||||
iph = (void *)(*pskb)->data + iphdroff;
|
||||
iph = (void *)skb->data + iphdroff;
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC) {
|
||||
nf_csum_replace4(&iph->check, iph->saddr, target->src.u3.ip);
|
||||
@ -385,7 +385,7 @@ manip_pkt(u_int16_t proto,
|
||||
unsigned int nf_nat_packet(struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int hooknum,
|
||||
struct sk_buff **pskb)
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
|
||||
unsigned long statusbit;
|
||||
@ -407,7 +407,7 @@ unsigned int nf_nat_packet(struct nf_conn *ct,
|
||||
/* We are aiming to look like inverse of other direction. */
|
||||
nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
|
||||
|
||||
if (!manip_pkt(target.dst.protonum, pskb, 0, &target, mtype))
|
||||
if (!manip_pkt(target.dst.protonum, skb, 0, &target, mtype))
|
||||
return NF_DROP;
|
||||
}
|
||||
return NF_ACCEPT;
|
||||
@ -418,7 +418,7 @@ EXPORT_SYMBOL_GPL(nf_nat_packet);
|
||||
int nf_nat_icmp_reply_translation(struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int hooknum,
|
||||
struct sk_buff **pskb)
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct {
|
||||
struct icmphdr icmp;
|
||||
@ -426,24 +426,24 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
|
||||
} *inside;
|
||||
struct nf_conntrack_l4proto *l4proto;
|
||||
struct nf_conntrack_tuple inner, target;
|
||||
int hdrlen = ip_hdrlen(*pskb);
|
||||
int hdrlen = ip_hdrlen(skb);
|
||||
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
|
||||
unsigned long statusbit;
|
||||
enum nf_nat_manip_type manip = HOOK2MANIP(hooknum);
|
||||
|
||||
if (!skb_make_writable(pskb, hdrlen + sizeof(*inside)))
|
||||
if (!skb_make_writable(skb, hdrlen + sizeof(*inside)))
|
||||
return 0;
|
||||
|
||||
inside = (void *)(*pskb)->data + ip_hdrlen(*pskb);
|
||||
inside = (void *)skb->data + ip_hdrlen(skb);
|
||||
|
||||
/* We're actually going to mangle it beyond trivial checksum
|
||||
adjustment, so make sure the current checksum is correct. */
|
||||
if (nf_ip_checksum(*pskb, hooknum, hdrlen, 0))
|
||||
if (nf_ip_checksum(skb, hooknum, hdrlen, 0))
|
||||
return 0;
|
||||
|
||||
/* Must be RELATED */
|
||||
NF_CT_ASSERT((*pskb)->nfctinfo == IP_CT_RELATED ||
|
||||
(*pskb)->nfctinfo == IP_CT_RELATED+IP_CT_IS_REPLY);
|
||||
NF_CT_ASSERT(skb->nfctinfo == IP_CT_RELATED ||
|
||||
skb->nfctinfo == IP_CT_RELATED+IP_CT_IS_REPLY);
|
||||
|
||||
/* Redirects on non-null nats must be dropped, else they'll
|
||||
start talking to each other without our translation, and be
|
||||
@ -458,15 +458,15 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
|
||||
}
|
||||
|
||||
pr_debug("icmp_reply_translation: translating error %p manip %u "
|
||||
"dir %s\n", *pskb, manip,
|
||||
"dir %s\n", skb, manip,
|
||||
dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
|
||||
|
||||
/* rcu_read_lock()ed by nf_hook_slow */
|
||||
l4proto = __nf_ct_l4proto_find(PF_INET, inside->ip.protocol);
|
||||
|
||||
if (!nf_ct_get_tuple(*pskb,
|
||||
ip_hdrlen(*pskb) + sizeof(struct icmphdr),
|
||||
(ip_hdrlen(*pskb) +
|
||||
if (!nf_ct_get_tuple(skb,
|
||||
ip_hdrlen(skb) + sizeof(struct icmphdr),
|
||||
(ip_hdrlen(skb) +
|
||||
sizeof(struct icmphdr) + inside->ip.ihl * 4),
|
||||
(u_int16_t)AF_INET,
|
||||
inside->ip.protocol,
|
||||
@ -478,19 +478,19 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
|
||||
pass all hooks (locally-generated ICMP). Consider incoming
|
||||
packet: PREROUTING (DST manip), routing produces ICMP, goes
|
||||
through POSTROUTING (which must correct the DST manip). */
|
||||
if (!manip_pkt(inside->ip.protocol, pskb,
|
||||
ip_hdrlen(*pskb) + sizeof(inside->icmp),
|
||||
if (!manip_pkt(inside->ip.protocol, skb,
|
||||
ip_hdrlen(skb) + sizeof(inside->icmp),
|
||||
&ct->tuplehash[!dir].tuple,
|
||||
!manip))
|
||||
return 0;
|
||||
|
||||
if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
|
||||
if (skb->ip_summed != CHECKSUM_PARTIAL) {
|
||||
/* Reloading "inside" here since manip_pkt inner. */
|
||||
inside = (void *)(*pskb)->data + ip_hdrlen(*pskb);
|
||||
inside = (void *)skb->data + ip_hdrlen(skb);
|
||||
inside->icmp.checksum = 0;
|
||||
inside->icmp.checksum =
|
||||
csum_fold(skb_checksum(*pskb, hdrlen,
|
||||
(*pskb)->len - hdrlen, 0));
|
||||
csum_fold(skb_checksum(skb, hdrlen,
|
||||
skb->len - hdrlen, 0));
|
||||
}
|
||||
|
||||
/* Change outer to look the reply to an incoming packet
|
||||
@ -506,7 +506,7 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
|
||||
|
||||
if (ct->status & statusbit) {
|
||||
nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
|
||||
if (!manip_pkt(0, pskb, 0, &target, manip))
|
||||
if (!manip_pkt(0, skb, 0, &target, manip))
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ MODULE_ALIAS("ip_nat_ftp");
|
||||
/* FIXME: Time out? --RR */
|
||||
|
||||
static int
|
||||
mangle_rfc959_packet(struct sk_buff **pskb,
|
||||
mangle_rfc959_packet(struct sk_buff *skb,
|
||||
__be32 newip,
|
||||
u_int16_t port,
|
||||
unsigned int matchoff,
|
||||
@ -43,13 +43,13 @@ mangle_rfc959_packet(struct sk_buff **pskb,
|
||||
|
||||
pr_debug("calling nf_nat_mangle_tcp_packet\n");
|
||||
|
||||
return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
|
||||
return nf_nat_mangle_tcp_packet(skb, ct, ctinfo, matchoff,
|
||||
matchlen, buffer, strlen(buffer));
|
||||
}
|
||||
|
||||
/* |1|132.235.1.2|6275| */
|
||||
static int
|
||||
mangle_eprt_packet(struct sk_buff **pskb,
|
||||
mangle_eprt_packet(struct sk_buff *skb,
|
||||
__be32 newip,
|
||||
u_int16_t port,
|
||||
unsigned int matchoff,
|
||||
@ -63,13 +63,13 @@ mangle_eprt_packet(struct sk_buff **pskb,
|
||||
|
||||
pr_debug("calling nf_nat_mangle_tcp_packet\n");
|
||||
|
||||
return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
|
||||
return nf_nat_mangle_tcp_packet(skb, ct, ctinfo, matchoff,
|
||||
matchlen, buffer, strlen(buffer));
|
||||
}
|
||||
|
||||
/* |1|132.235.1.2|6275| */
|
||||
static int
|
||||
mangle_epsv_packet(struct sk_buff **pskb,
|
||||
mangle_epsv_packet(struct sk_buff *skb,
|
||||
__be32 newip,
|
||||
u_int16_t port,
|
||||
unsigned int matchoff,
|
||||
@ -83,11 +83,11 @@ mangle_epsv_packet(struct sk_buff **pskb,
|
||||
|
||||
pr_debug("calling nf_nat_mangle_tcp_packet\n");
|
||||
|
||||
return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
|
||||
return nf_nat_mangle_tcp_packet(skb, ct, ctinfo, matchoff,
|
||||
matchlen, buffer, strlen(buffer));
|
||||
}
|
||||
|
||||
static int (*mangle[])(struct sk_buff **, __be32, u_int16_t,
|
||||
static int (*mangle[])(struct sk_buff *, __be32, u_int16_t,
|
||||
unsigned int, unsigned int, struct nf_conn *,
|
||||
enum ip_conntrack_info)
|
||||
= {
|
||||
@ -99,7 +99,7 @@ static int (*mangle[])(struct sk_buff **, __be32, u_int16_t,
|
||||
|
||||
/* So, this packet has hit the connection tracking matching code.
|
||||
Mangle it, and change the expectation to match the new version. */
|
||||
static unsigned int nf_nat_ftp(struct sk_buff **pskb,
|
||||
static unsigned int nf_nat_ftp(struct sk_buff *skb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
enum nf_ct_ftp_type type,
|
||||
unsigned int matchoff,
|
||||
@ -132,7 +132,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb,
|
||||
if (port == 0)
|
||||
return NF_DROP;
|
||||
|
||||
if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo)) {
|
||||
if (!mangle[type](skb, newip, port, matchoff, matchlen, ct, ctinfo)) {
|
||||
nf_ct_unexpect_related(exp);
|
||||
return NF_DROP;
|
||||
}
|
||||
|
@ -22,12 +22,12 @@
|
||||
#include <linux/netfilter/nf_conntrack_h323.h>
|
||||
|
||||
/****************************************************************************/
|
||||
static int set_addr(struct sk_buff **pskb,
|
||||
static int set_addr(struct sk_buff *skb,
|
||||
unsigned char **data, int dataoff,
|
||||
unsigned int addroff, __be32 ip, __be16 port)
|
||||
{
|
||||
enum ip_conntrack_info ctinfo;
|
||||
struct nf_conn *ct = nf_ct_get(*pskb, &ctinfo);
|
||||
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
|
||||
struct {
|
||||
__be32 ip;
|
||||
__be16 port;
|
||||
@ -38,8 +38,8 @@ static int set_addr(struct sk_buff **pskb,
|
||||
buf.port = port;
|
||||
addroff += dataoff;
|
||||
|
||||
if (ip_hdr(*pskb)->protocol == IPPROTO_TCP) {
|
||||
if (!nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
|
||||
if (ip_hdr(skb)->protocol == IPPROTO_TCP) {
|
||||
if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
|
||||
addroff, sizeof(buf),
|
||||
(char *) &buf, sizeof(buf))) {
|
||||
if (net_ratelimit())
|
||||
@ -49,14 +49,13 @@ static int set_addr(struct sk_buff **pskb,
|
||||
}
|
||||
|
||||
/* Relocate data pointer */
|
||||
th = skb_header_pointer(*pskb, ip_hdrlen(*pskb),
|
||||
th = skb_header_pointer(skb, ip_hdrlen(skb),
|
||||
sizeof(_tcph), &_tcph);
|
||||
if (th == NULL)
|
||||
return -1;
|
||||
*data = (*pskb)->data + ip_hdrlen(*pskb) +
|
||||
th->doff * 4 + dataoff;
|
||||
*data = skb->data + ip_hdrlen(skb) + th->doff * 4 + dataoff;
|
||||
} else {
|
||||
if (!nf_nat_mangle_udp_packet(pskb, ct, ctinfo,
|
||||
if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo,
|
||||
addroff, sizeof(buf),
|
||||
(char *) &buf, sizeof(buf))) {
|
||||
if (net_ratelimit())
|
||||
@ -67,36 +66,35 @@ static int set_addr(struct sk_buff **pskb,
|
||||
/* nf_nat_mangle_udp_packet uses skb_make_writable() to copy
|
||||
* or pull everything in a linear buffer, so we can safely
|
||||
* use the skb pointers now */
|
||||
*data = ((*pskb)->data + ip_hdrlen(*pskb) +
|
||||
sizeof(struct udphdr));
|
||||
*data = skb->data + ip_hdrlen(skb) + sizeof(struct udphdr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static int set_h225_addr(struct sk_buff **pskb,
|
||||
static int set_h225_addr(struct sk_buff *skb,
|
||||
unsigned char **data, int dataoff,
|
||||
TransportAddress *taddr,
|
||||
union nf_conntrack_address *addr, __be16 port)
|
||||
{
|
||||
return set_addr(pskb, data, dataoff, taddr->ipAddress.ip,
|
||||
return set_addr(skb, data, dataoff, taddr->ipAddress.ip,
|
||||
addr->ip, port);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static int set_h245_addr(struct sk_buff **pskb,
|
||||
static int set_h245_addr(struct sk_buff *skb,
|
||||
unsigned char **data, int dataoff,
|
||||
H245_TransportAddress *taddr,
|
||||
union nf_conntrack_address *addr, __be16 port)
|
||||
{
|
||||
return set_addr(pskb, data, dataoff,
|
||||
return set_addr(skb, data, dataoff,
|
||||
taddr->unicastAddress.iPAddress.network,
|
||||
addr->ip, port);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static int set_sig_addr(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
static int set_sig_addr(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data,
|
||||
TransportAddress *taddr, int count)
|
||||
@ -125,7 +123,7 @@ static int set_sig_addr(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
NIPQUAD(addr.ip), port,
|
||||
NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
|
||||
info->sig_port[!dir]);
|
||||
return set_h225_addr(pskb, data, 0, &taddr[i],
|
||||
return set_h225_addr(skb, data, 0, &taddr[i],
|
||||
&ct->tuplehash[!dir].
|
||||
tuple.dst.u3,
|
||||
info->sig_port[!dir]);
|
||||
@ -137,7 +135,7 @@ static int set_sig_addr(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
NIPQUAD(addr.ip), port,
|
||||
NIPQUAD(ct->tuplehash[!dir].tuple.src.u3.ip),
|
||||
info->sig_port[!dir]);
|
||||
return set_h225_addr(pskb, data, 0, &taddr[i],
|
||||
return set_h225_addr(skb, data, 0, &taddr[i],
|
||||
&ct->tuplehash[!dir].
|
||||
tuple.src.u3,
|
||||
info->sig_port[!dir]);
|
||||
@ -149,7 +147,7 @@ static int set_sig_addr(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static int set_ras_addr(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
static int set_ras_addr(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data,
|
||||
TransportAddress *taddr, int count)
|
||||
@ -168,7 +166,7 @@ static int set_ras_addr(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
NIPQUAD(addr.ip), ntohs(port),
|
||||
NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
|
||||
ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port));
|
||||
return set_h225_addr(pskb, data, 0, &taddr[i],
|
||||
return set_h225_addr(skb, data, 0, &taddr[i],
|
||||
&ct->tuplehash[!dir].tuple.dst.u3,
|
||||
ct->tuplehash[!dir].tuple.
|
||||
dst.u.udp.port);
|
||||
@ -179,7 +177,7 @@ static int set_ras_addr(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static int nat_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data, int dataoff,
|
||||
H245_TransportAddress *taddr,
|
||||
@ -244,7 +242,7 @@ static int nat_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
}
|
||||
|
||||
/* Modify signal */
|
||||
if (set_h245_addr(pskb, data, dataoff, taddr,
|
||||
if (set_h245_addr(skb, data, dataoff, taddr,
|
||||
&ct->tuplehash[!dir].tuple.dst.u3,
|
||||
htons((port & htons(1)) ? nated_port + 1 :
|
||||
nated_port)) == 0) {
|
||||
@ -273,7 +271,7 @@ static int nat_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static int nat_t120(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
static int nat_t120(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data, int dataoff,
|
||||
H245_TransportAddress *taddr, __be16 port,
|
||||
@ -301,7 +299,7 @@ static int nat_t120(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
}
|
||||
|
||||
/* Modify signal */
|
||||
if (set_h245_addr(pskb, data, dataoff, taddr,
|
||||
if (set_h245_addr(skb, data, dataoff, taddr,
|
||||
&ct->tuplehash[!dir].tuple.dst.u3,
|
||||
htons(nated_port)) < 0) {
|
||||
nf_ct_unexpect_related(exp);
|
||||
@ -318,7 +316,7 @@ static int nat_t120(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static int nat_h245(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
static int nat_h245(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data, int dataoff,
|
||||
TransportAddress *taddr, __be16 port,
|
||||
@ -351,7 +349,7 @@ static int nat_h245(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
}
|
||||
|
||||
/* Modify signal */
|
||||
if (set_h225_addr(pskb, data, dataoff, taddr,
|
||||
if (set_h225_addr(skb, data, dataoff, taddr,
|
||||
&ct->tuplehash[!dir].tuple.dst.u3,
|
||||
htons(nated_port)) == 0) {
|
||||
/* Save ports */
|
||||
@ -406,7 +404,7 @@ static void ip_nat_q931_expect(struct nf_conn *new,
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static int nat_q931(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
static int nat_q931(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data, TransportAddress *taddr, int idx,
|
||||
__be16 port, struct nf_conntrack_expect *exp)
|
||||
@ -439,7 +437,7 @@ static int nat_q931(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
}
|
||||
|
||||
/* Modify signal */
|
||||
if (set_h225_addr(pskb, data, 0, &taddr[idx],
|
||||
if (set_h225_addr(skb, data, 0, &taddr[idx],
|
||||
&ct->tuplehash[!dir].tuple.dst.u3,
|
||||
htons(nated_port)) == 0) {
|
||||
/* Save ports */
|
||||
@ -450,7 +448,7 @@ static int nat_q931(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
if (idx > 0 &&
|
||||
get_h225_addr(ct, *data, &taddr[0], &addr, &port) &&
|
||||
(ntohl(addr.ip) & 0xff000000) == 0x7f000000) {
|
||||
set_h225_addr(pskb, data, 0, &taddr[0],
|
||||
set_h225_addr(skb, data, 0, &taddr[0],
|
||||
&ct->tuplehash[!dir].tuple.dst.u3,
|
||||
info->sig_port[!dir]);
|
||||
}
|
||||
@ -495,7 +493,7 @@ static void ip_nat_callforwarding_expect(struct nf_conn *new,
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static int nat_callforwarding(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned char **data, int dataoff,
|
||||
TransportAddress *taddr, __be16 port,
|
||||
@ -525,7 +523,7 @@ static int nat_callforwarding(struct sk_buff **pskb, struct nf_conn *ct,
|
||||
}
|
||||
|
||||
/* Modify signal */
|
||||
if (!set_h225_addr(pskb, data, dataoff, taddr,
|
||||
if (!set_h225_addr(skb, data, dataoff, taddr,
|
||||
&ct->tuplehash[!dir].tuple.dst.u3,
|
||||
htons(nated_port)) == 0) {
|
||||
nf_ct_unexpect_related(exp);
|
||||
|
@ -111,22 +111,14 @@ static void mangle_contents(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
/* Unusual, but possible case. */
|
||||
static int enlarge_skb(struct sk_buff **pskb, unsigned int extra)
|
||||
static int enlarge_skb(struct sk_buff *skb, unsigned int extra)
|
||||
{
|
||||
struct sk_buff *nskb;
|
||||
|
||||
if ((*pskb)->len + extra > 65535)
|
||||
if (skb->len + extra > 65535)
|
||||
return 0;
|
||||
|
||||
nskb = skb_copy_expand(*pskb, skb_headroom(*pskb), extra, GFP_ATOMIC);
|
||||
if (!nskb)
|
||||
if (pskb_expand_head(skb, 0, extra - skb_tailroom(skb), GFP_ATOMIC))
|
||||
return 0;
|
||||
|
||||
/* Transfer socket to new skb. */
|
||||
if ((*pskb)->sk)
|
||||
skb_set_owner_w(nskb, (*pskb)->sk);
|
||||
kfree_skb(*pskb);
|
||||
*pskb = nskb;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -139,7 +131,7 @@ static int enlarge_skb(struct sk_buff **pskb, unsigned int extra)
|
||||
*
|
||||
* */
|
||||
int
|
||||
nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
|
||||
nf_nat_mangle_tcp_packet(struct sk_buff *skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int match_offset,
|
||||
@ -147,37 +139,37 @@ nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
|
||||
const char *rep_buffer,
|
||||
unsigned int rep_len)
|
||||
{
|
||||
struct rtable *rt = (struct rtable *)(*pskb)->dst;
|
||||
struct rtable *rt = (struct rtable *)skb->dst;
|
||||
struct iphdr *iph;
|
||||
struct tcphdr *tcph;
|
||||
int oldlen, datalen;
|
||||
|
||||
if (!skb_make_writable(pskb, (*pskb)->len))
|
||||
if (!skb_make_writable(skb, skb->len))
|
||||
return 0;
|
||||
|
||||
if (rep_len > match_len &&
|
||||
rep_len - match_len > skb_tailroom(*pskb) &&
|
||||
!enlarge_skb(pskb, rep_len - match_len))
|
||||
rep_len - match_len > skb_tailroom(skb) &&
|
||||
!enlarge_skb(skb, rep_len - match_len))
|
||||
return 0;
|
||||
|
||||
SKB_LINEAR_ASSERT(*pskb);
|
||||
SKB_LINEAR_ASSERT(skb);
|
||||
|
||||
iph = ip_hdr(*pskb);
|
||||
iph = ip_hdr(skb);
|
||||
tcph = (void *)iph + iph->ihl*4;
|
||||
|
||||
oldlen = (*pskb)->len - iph->ihl*4;
|
||||
mangle_contents(*pskb, iph->ihl*4 + tcph->doff*4,
|
||||
oldlen = skb->len - iph->ihl*4;
|
||||
mangle_contents(skb, iph->ihl*4 + tcph->doff*4,
|
||||
match_offset, match_len, rep_buffer, rep_len);
|
||||
|
||||
datalen = (*pskb)->len - iph->ihl*4;
|
||||
if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
|
||||
datalen = skb->len - iph->ihl*4;
|
||||
if (skb->ip_summed != CHECKSUM_PARTIAL) {
|
||||
if (!(rt->rt_flags & RTCF_LOCAL) &&
|
||||
(*pskb)->dev->features & NETIF_F_V4_CSUM) {
|
||||
(*pskb)->ip_summed = CHECKSUM_PARTIAL;
|
||||
(*pskb)->csum_start = skb_headroom(*pskb) +
|
||||
skb_network_offset(*pskb) +
|
||||
iph->ihl * 4;
|
||||
(*pskb)->csum_offset = offsetof(struct tcphdr, check);
|
||||
skb->dev->features & NETIF_F_V4_CSUM) {
|
||||
skb->ip_summed = CHECKSUM_PARTIAL;
|
||||
skb->csum_start = skb_headroom(skb) +
|
||||
skb_network_offset(skb) +
|
||||
iph->ihl * 4;
|
||||
skb->csum_offset = offsetof(struct tcphdr, check);
|
||||
tcph->check = ~tcp_v4_check(datalen,
|
||||
iph->saddr, iph->daddr, 0);
|
||||
} else {
|
||||
@ -188,7 +180,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
|
||||
datalen, 0));
|
||||
}
|
||||
} else
|
||||
nf_proto_csum_replace2(&tcph->check, *pskb,
|
||||
nf_proto_csum_replace2(&tcph->check, skb,
|
||||
htons(oldlen), htons(datalen), 1);
|
||||
|
||||
if (rep_len != match_len) {
|
||||
@ -197,7 +189,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
|
||||
(int)rep_len - (int)match_len,
|
||||
ct, ctinfo);
|
||||
/* Tell TCP window tracking about seq change */
|
||||
nf_conntrack_tcp_update(*pskb, ip_hdrlen(*pskb),
|
||||
nf_conntrack_tcp_update(skb, ip_hdrlen(skb),
|
||||
ct, CTINFO2DIR(ctinfo));
|
||||
}
|
||||
return 1;
|
||||
@ -215,7 +207,7 @@ EXPORT_SYMBOL(nf_nat_mangle_tcp_packet);
|
||||
* should be fairly easy to do.
|
||||
*/
|
||||
int
|
||||
nf_nat_mangle_udp_packet(struct sk_buff **pskb,
|
||||
nf_nat_mangle_udp_packet(struct sk_buff *skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int match_offset,
|
||||
@ -223,48 +215,48 @@ nf_nat_mangle_udp_packet(struct sk_buff **pskb,
|
||||
const char *rep_buffer,
|
||||
unsigned int rep_len)
|
||||
{
|
||||
struct rtable *rt = (struct rtable *)(*pskb)->dst;
|
||||
struct rtable *rt = (struct rtable *)skb->dst;
|
||||
struct iphdr *iph;
|
||||
struct udphdr *udph;
|
||||
int datalen, oldlen;
|
||||
|
||||
/* UDP helpers might accidentally mangle the wrong packet */
|
||||
iph = ip_hdr(*pskb);
|
||||
if ((*pskb)->len < iph->ihl*4 + sizeof(*udph) +
|
||||
iph = ip_hdr(skb);
|
||||
if (skb->len < iph->ihl*4 + sizeof(*udph) +
|
||||
match_offset + match_len)
|
||||
return 0;
|
||||
|
||||
if (!skb_make_writable(pskb, (*pskb)->len))
|
||||
if (!skb_make_writable(skb, skb->len))
|
||||
return 0;
|
||||
|
||||
if (rep_len > match_len &&
|
||||
rep_len - match_len > skb_tailroom(*pskb) &&
|
||||
!enlarge_skb(pskb, rep_len - match_len))
|
||||
rep_len - match_len > skb_tailroom(skb) &&
|
||||
!enlarge_skb(skb, rep_len - match_len))
|
||||
return 0;
|
||||
|
||||
iph = ip_hdr(*pskb);
|
||||
iph = ip_hdr(skb);
|
||||
udph = (void *)iph + iph->ihl*4;
|
||||
|
||||
oldlen = (*pskb)->len - iph->ihl*4;
|
||||
mangle_contents(*pskb, iph->ihl*4 + sizeof(*udph),
|
||||
oldlen = skb->len - iph->ihl*4;
|
||||
mangle_contents(skb, iph->ihl*4 + sizeof(*udph),
|
||||
match_offset, match_len, rep_buffer, rep_len);
|
||||
|
||||
/* update the length of the UDP packet */
|
||||
datalen = (*pskb)->len - iph->ihl*4;
|
||||
datalen = skb->len - iph->ihl*4;
|
||||
udph->len = htons(datalen);
|
||||
|
||||
/* fix udp checksum if udp checksum was previously calculated */
|
||||
if (!udph->check && (*pskb)->ip_summed != CHECKSUM_PARTIAL)
|
||||
if (!udph->check && skb->ip_summed != CHECKSUM_PARTIAL)
|
||||
return 1;
|
||||
|
||||
if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
|
||||
if (skb->ip_summed != CHECKSUM_PARTIAL) {
|
||||
if (!(rt->rt_flags & RTCF_LOCAL) &&
|
||||
(*pskb)->dev->features & NETIF_F_V4_CSUM) {
|
||||
(*pskb)->ip_summed = CHECKSUM_PARTIAL;
|
||||
(*pskb)->csum_start = skb_headroom(*pskb) +
|
||||
skb_network_offset(*pskb) +
|
||||
iph->ihl * 4;
|
||||
(*pskb)->csum_offset = offsetof(struct udphdr, check);
|
||||
skb->dev->features & NETIF_F_V4_CSUM) {
|
||||
skb->ip_summed = CHECKSUM_PARTIAL;
|
||||
skb->csum_start = skb_headroom(skb) +
|
||||
skb_network_offset(skb) +
|
||||
iph->ihl * 4;
|
||||
skb->csum_offset = offsetof(struct udphdr, check);
|
||||
udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
|
||||
datalen, IPPROTO_UDP,
|
||||
0);
|
||||
@ -278,7 +270,7 @@ nf_nat_mangle_udp_packet(struct sk_buff **pskb,
|
||||
udph->check = CSUM_MANGLED_0;
|
||||
}
|
||||
} else
|
||||
nf_proto_csum_replace2(&udph->check, *pskb,
|
||||
nf_proto_csum_replace2(&udph->check, skb,
|
||||
htons(oldlen), htons(datalen), 1);
|
||||
|
||||
return 1;
|
||||
@ -330,7 +322,7 @@ sack_adjust(struct sk_buff *skb,
|
||||
|
||||
/* TCP SACK sequence number adjustment */
|
||||
static inline unsigned int
|
||||
nf_nat_sack_adjust(struct sk_buff **pskb,
|
||||
nf_nat_sack_adjust(struct sk_buff *skb,
|
||||
struct tcphdr *tcph,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo)
|
||||
@ -338,17 +330,17 @@ nf_nat_sack_adjust(struct sk_buff **pskb,
|
||||
unsigned int dir, optoff, optend;
|
||||
struct nf_conn_nat *nat = nfct_nat(ct);
|
||||
|
||||
optoff = ip_hdrlen(*pskb) + sizeof(struct tcphdr);
|
||||
optend = ip_hdrlen(*pskb) + tcph->doff * 4;
|
||||
optoff = ip_hdrlen(skb) + sizeof(struct tcphdr);
|
||||
optend = ip_hdrlen(skb) + tcph->doff * 4;
|
||||
|
||||
if (!skb_make_writable(pskb, optend))
|
||||
if (!skb_make_writable(skb, optend))
|
||||
return 0;
|
||||
|
||||
dir = CTINFO2DIR(ctinfo);
|
||||
|
||||
while (optoff < optend) {
|
||||
/* Usually: option, length. */
|
||||
unsigned char *op = (*pskb)->data + optoff;
|
||||
unsigned char *op = skb->data + optoff;
|
||||
|
||||
switch (op[0]) {
|
||||
case TCPOPT_EOL:
|
||||
@ -365,7 +357,7 @@ nf_nat_sack_adjust(struct sk_buff **pskb,
|
||||
if (op[0] == TCPOPT_SACK &&
|
||||
op[1] >= 2+TCPOLEN_SACK_PERBLOCK &&
|
||||
((op[1] - 2) % TCPOLEN_SACK_PERBLOCK) == 0)
|
||||
sack_adjust(*pskb, tcph, optoff+2,
|
||||
sack_adjust(skb, tcph, optoff+2,
|
||||
optoff+op[1], &nat->seq[!dir]);
|
||||
optoff += op[1];
|
||||
}
|
||||
@ -375,7 +367,7 @@ nf_nat_sack_adjust(struct sk_buff **pskb,
|
||||
|
||||
/* TCP sequence number adjustment. Returns 1 on success, 0 on failure */
|
||||
int
|
||||
nf_nat_seq_adjust(struct sk_buff **pskb,
|
||||
nf_nat_seq_adjust(struct sk_buff *skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo)
|
||||
{
|
||||
@ -390,10 +382,10 @@ nf_nat_seq_adjust(struct sk_buff **pskb,
|
||||
this_way = &nat->seq[dir];
|
||||
other_way = &nat->seq[!dir];
|
||||
|
||||
if (!skb_make_writable(pskb, ip_hdrlen(*pskb) + sizeof(*tcph)))
|
||||
if (!skb_make_writable(skb, ip_hdrlen(skb) + sizeof(*tcph)))
|
||||
return 0;
|
||||
|
||||
tcph = (void *)(*pskb)->data + ip_hdrlen(*pskb);
|
||||
tcph = (void *)skb->data + ip_hdrlen(skb);
|
||||
if (after(ntohl(tcph->seq), this_way->correction_pos))
|
||||
newseq = htonl(ntohl(tcph->seq) + this_way->offset_after);
|
||||
else
|
||||
@ -405,8 +397,8 @@ nf_nat_seq_adjust(struct sk_buff **pskb,
|
||||
else
|
||||
newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before);
|
||||
|
||||
nf_proto_csum_replace4(&tcph->check, *pskb, tcph->seq, newseq, 0);
|
||||
nf_proto_csum_replace4(&tcph->check, *pskb, tcph->ack_seq, newack, 0);
|
||||
nf_proto_csum_replace4(&tcph->check, skb, tcph->seq, newseq, 0);
|
||||
nf_proto_csum_replace4(&tcph->check, skb, tcph->ack_seq, newack, 0);
|
||||
|
||||
pr_debug("Adjusting sequence number from %u->%u, ack from %u->%u\n",
|
||||
ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),
|
||||
@ -415,10 +407,10 @@ nf_nat_seq_adjust(struct sk_buff **pskb,
|
||||
tcph->seq = newseq;
|
||||
tcph->ack_seq = newack;
|
||||
|
||||
if (!nf_nat_sack_adjust(pskb, tcph, ct, ctinfo))
|
||||
if (!nf_nat_sack_adjust(skb, tcph, ct, ctinfo))
|
||||
return 0;
|
||||
|
||||
nf_conntrack_tcp_update(*pskb, ip_hdrlen(*pskb), ct, dir);
|
||||
nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ MODULE_DESCRIPTION("IRC (DCC) NAT helper");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ip_nat_irc");
|
||||
|
||||
static unsigned int help(struct sk_buff **pskb,
|
||||
static unsigned int help(struct sk_buff *skb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int matchoff,
|
||||
unsigned int matchlen,
|
||||
@ -58,7 +58,7 @@ static unsigned int help(struct sk_buff **pskb,
|
||||
pr_debug("nf_nat_irc: inserting '%s' == %u.%u.%u.%u, port %u\n",
|
||||
buffer, NIPQUAD(ip), port);
|
||||
|
||||
ret = nf_nat_mangle_tcp_packet(pskb, exp->master, ctinfo,
|
||||
ret = nf_nat_mangle_tcp_packet(skb, exp->master, ctinfo,
|
||||
matchoff, matchlen, buffer,
|
||||
strlen(buffer));
|
||||
if (ret != NF_ACCEPT)
|
||||
|
@ -110,7 +110,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
|
||||
|
||||
/* outbound packets == from PNS to PAC */
|
||||
static int
|
||||
pptp_outbound_pkt(struct sk_buff **pskb,
|
||||
pptp_outbound_pkt(struct sk_buff *skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
struct PptpControlHeader *ctlh,
|
||||
@ -175,7 +175,7 @@ pptp_outbound_pkt(struct sk_buff **pskb,
|
||||
ntohs(REQ_CID(pptpReq, cid_off)), ntohs(new_callid));
|
||||
|
||||
/* mangle packet */
|
||||
if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
|
||||
if (nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
|
||||
cid_off + sizeof(struct pptp_pkt_hdr) +
|
||||
sizeof(struct PptpControlHeader),
|
||||
sizeof(new_callid), (char *)&new_callid,
|
||||
@ -213,7 +213,7 @@ pptp_exp_gre(struct nf_conntrack_expect *expect_orig,
|
||||
|
||||
/* inbound packets == from PAC to PNS */
|
||||
static int
|
||||
pptp_inbound_pkt(struct sk_buff **pskb,
|
||||
pptp_inbound_pkt(struct sk_buff *skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
struct PptpControlHeader *ctlh,
|
||||
@ -268,7 +268,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
|
||||
pr_debug("altering peer call id from 0x%04x to 0x%04x\n",
|
||||
ntohs(REQ_CID(pptpReq, pcid_off)), ntohs(new_pcid));
|
||||
|
||||
if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
|
||||
if (nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
|
||||
pcid_off + sizeof(struct pptp_pkt_hdr) +
|
||||
sizeof(struct PptpControlHeader),
|
||||
sizeof(new_pcid), (char *)&new_pcid,
|
||||
|
@ -98,21 +98,21 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
|
||||
/* manipulate a GRE packet according to maniptype */
|
||||
static int
|
||||
gre_manip_pkt(struct sk_buff **pskb, unsigned int iphdroff,
|
||||
gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype)
|
||||
{
|
||||
struct gre_hdr *greh;
|
||||
struct gre_hdr_pptp *pgreh;
|
||||
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
|
||||
struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
unsigned int hdroff = iphdroff + iph->ihl * 4;
|
||||
|
||||
/* pgreh includes two optional 32bit fields which are not required
|
||||
* to be there. That's where the magic '8' comes from */
|
||||
if (!skb_make_writable(pskb, hdroff + sizeof(*pgreh) - 8))
|
||||
if (!skb_make_writable(skb, hdroff + sizeof(*pgreh) - 8))
|
||||
return 0;
|
||||
|
||||
greh = (void *)(*pskb)->data + hdroff;
|
||||
greh = (void *)skb->data + hdroff;
|
||||
pgreh = (struct gre_hdr_pptp *)greh;
|
||||
|
||||
/* we only have destination manip of a packet, since 'source key'
|
||||
|
@ -52,20 +52,20 @@ icmp_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
}
|
||||
|
||||
static int
|
||||
icmp_manip_pkt(struct sk_buff **pskb,
|
||||
icmp_manip_pkt(struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype)
|
||||
{
|
||||
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
|
||||
struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
struct icmphdr *hdr;
|
||||
unsigned int hdroff = iphdroff + iph->ihl*4;
|
||||
|
||||
if (!skb_make_writable(pskb, hdroff + sizeof(*hdr)))
|
||||
if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
|
||||
return 0;
|
||||
|
||||
hdr = (struct icmphdr *)((*pskb)->data + hdroff);
|
||||
nf_proto_csum_replace2(&hdr->checksum, *pskb,
|
||||
hdr = (struct icmphdr *)(skb->data + hdroff);
|
||||
nf_proto_csum_replace2(&hdr->checksum, skb,
|
||||
hdr->un.echo.id, tuple->src.u.icmp.id, 0);
|
||||
hdr->un.echo.id = tuple->src.u.icmp.id;
|
||||
return 1;
|
||||
|
@ -88,12 +88,12 @@ tcp_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_manip_pkt(struct sk_buff **pskb,
|
||||
tcp_manip_pkt(struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype)
|
||||
{
|
||||
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
|
||||
struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
struct tcphdr *hdr;
|
||||
unsigned int hdroff = iphdroff + iph->ihl*4;
|
||||
__be32 oldip, newip;
|
||||
@ -103,14 +103,14 @@ tcp_manip_pkt(struct sk_buff **pskb,
|
||||
/* this could be a inner header returned in icmp packet; in such
|
||||
cases we cannot update the checksum field since it is outside of
|
||||
the 8 bytes of transport layer headers we are guaranteed */
|
||||
if ((*pskb)->len >= hdroff + sizeof(struct tcphdr))
|
||||
if (skb->len >= hdroff + sizeof(struct tcphdr))
|
||||
hdrsize = sizeof(struct tcphdr);
|
||||
|
||||
if (!skb_make_writable(pskb, hdroff + hdrsize))
|
||||
if (!skb_make_writable(skb, hdroff + hdrsize))
|
||||
return 0;
|
||||
|
||||
iph = (struct iphdr *)((*pskb)->data + iphdroff);
|
||||
hdr = (struct tcphdr *)((*pskb)->data + hdroff);
|
||||
iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
hdr = (struct tcphdr *)(skb->data + hdroff);
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC) {
|
||||
/* Get rid of src ip and src pt */
|
||||
@ -132,8 +132,8 @@ tcp_manip_pkt(struct sk_buff **pskb,
|
||||
if (hdrsize < sizeof(*hdr))
|
||||
return 1;
|
||||
|
||||
nf_proto_csum_replace4(&hdr->check, *pskb, oldip, newip, 1);
|
||||
nf_proto_csum_replace2(&hdr->check, *pskb, oldport, newport, 0);
|
||||
nf_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1);
|
||||
nf_proto_csum_replace2(&hdr->check, skb, oldport, newport, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -86,22 +86,22 @@ udp_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
}
|
||||
|
||||
static int
|
||||
udp_manip_pkt(struct sk_buff **pskb,
|
||||
udp_manip_pkt(struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype)
|
||||
{
|
||||
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
|
||||
struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
struct udphdr *hdr;
|
||||
unsigned int hdroff = iphdroff + iph->ihl*4;
|
||||
__be32 oldip, newip;
|
||||
__be16 *portptr, newport;
|
||||
|
||||
if (!skb_make_writable(pskb, hdroff + sizeof(*hdr)))
|
||||
if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
|
||||
return 0;
|
||||
|
||||
iph = (struct iphdr *)((*pskb)->data + iphdroff);
|
||||
hdr = (struct udphdr *)((*pskb)->data + hdroff);
|
||||
iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
hdr = (struct udphdr *)(skb->data + hdroff);
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC) {
|
||||
/* Get rid of src ip and src pt */
|
||||
@ -116,9 +116,9 @@ udp_manip_pkt(struct sk_buff **pskb,
|
||||
newport = tuple->dst.u.udp.port;
|
||||
portptr = &hdr->dest;
|
||||
}
|
||||
if (hdr->check || (*pskb)->ip_summed == CHECKSUM_PARTIAL) {
|
||||
nf_proto_csum_replace4(&hdr->check, *pskb, oldip, newip, 1);
|
||||
nf_proto_csum_replace2(&hdr->check, *pskb, *portptr, newport,
|
||||
if (hdr->check || skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
nf_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1);
|
||||
nf_proto_csum_replace2(&hdr->check, skb, *portptr, newport,
|
||||
0);
|
||||
if (!hdr->check)
|
||||
hdr->check = CSUM_MANGLED_0;
|
||||
|
@ -37,7 +37,7 @@ static int unknown_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
}
|
||||
|
||||
static int
|
||||
unknown_manip_pkt(struct sk_buff **pskb,
|
||||
unknown_manip_pkt(struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype)
|
||||
|
@ -65,7 +65,7 @@ static struct xt_table nat_table = {
|
||||
};
|
||||
|
||||
/* Source NAT */
|
||||
static unsigned int ipt_snat_target(struct sk_buff **pskb,
|
||||
static unsigned int ipt_snat_target(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -78,7 +78,7 @@ static unsigned int ipt_snat_target(struct sk_buff **pskb,
|
||||
|
||||
NF_CT_ASSERT(hooknum == NF_IP_POST_ROUTING);
|
||||
|
||||
ct = nf_ct_get(*pskb, &ctinfo);
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
|
||||
/* Connection must be valid and new. */
|
||||
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
|
||||
@ -107,7 +107,7 @@ static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
|
||||
ip_rt_put(rt);
|
||||
}
|
||||
|
||||
static unsigned int ipt_dnat_target(struct sk_buff **pskb,
|
||||
static unsigned int ipt_dnat_target(struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
unsigned int hooknum,
|
||||
@ -121,14 +121,14 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb,
|
||||
NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
|
||||
hooknum == NF_IP_LOCAL_OUT);
|
||||
|
||||
ct = nf_ct_get(*pskb, &ctinfo);
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
|
||||
/* Connection must be valid and new. */
|
||||
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
|
||||
|
||||
if (hooknum == NF_IP_LOCAL_OUT &&
|
||||
mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)
|
||||
warn_if_extra_mangle(ip_hdr(*pskb)->daddr,
|
||||
warn_if_extra_mangle(ip_hdr(skb)->daddr,
|
||||
mr->range[0].min_ip);
|
||||
|
||||
return nf_nat_setup_info(ct, &mr->range[0], hooknum);
|
||||
@ -204,7 +204,7 @@ alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum)
|
||||
return nf_nat_setup_info(ct, &range, hooknum);
|
||||
}
|
||||
|
||||
int nf_nat_rule_find(struct sk_buff **pskb,
|
||||
int nf_nat_rule_find(struct sk_buff *skb,
|
||||
unsigned int hooknum,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
@ -212,7 +212,7 @@ int nf_nat_rule_find(struct sk_buff **pskb,
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ipt_do_table(pskb, hooknum, in, out, &nat_table);
|
||||
ret = ipt_do_table(skb, hooknum, in, out, &nat_table);
|
||||
|
||||
if (ret == NF_ACCEPT) {
|
||||
if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user