patch-2.1.91 linux/net/ipv6/ip6_output.c
Next file: linux/net/ipv6/ipv6_sockglue.c
Previous file: linux/net/ipv6/ip6_fib.c
Back to the patch index
Back to the overall index
- Lines: 114
- Date:
Mon Mar 23 16:48:25 1998
- Orig file:
v2.1.90/linux/net/ipv6/ip6_output.c
- Orig date:
Tue Mar 17 22:18:16 1998
diff -u --recursive --new-file v2.1.90/linux/net/ipv6/ip6_output.c linux/net/ipv6/ip6_output.c
@@ -5,7 +5,7 @@
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: ip6_output.c,v 1.9 1998/03/08 05:56:50 davem Exp $
+ * $Id: ip6_output.c,v 1.10 1998/03/20 09:12:17 davem Exp $
*
* Based on linux/net/ipv4/ip_output.c
*
@@ -82,64 +82,43 @@
/*
* xmit an sk_buff (used by TCP)
- * sk can be NULL (for sending RESETs)
*/
int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
struct ipv6_options *opt)
{
- struct ipv6_pinfo *np = NULL;
- struct dst_entry *dst = NULL;
+ struct ipv6_pinfo * np = sk ? &sk->net_pinfo.af_inet6 : NULL;
+ struct dst_entry *dst = skb->dst;
struct ipv6hdr *hdr;
int seg_len;
+ int hlimit;
- hdr = skb->nh.ipv6h;
-
- if (sk) {
- np = &sk->net_pinfo.af_inet6;
+ /* Do something with IPv6 options headers here. */
- if (sk->dst_cache) {
- /*
- * dst_check returns NULL if route is no longer valid
- */
- dst = dst_check(&sk->dst_cache, np->dst_cookie);
- }
- }
+ seg_len = skb->len;
- if (dst == NULL) {
- dst = ip6_route_output(sk, fl);
-
- if (dst->error) {
- /*
- * NETUNREACH usually
- */
- dst_release(dst);
- return dst->error;
- }
- }
-
- skb->dst = dst_clone(dst);
- seg_len = skb->tail - ((unsigned char *) hdr);
- hdr = skb->nh.ipv6h;
+ hdr = skb->nh.ipv6h = (struct ipv6hdr*)skb_push(skb, sizeof(struct ipv6hdr));
/*
* Fill in the IPv6 header
*/
hdr->version = 6;
- hdr->priority = np ? np->priority : 0;
-
- if (np)
+ if (np) {
+ hdr->priority = np->priority;
memcpy(hdr->flow_lbl, (void *) &np->flow_lbl, 3);
- else
+ hlimit = np->hop_limit;
+ } else {
+ hdr->priority = 0;
memset(hdr->flow_lbl, 0, 3);
+ hlimit = -1;
+ }
+ if (hlimit < 0)
+ hlimit = ((struct rt6_info*)dst)->rt6i_hoplimit;
- hdr->payload_len = htons(seg_len - sizeof(struct ipv6hdr));
+ hdr->payload_len = htons(seg_len);
hdr->nexthdr = fl->proto;
- if (np == NULL || np->hop_limit < 0)
- hdr->hop_limit = ((struct rt6_info*)dst)->rt6i_hoplimit;
- else
- hdr->hop_limit = np->hop_limit;
+ hdr->hop_limit = hlimit;
ipv6_addr_copy(&hdr->saddr, fl->nl_u.ip6_u.saddr);
ipv6_addr_copy(&hdr->daddr, fl->nl_u.ip6_u.daddr);
@@ -147,12 +126,6 @@
ipv6_statistics.Ip6OutRequests++;
dst->output(skb);
- if (sk) {
- if (sk->dst_cache == NULL)
- ip6_dst_store(sk, dst);
- } else
- dst_release(dst);
-
return 0;
}
@@ -412,6 +385,9 @@
}
dst = NULL;
+
+ if (!fl->oif && ipv6_addr_is_multicast(fl->nl_u.ip6_u.daddr))
+ fl->oif = np->mcast_oif;
if (sk->dst_cache)
dst = dst_check(&sk->dst_cache, np->dst_cookie);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov