Commit 0daefd17 authored by David S. Miller's avatar David S. Miller

Merge davem@nuts.davemloft.net:/disk1/BK/net-2.6

into kernel.bkbits.net:/home/davem/net-2.6
parents 981a1ad3 caa702e2
DaveM:
If you agree with it I will send two small patches to modify
kernel's configure help.
Ulisses
--------------------------------------------------------------------------------
+ ABSTRACT
--------------------------------------------------------------------------------
......@@ -405,8 +397,3 @@ then poll for frames.
Jesse Brandeburg, for fixing my grammathical/spelling errors
>>> EOF
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
\ No newline at end of file
......@@ -29,11 +29,26 @@ static void update(struct crypto_tfm *tfm,
unsigned int i;
for (i = 0; i < nsg; i++) {
char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm),
p, sg[i].length);
struct page *pg = sg[i].page;
unsigned int offset = sg[i].offset;
unsigned int l = sg[i].length;
do {
unsigned int bytes_from_page = min(l, ((unsigned int)
(PAGE_SIZE)) -
offset);
char *p = crypto_kmap(pg, 0) + offset;
tfm->__crt_alg->cra_digest.dia_update
(crypto_tfm_ctx(tfm), p,
bytes_from_page);
crypto_kunmap(p, 0);
crypto_yield(tfm);
offset = 0;
pg++;
l -= bytes_from_page;
} while (l > 0);
}
}
......
......@@ -192,6 +192,8 @@ struct inet6_skb_parm
__u16 dst1;
};
#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))
struct ipv6_pinfo {
struct in6_addr saddr;
struct in6_addr rcv_saddr;
......
......@@ -89,6 +89,7 @@ struct dst_ops
int (*gc)(void);
struct dst_entry * (*check)(struct dst_entry *, __u32 cookie);
void (*destroy)(struct dst_entry *);
void (*ifdown)(struct dst_entry *, int how);
struct dst_entry * (*negative_advice)(struct dst_entry *);
void (*link_failure)(struct sk_buff *);
void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
......
......@@ -356,7 +356,6 @@ extern int ip6_dst_lookup(struct sock *sk,
*/
extern int ip6_output(struct sk_buff **pskb);
extern int ip6_output2(struct sk_buff **pskb);
extern int ip6_forward(struct sk_buff *skb);
extern int ip6_input(struct sk_buff *skb);
extern int ip6_mc_input(struct sk_buff *skb);
......
......@@ -398,6 +398,21 @@ static inline int sock_flag(struct sock *sk, enum sock_flags flag)
return test_bit(flag, &sk->sk_flags);
}
static inline void sk_acceptq_removed(struct sock *sk)
{
sk->sk_ack_backlog--;
}
static inline void sk_acceptq_added(struct sock *sk)
{
sk->sk_ack_backlog++;
}
static inline int sk_acceptq_is_full(struct sock *sk)
{
return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
}
/* The per-socket spinlock must be held here. */
#define sk_add_backlog(__sk, __skb) \
do { if (!(__sk)->sk_backlog.tail) { \
......@@ -410,6 +425,20 @@ do { if (!(__sk)->sk_backlog.tail) { \
(__skb)->next = NULL; \
} while(0)
#define sk_wait_event(__sk, __timeo, __condition) \
({ int rc; \
release_sock(__sk); \
rc = __condition; \
if (!rc) { \
*(__timeo) = schedule_timeout(*(__timeo)); \
rc = __condition; \
} \
lock_sock(__sk); \
rc; \
})
extern int sk_wait_data(struct sock *sk, long *timeo);
/* IP protocol blocks we attach to sockets.
* socket layer -> transport layer interface
* transport -> network interface is defined by struct inet_proto
......@@ -898,6 +927,11 @@ static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
atomic_add(skb->truesize, &sk->sk_rmem_alloc);
}
extern void sk_reset_timer(struct sock *sk, struct timer_list* timer,
unsigned long expires);
extern void sk_stop_timer(struct sock *sk, struct timer_list* timer);
static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
int err = 0;
......@@ -1035,6 +1069,20 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
sk->sk_stamp = *stamp;
}
/**
* sk_eat_skb - Release a skb if it is no longer needed
* @sk - socket to eat this skb from
* @skb - socket buffer to eat
*
* This routine must be called with interrupts disabled or with the socket
* locked so that the sk_buff queue operation is ok.
*/
static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb)
{
__skb_unlink(skb, &sk->sk_receive_queue);
__kfree_skb(skb);
}
extern atomic_t netstamp_needed;
extern void sock_enable_timestamp(struct sock *sk);
extern void sock_disable_timestamp(struct sock *sk);
......
......@@ -989,9 +989,7 @@ static inline void tcp_clear_xmit_timer(struct sock *sk, int what)
tp->pending = 0;
#ifdef TCP_CLEAR_TIMERS
if (timer_pending(&tp->retransmit_timer) &&
del_timer(&tp->retransmit_timer))
__sock_put(sk);
sk_stop_timer(sk, &tp->retransmit_timer);
#endif
break;
case TCP_TIME_DACK:
......@@ -999,9 +997,7 @@ static inline void tcp_clear_xmit_timer(struct sock *sk, int what)
tp->ack.pending = 0;
#ifdef TCP_CLEAR_TIMERS
if (timer_pending(&tp->delack_timer) &&
del_timer(&tp->delack_timer))
__sock_put(sk);
sk_stop_timer(sk, &tp->delack_timer);
#endif
break;
default:
......@@ -1030,15 +1026,13 @@ static inline void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long
case TCP_TIME_PROBE0:
tp->pending = what;
tp->timeout = jiffies+when;
if (!mod_timer(&tp->retransmit_timer, tp->timeout))
sock_hold(sk);
sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout);
break;
case TCP_TIME_DACK:
tp->ack.pending |= TCP_ACK_TIMER;
tp->ack.timeout = jiffies+when;
if (!mod_timer(&tp->delack_timer, tp->ack.timeout))
sock_hold(sk);
sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout);
break;
default:
......@@ -1800,28 +1794,13 @@ static inline int tcp_full_space( struct sock *sk)
return tcp_win_from_space(sk->sk_rcvbuf);
}
static inline void tcp_acceptq_removed(struct sock *sk)
{
sk->sk_ack_backlog--;
}
static inline void tcp_acceptq_added(struct sock *sk)
{
sk->sk_ack_backlog++;
}
static inline int tcp_acceptq_is_full(struct sock *sk)
{
return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
}
static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req,
struct sock *child)
{
struct tcp_opt *tp = tcp_sk(sk);
req->sk = child;
tcp_acceptq_added(sk);
sk_acceptq_added(sk);
if (!tp->accept_queue_tail) {
tp->accept_queue = req;
......
......@@ -95,17 +95,13 @@ static void l2cap_sock_timeout(unsigned long arg)
static void l2cap_sock_set_timer(struct sock *sk, long timeout)
{
BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
if (!mod_timer(&sk->sk_timer, jiffies + timeout))
sock_hold(sk);
sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
}
static void l2cap_sock_clear_timer(struct sock *sk)
{
BT_DBG("sock %p state %d", sk, sk->sk_state);
if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer))
__sock_put(sk);
sk_stop_timer(sk, &sk->sk_timer);
}
static void l2cap_sock_init_timer(struct sock *sk)
......
......@@ -91,17 +91,13 @@ static void sco_sock_timeout(unsigned long arg)
static void sco_sock_set_timer(struct sock *sk, long timeout)
{
BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout);
if (!mod_timer(&sk->sk_timer, jiffies + timeout))
sock_hold(sk);
sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
}
static void sco_sock_clear_timer(struct sock *sk)
{
BT_DBG("sock %p state %d", sk, sk->sk_state);
if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer))
__sock_put(sk);
sk_stop_timer(sk, &sk->sk_timer);
}
static void sco_sock_init_timer(struct sock *sk)
......
......@@ -230,8 +230,8 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, void
if (event!=NETDEV_DOWN &&
dst->output == dst_discard_out) {
dst->dev = &loopback_dev;
dev_put(dev);
dev_hold(&loopback_dev);
dev_put(dev);
dst->output = dst_discard_out;
if (dst->neighbour && dst->neighbour->dev == dev) {
dst->neighbour->dev = &loopback_dev;
......@@ -242,6 +242,8 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, void
dst->input = dst_discard_in;
dst->output = dst_discard_out;
}
if (dst->ops->ifdown)
dst->ops->ifdown(dst, event != NETDEV_DOWN);
}
}
spin_unlock_bh(&dst_lock);
......
......@@ -917,6 +917,31 @@ void __release_sock(struct sock *sk)
} while((skb = sk->sk_backlog.head) != NULL);
}
/**
* sk_wait_data - wait for data to arrive at sk_receive_queue
* sk - sock to wait on
* timeo - for how long
*
* Now socket state including sk->sk_err is changed only under lock,
* hence we may omit checks after joining wait queue.
* We check receive queue before schedule() only as optimization;
* it is very likely that release_sock() added new data.
*/
int sk_wait_data(struct sock *sk, long *timeo)
{
int rc;
DEFINE_WAIT(wait);
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
rc = sk_wait_event(sk, timeo, !skb_queue_empty(&sk->sk_receive_queue));
clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
finish_wait(sk->sk_sleep, &wait);
return rc;
}
EXPORT_SYMBOL(sk_wait_data);
/*
* Set of default routines for initialising struct proto_ops when
* the protocol does not support a particular function. In certain
......@@ -1099,6 +1124,23 @@ void sk_send_sigurg(struct sock *sk)
sk_wake_async(sk, 3, POLL_PRI);
}
void sk_reset_timer(struct sock *sk, struct timer_list* timer,
unsigned long expires)
{
if (!mod_timer(timer, expires))
sock_hold(sk);
}
EXPORT_SYMBOL(sk_reset_timer);
void sk_stop_timer(struct sock *sk, struct timer_list* timer)
{
if (timer_pending(timer) && del_timer(timer))
__sock_put(sk);
}
EXPORT_SYMBOL(sk_stop_timer);
void sock_init_data(struct socket *sock, struct sock *sk)
{
skb_queue_head_init(&sk->sk_receive_queue);
......
......@@ -179,11 +179,10 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
return 0;
}
/* Look for ifname matches; this should unroll nicely. */
for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
ret |= (((const unsigned long *)indev)[i]
^ ((const unsigned long *)arpinfo->iniface)[i])
& ((const unsigned long *)arpinfo->iniface_mask)[i];
/* Look for ifname matches. */
for (i = 0, ret = 0; i < IFNAMSIZ; i++) {
ret |= (indev[i] ^ arpinfo->iniface[i])
& arpinfo->iniface_mask[i];
}
if (FWINV(ret != 0, ARPT_INV_VIA_IN)) {
......
......@@ -138,6 +138,7 @@ static struct timer_list rt_secret_timer;
static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
static void ipv4_dst_destroy(struct dst_entry *dst);
static void ipv4_dst_ifdown(struct dst_entry *dst, int how);
static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
static void ipv4_link_failure(struct sk_buff *skb);
static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
......@@ -150,6 +151,7 @@ static struct dst_ops ipv4_dst_ops = {
.gc = rt_garbage_collect,
.check = ipv4_dst_check,
.destroy = ipv4_dst_destroy,
.ifdown = ipv4_dst_ifdown,
.negative_advice = ipv4_negative_advice,
.link_failure = ipv4_link_failure,
.update_pmtu = ip_rt_update_pmtu,
......@@ -1336,6 +1338,16 @@ static void ipv4_dst_destroy(struct dst_entry *dst)
}
}
static void ipv4_dst_ifdown(struct dst_entry *dst, int how)
{
struct rtable *rt = (struct rtable *) dst;
struct in_device *idev = rt->idev;
if (idev) {
rt->idev = NULL;
in_dev_put(idev);
}
}
static void ipv4_link_failure(struct sk_buff *skb)
{
struct rtable *rt;
......
......@@ -648,7 +648,7 @@ static void tcp_listen_stop (struct sock *sk)
local_bh_enable();
sock_put(child);
tcp_acceptq_removed(sk);
sk_acceptq_removed(sk);
tcp_openreq_fastfree(req);
}
BUG_TRAP(!sk->sk_ack_backlog);
......@@ -1296,18 +1296,6 @@ static int tcp_recv_urg(struct sock *sk, long timeo,
return -EAGAIN;
}
/*
* Release a skb if it is no longer needed. This routine
* must be called with interrupts disabled or with the
* socket locked so that the sk_buff queue operation is ok.
*/
static inline void tcp_eat_skb(struct sock *sk, struct sk_buff *skb)
{
__skb_unlink(skb, &sk->sk_receive_queue);
__kfree_skb(skb);
}
/* Clean up the receive buffer for full frames taken by the user,
* then send an ACK if necessary. COPIED is the number of bytes
* tcp_recvmsg has given to the user so far, it speeds up the
......@@ -1368,31 +1356,6 @@ static void cleanup_rbuf(struct sock *sk, int copied)
tcp_send_ack(sk);
}
/* Now socket state including sk->sk_err is changed only under lock,
* hence we may omit checks after joining wait queue.
* We check receive queue before schedule() only as optimization;
* it is very likely that release_sock() added new data.
*/
static long tcp_data_wait(struct sock *sk, long timeo)
{
DEFINE_WAIT(wait);
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
release_sock(sk);
if (skb_queue_empty(&sk->sk_receive_queue))
timeo = schedule_timeout(timeo);
lock_sock(sk);
clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
finish_wait(sk->sk_sleep, &wait);
return timeo;
}
static void tcp_prequeue_process(struct sock *sk)
{
struct sk_buff *skb;
......@@ -1473,11 +1436,11 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
break;
}
if (skb->h.th->fin) {
tcp_eat_skb(sk, skb);
sk_eat_skb(sk, skb);
++seq;
break;
}
tcp_eat_skb(sk, skb);
sk_eat_skb(sk, skb);
if (!desc->count)
break;
}
......@@ -1672,9 +1635,8 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
/* Do not sleep, just process backlog. */
release_sock(sk);
lock_sock(sk);
} else {
timeo = tcp_data_wait(sk, timeo);
}
} else
sk_wait_data(sk, &timeo);
if (user_recv) {
int chunk;
......@@ -1758,14 +1720,14 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
if (skb->h.th->fin)
goto found_fin_ok;
if (!(flags & MSG_PEEK))
tcp_eat_skb(sk, skb);
sk_eat_skb(sk, skb);
continue;
found_fin_ok:
/* Process the FIN. */
++*seq;
if (!(flags & MSG_PEEK))
tcp_eat_skb(sk, skb);
sk_eat_skb(sk, skb);
break;
} while (len > 0);
......@@ -2263,7 +2225,7 @@ struct sock *tcp_accept(struct sock *sk, int flags, int *err)
tp->accept_queue_tail = NULL;
newsk = req->sk;
tcp_acceptq_removed(sk);
sk_acceptq_removed(sk);
tcp_openreq_fastfree(req);
BUG_TRAP(newsk->sk_state != TCP_SYN_RECV);
release_sock(sk);
......
......@@ -463,6 +463,8 @@ void tcp_rcv_space_adjust(struct sock *sk)
tp->rcvq_space.space = space;
if (sysctl_tcp_moderate_rcvbuf) {
int new_clamp = space;
/* Receive space grows, normalize in order to
* take into account packet headers and sk_buff
* structure overhead.
......@@ -472,10 +474,16 @@ void tcp_rcv_space_adjust(struct sock *sk)
space = 1;
rcvmem = (tp->advmss + MAX_TCP_HEADER +
16 + sizeof(struct sk_buff));
while (tcp_win_from_space(rcvmem) < tp->advmss)
rcvmem += 128;
space *= rcvmem;
space = min(space, sysctl_tcp_rmem[2]);
if (space > sk->sk_rcvbuf)
if (space > sk->sk_rcvbuf) {
sk->sk_rcvbuf = space;
/* Make the window clamp follow along. */
tp->window_clamp = new_clamp;
}
}
}
......
......@@ -1442,7 +1442,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
* clogging syn queue with openreqs with exponentially increasing
* timeout.
*/
if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
goto drop;
req = tcp_openreq_alloc();
......@@ -1567,7 +1567,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
struct tcp_opt *newtp;
struct sock *newsk;
if (tcp_acceptq_is_full(sk))
if (sk_acceptq_is_full(sk))
goto exit_overflow;
if (!dst && (dst = tcp_v4_route_req(sk, req)) == NULL)
......
......@@ -1389,8 +1389,7 @@ void tcp_send_delayed_ack(struct sock *sk)
}
tp->ack.pending |= TCP_ACK_SCHED|TCP_ACK_TIMER;
tp->ack.timeout = timeout;
if (!mod_timer(&tp->delack_timer, timeout))
sock_hold(sk);
sk_reset_timer(sk, &tp->delack_timer, timeout);
}
/* This routine sends an ack and also updates the window. */
......
......@@ -68,18 +68,13 @@ void tcp_clear_xmit_timers(struct sock *sk)
struct tcp_opt *tp = tcp_sk(sk);
tp->pending = 0;
if (timer_pending(&tp->retransmit_timer) &&
del_timer(&tp->retransmit_timer))
__sock_put(sk);
sk_stop_timer(sk, &tp->retransmit_timer);
tp->ack.pending = 0;
tp->ack.blocked = 0;
if (timer_pending(&tp->delack_timer) &&
del_timer(&tp->delack_timer))
__sock_put(sk);
sk_stop_timer(sk, &tp->delack_timer);
if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer))
__sock_put(sk);
sk_stop_timer(sk, &sk->sk_timer);
}
static void tcp_write_err(struct sock *sk)
......@@ -218,8 +213,7 @@ static void tcp_delack_timer(unsigned long data)
/* Try again later. */
tp->ack.blocked = 1;
NET_INC_STATS_BH(DelayedACKLocked);
if (!mod_timer(&tp->delack_timer, jiffies + TCP_DELACK_MIN))
sock_hold(sk);
sk_reset_timer(sk, &tp->delack_timer, jiffies + TCP_DELACK_MIN);
goto out_unlock;
}
......@@ -229,8 +223,7 @@ static void tcp_delack_timer(unsigned long data)
goto out;
if (time_after(tp->ack.timeout, jiffies)) {
if (!mod_timer(&tp->delack_timer, tp->ack.timeout))
sock_hold(sk);
sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout);
goto out;
}
tp->ack.pending &= ~TCP_ACK_TIMER;
......@@ -429,8 +422,7 @@ static void tcp_write_timer(unsigned long data)
bh_lock_sock(sk);
if (sock_owned_by_user(sk)) {
/* Try again later */
if (!mod_timer(&tp->retransmit_timer, jiffies + (HZ/20)))
sock_hold(sk);
sk_reset_timer(sk, &tp->retransmit_timer, jiffies + (HZ / 20));
goto out_unlock;
}
......@@ -438,8 +430,7 @@ static void tcp_write_timer(unsigned long data)
goto out;
if (time_after(tp->timeout, jiffies)) {
if (!mod_timer(&tp->retransmit_timer, tp->timeout))
sock_hold(sk);
sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout);
goto out;
}
......@@ -557,14 +548,12 @@ static void tcp_synack_timer(struct sock *sk)
void tcp_delete_keepalive_timer (struct sock *sk)
{
if (timer_pending(&sk->sk_timer) && del_timer (&sk->sk_timer))
__sock_put(sk);
sk_stop_timer(sk, &sk->sk_timer);
}
void tcp_reset_keepalive_timer (struct sock *sk, unsigned long len)
{
if (!mod_timer(&sk->sk_timer, jiffies + len))
sock_hold(sk);
sk_reset_timer(sk, &sk->sk_timer, jiffies + len);
}
void tcp_set_keepalive(struct sock *sk, int val)
......
......@@ -363,7 +363,7 @@ void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset);
struct xfrm_state *x;
if (type != ICMPV6_DEST_UNREACH ||
if (type != ICMPV6_DEST_UNREACH &&
type != ICMPV6_PKT_TOOBIG)
return;
......
......@@ -145,10 +145,8 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
(struct in6_addr *)(skb->nh.raw + serr->addr_offset));
if (np->sndflow)
sin->sin6_flowinfo = *(u32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK;
if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
sin->sin6_scope_id = opt->iif;
}
if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
sin->sin6_scope_id = IP6CB(skb)->iif;
} else {
ipv6_addr_set(&sin->sin6_addr, 0, 0,
htonl(0xffff),
......@@ -167,10 +165,8 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
ipv6_addr_copy(&sin->sin6_addr, &skb->nh.ipv6h->saddr);
if (np->rxopt.all)
datagram_recv_ctl(sk, msg, skb);
if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
sin->sin6_scope_id = opt->iif;
}
if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
sin->sin6_scope_id = IP6CB(skb)->iif;
} else {
struct inet_opt *inet = inet_sk(sk);
......@@ -211,7 +207,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
struct inet6_skb_parm *opt = IP6CB(skb);
if (np->rxopt.bits.rxinfo) {
struct in6_pktinfo src_info;
......
......@@ -324,7 +324,7 @@ void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
struct ipv6_esp_hdr *esph = (struct ipv6_esp_hdr*)(skb->data+offset);
struct xfrm_state *x;
if (type != ICMPV6_DEST_UNREACH ||
if (type != ICMPV6_DEST_UNREACH &&
type != ICMPV6_PKT_TOOBIG)
return;
......
......@@ -155,7 +155,7 @@ static struct tlvtype_proc tlvprocdestopt_lst[] = {
static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
{
struct sk_buff *skb = *skbp;
struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
struct inet6_skb_parm *opt = IP6CB(skb);
if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
!pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
......@@ -217,7 +217,7 @@ void __init ipv6_nodata_init(void)
static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
{
struct sk_buff *skb = *skbp;
struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
struct inet6_skb_parm *opt = IP6CB(skb);
struct in6_addr *addr;
struct in6_addr daddr;
int n, i;
......@@ -288,7 +288,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
return -1;
}
*skbp = skb = skb2;
opt = (struct inet6_skb_parm *)skb2->cb;
opt = IP6CB(skb2);
hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
}
......@@ -418,7 +418,7 @@ ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
{
if (skb->nh.raw[optoff+1] == 2) {
((struct inet6_skb_parm*)skb->cb)->ra = optoff;
IP6CB(skb)->ra = optoff;
return 1;
}
LIMIT_NETDEBUG(
......@@ -482,7 +482,7 @@ static struct tlvtype_proc tlvprochopopt_lst[] = {
int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff)
{
((struct inet6_skb_parm*)skb->cb)->hop = sizeof(struct ipv6hdr);
IP6CB(skb)->hop = sizeof(struct ipv6hdr);
if (ip6_parse_tlv(tlvprochopopt_lst, skb))
return sizeof(struct ipv6hdr);
return -1;
......
......@@ -74,7 +74,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
/* Store incoming device index. When the packet will
be queued, we cannot refer to skb->dev anymore.
*/
((struct inet6_skb_parm *)skb->cb)->iif = dev->ifindex;
IP6CB(skb)->iif = dev->ifindex;
if (skb->len < sizeof(struct ipv6hdr))
goto err;
......
......@@ -107,7 +107,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
}
int ip6_output2(struct sk_buff **pskb)
static int ip6_output2(struct sk_buff **pskb)
{
struct sk_buff *skb = *pskb;
struct dst_entry *dst = skb->dst;
......@@ -349,7 +349,7 @@ int ip6_forward(struct sk_buff *skb)
{
struct dst_entry *dst = skb->dst;
struct ipv6hdr *hdr = skb->nh.ipv6h;
struct inet6_skb_parm *opt =(struct inet6_skb_parm*)skb->cb;
struct inet6_skb_parm *opt = IP6CB(skb);
if (ipv6_devconf.forwarding == 0)
goto error;
......
......@@ -395,7 +395,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
if (!dst)
return;
......@@ -486,7 +486,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
if (!dst)
return;
......@@ -562,7 +562,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output2);
dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
if (!dst)
return;
......
......@@ -409,10 +409,8 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
sin6->sin6_flowinfo = 0;
sin6->sin6_scope_id = 0;
if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
sin6->sin6_scope_id = opt->iif;
}
if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
sin6->sin6_scope_id = IP6CB(skb)->iif;
}
sock_recv_timestamp(msg, sk, skb);
......
......@@ -84,6 +84,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort);
static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
static struct dst_entry *ip6_negative_advice(struct dst_entry *);
static void ip6_dst_destroy(struct dst_entry *);
static void ip6_dst_ifdown(struct dst_entry *, int how);
static int ip6_dst_gc(void);
static int ip6_pkt_discard(struct sk_buff *skb);
......@@ -98,6 +99,7 @@ static struct dst_ops ip6_dst_ops = {
.gc_thresh = 1024,
.check = ip6_dst_check,
.destroy = ip6_dst_destroy,
.ifdown = ip6_dst_ifdown,
.negative_advice = ip6_negative_advice,
.link_failure = ip6_link_failure,
.update_pmtu = ip6_rt_update_pmtu,
......@@ -143,9 +145,17 @@ static __inline__ struct rt6_info *ip6_dst_alloc(void)
static void ip6_dst_destroy(struct dst_entry *dst)
{
struct rt6_info *rt = (struct rt6_info *)dst;
if (rt->rt6i_idev != NULL)
in6_dev_put(rt->rt6i_idev);
struct inet6_dev *idev = rt->rt6i_idev;
if (idev != NULL) {
rt->rt6i_idev = NULL;
in6_dev_put(idev);
}
}
static void ip6_dst_ifdown(struct dst_entry *dst, int how)
{
ip6_dst_destroy(dst);
}
/*
......@@ -573,6 +583,8 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
/* Protected by rt6_lock. */
static struct dst_entry *ndisc_dst_gc_list;
static int ipv6_get_mtu(struct net_device *dev);
static inline unsigned int ipv6_advmss(unsigned int mtu);
struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
struct neighbour *neigh,
......@@ -598,6 +610,8 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
rt->rt6i_metric = 0;
atomic_set(&rt->u.dst.__refcnt, 1);
rt->u.dst.metrics[RTAX_HOPLIMIT-1] = 255;
rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&rt->u.dst));
rt->u.dst.output = output;
write_lock_bh(&rt6_lock);
......
......@@ -536,8 +536,7 @@ static int tcp_v6_hash_connect(struct sock *sk)
static __inline__ int tcp_v6_iif(struct sk_buff *skb)
{
struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
return opt->iif;
return IP6CB(skb)->iif;
}
static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
......@@ -879,7 +878,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
np->rxopt.bits.srcrt == 2 &&
req->af.v6_req.pktopts) {
struct sk_buff *pktopts = req->af.v6_req.pktopts;
struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)pktopts->cb;
struct inet6_skb_parm *rxopt = IP6CB(pktopts);
if (rxopt->srcrt)
opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt));
}
......@@ -932,7 +931,7 @@ static struct or_calltable or_ipv6 = {
static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
struct inet6_skb_parm *opt = IP6CB(skb);
if (np->rxopt.all) {
if ((opt->hop && np->rxopt.bits.hopopts) ||
......@@ -1183,7 +1182,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
goto drop;
}
if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
goto drop;
req = tcp_openreq_alloc();
......@@ -1300,12 +1299,12 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
opt = np->opt;
if (tcp_acceptq_is_full(sk))
if (sk_acceptq_is_full(sk))
goto out_overflow;
if (np->rxopt.bits.srcrt == 2 &&
opt == NULL && req->af.v6_req.pktopts) {
struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)req->af.v6_req.pktopts->cb;
struct inet6_skb_parm *rxopt = IP6CB(req->af.v6_req.pktopts);
if (rxopt->srcrt)
opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(req->af.v6_req.pktopts->nh.raw+rxopt->srcrt));
}
......
......@@ -432,10 +432,8 @@ static int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
if (np->rxopt.all)
datagram_recv_ctl(sk, msg, skb);
if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
sin6->sin6_scope_id = opt->iif;
}
if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
sin6->sin6_scope_id = IP6CB(skb)->iif;
}
}
err = copied;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment