diff --git a/[refs] b/[refs] index fcf835a128ab..b6dceddbc5c4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e933d0198d399842f075c2c8af0f38630e7e4bee +refs/heads/master: 6d9e5130b96daa1656966f7271e8a0928b3906c4 diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c index 729281961f22..d4ddeba56682 100644 --- a/trunk/drivers/char/random.c +++ b/trunk/drivers/char/random.c @@ -1523,21 +1523,6 @@ __u32 secure_ip_id(__be32 daddr) return half_md4_transform(hash, keyptr->secret); } -__u32 secure_ipv6_id(const __be32 daddr[4]) -{ - const struct keydata *keyptr; - __u32 hash[4]; - - keyptr = get_keyptr(); - - hash[0] = (__force __u32)daddr[0]; - hash[1] = (__force __u32)daddr[1]; - hash[2] = (__force __u32)daddr[2]; - hash[3] = (__force __u32)daddr[3]; - - return half_md4_transform(hash, keyptr->secret); -} - #ifdef CONFIG_INET __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, diff --git a/trunk/drivers/net/benet/be_cmds.c b/trunk/drivers/net/benet/be_cmds.c index 054fa67bc4e3..f520a5c75032 100644 --- a/trunk/drivers/net/benet/be_cmds.c +++ b/trunk/drivers/net/benet/be_cmds.c @@ -2390,7 +2390,7 @@ int be_cmd_get_cntl_attributes(struct be_adapter *adapter) } /* Uses mbox */ -int be_cmd_req_native_mode(struct be_adapter *adapter) +int be_cmd_check_native_mode(struct be_adapter *adapter) { struct be_mcc_wrb *wrb; struct be_cmd_req_set_func_cap *req; diff --git a/trunk/drivers/net/benet/be_cmds.h b/trunk/drivers/net/benet/be_cmds.h index 8e4d48824fe9..1151df6b0020 100644 --- a/trunk/drivers/net/benet/be_cmds.h +++ b/trunk/drivers/net/benet/be_cmds.h @@ -1545,7 +1545,7 @@ extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); extern void be_detect_dump_ue(struct be_adapter *adapter); extern int be_cmd_get_die_temperature(struct be_adapter *adapter); extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); -extern int be_cmd_req_native_mode(struct be_adapter *adapter); +extern int be_cmd_check_native_mode(struct be_adapter *adapter); extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size); extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf); diff --git a/trunk/drivers/net/benet/be_main.c b/trunk/drivers/net/benet/be_main.c index c411bb1845fd..ae2d2622a18e 100644 --- a/trunk/drivers/net/benet/be_main.c +++ b/trunk/drivers/net/benet/be_main.c @@ -2511,8 +2511,6 @@ static int be_setup(struct be_adapter *adapter) int status; u8 mac[ETH_ALEN]; - be_cmd_req_native_mode(adapter); - cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_MULTICAST; @@ -2620,8 +2618,6 @@ static int be_clear(struct be_adapter *adapter) be_cmd_if_destroy(adapter, adapter->if_handle, 0); - adapter->be3_native = 0; - /* tell fw we're done with firing cmds */ be_cmd_fw_clean(adapter); return 0; @@ -3219,6 +3215,8 @@ static int be_get_config(struct be_adapter *adapter) if (status) return status; + be_cmd_check_native_mode(adapter); + if ((num_vfs && adapter->sriov_enabled) || (adapter->function_mode & 0x400) || lancer_chip(adapter) || !be_physfn(adapter)) { diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index acaebecf0ca7..f97afda941d7 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -2402,13 +2402,16 @@ bool e1000_has_link(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; bool link_active = false; - /* get_link_status is set on LSC (link status) interrupt or - * rx sequence error interrupt. get_link_status will stay - * false until the e1000_check_for_link establishes link - * for copper adapters ONLY + /* get_link_status is set on LSC (link status) interrupt or rx + * sequence error interrupt (except on intel ce4100). + * get_link_status will stay false until the + * e1000_check_for_link establishes link for copper adapters + * ONLY */ switch (hw->media_type) { case e1000_media_type_copper: + if (hw->mac_type == e1000_ce4100) + hw->get_link_status = 1; if (hw->get_link_status) { e1000_check_for_link(hw); link_active = !hw->get_link_status; diff --git a/trunk/drivers/net/netxen/netxen_nic.h b/trunk/drivers/net/netxen/netxen_nic.h index f744d291218a..77220687b92a 100644 --- a/trunk/drivers/net/netxen/netxen_nic.h +++ b/trunk/drivers/net/netxen/netxen_nic.h @@ -53,8 +53,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 76 -#define NETXEN_NIC_LINUX_VERSIONID "4.0.76" +#define _NETXEN_NIC_LINUX_SUBVERSION 75 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.75" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) @@ -1302,7 +1302,6 @@ int netxen_nic_wol_supported(struct netxen_adapter *adapter); int netxen_init_dummy_dma(struct netxen_adapter *adapter); void netxen_free_dummy_dma(struct netxen_adapter *adapter); -int netxen_check_flash_fw_compatibility(struct netxen_adapter *adapter); int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); int netxen_load_firmware(struct netxen_adapter *adapter); int netxen_need_fw_reset(struct netxen_adapter *adapter); diff --git a/trunk/drivers/net/netxen/netxen_nic_init.c b/trunk/drivers/net/netxen/netxen_nic_init.c index e8993a76a080..ca59b4f026f0 100644 --- a/trunk/drivers/net/netxen/netxen_nic_init.c +++ b/trunk/drivers/net/netxen/netxen_nic_init.c @@ -964,35 +964,6 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) return 0; } -#define NETXEN_MIN_P3_FW_SUPP NETXEN_VERSION_CODE(4, 0, 505) - -int -netxen_check_flash_fw_compatibility(struct netxen_adapter *adapter) -{ - u32 flash_fw_ver, min_fw_ver; - - if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) - return 0; - - if (netxen_rom_fast_read(adapter, - NX_FW_VERSION_OFFSET, (int *)&flash_fw_ver)) { - dev_err(&adapter->pdev->dev, "Unable to read flash fw" - "version\n"); - return -EIO; - } - - flash_fw_ver = NETXEN_DECODE_VERSION(flash_fw_ver); - min_fw_ver = NETXEN_MIN_P3_FW_SUPP; - if (flash_fw_ver >= min_fw_ver) - return 0; - - dev_info(&adapter->pdev->dev, "Flash fw[%d.%d.%d] is < min fw supported" - "[4.0.505]. Please update firmware on flash\n", - _major(flash_fw_ver), _minor(flash_fw_ver), - _build(flash_fw_ver)); - return -EINVAL; -} - static char *fw_name[] = { NX_P2_MN_ROMIMAGE_NAME, NX_P3_CT_ROMIMAGE_NAME, @@ -1100,12 +1071,10 @@ static int netxen_validate_firmware(struct netxen_adapter *adapter) { __le32 val; - __le32 flash_fw_ver; - u32 file_fw_ver, min_ver, bios; + u32 ver, min_ver, bios; struct pci_dev *pdev = adapter->pdev; const struct firmware *fw = adapter->fw; u8 fw_type = adapter->fw_type; - u32 crbinit_fix_fw; if (fw_type == NX_UNIFIED_ROMIMAGE) { if (netxen_nic_validate_unified_romimage(adapter)) @@ -1122,18 +1091,16 @@ netxen_validate_firmware(struct netxen_adapter *adapter) val = nx_get_fw_version(adapter); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) - min_ver = NETXEN_MIN_P3_FW_SUPP; + min_ver = NETXEN_VERSION_CODE(4, 0, 216); else min_ver = NETXEN_VERSION_CODE(3, 4, 216); - file_fw_ver = NETXEN_DECODE_VERSION(val); + ver = NETXEN_DECODE_VERSION(val); - if ((_major(file_fw_ver) > _NETXEN_NIC_LINUX_MAJOR) || - (file_fw_ver < min_ver)) { + if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { dev_err(&pdev->dev, "%s: firmware version %d.%d.%d unsupported\n", - fw_name[fw_type], _major(file_fw_ver), _minor(file_fw_ver), - _build(file_fw_ver)); + fw_name[fw_type], _major(ver), _minor(ver), _build(ver)); return -EINVAL; } @@ -1145,32 +1112,15 @@ netxen_validate_firmware(struct netxen_adapter *adapter) return -EINVAL; } + /* check if flashed firmware is newer */ if (netxen_rom_fast_read(adapter, - NX_FW_VERSION_OFFSET, (int *)&flash_fw_ver)) { - dev_err(&pdev->dev, "Unable to read flash fw version\n"); + NX_FW_VERSION_OFFSET, (int *)&val)) return -EIO; - } - flash_fw_ver = NETXEN_DECODE_VERSION(flash_fw_ver); - - /* New fw from file is not allowed, if fw on flash is < 4.0.554 */ - crbinit_fix_fw = NETXEN_VERSION_CODE(4, 0, 554); - if (file_fw_ver >= crbinit_fix_fw && flash_fw_ver < crbinit_fix_fw && - NX_IS_REVISION_P3(adapter->ahw.revision_id)) { - dev_err(&pdev->dev, "Incompatibility detected between driver " - "and firmware version on flash. This configuration " - "is not recommended. Please update the firmware on " - "flash immediately\n"); - return -EINVAL; - } - - /* check if flashed firmware is newer only for no-mn and P2 case*/ - if (!netxen_p3_has_mn(adapter) || - NX_IS_REVISION_P2(adapter->ahw.revision_id)) { - if (flash_fw_ver > file_fw_ver) { - dev_info(&pdev->dev, "%s: firmware is older than flash\n", + val = NETXEN_DECODE_VERSION(val); + if (val > ver) { + dev_info(&pdev->dev, "%s: firmware is older than flash\n", fw_name[fw_type]); - return -EINVAL; - } + return -EINVAL; } NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c index f574edff7fcb..30f41e62049a 100644 --- a/trunk/drivers/net/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/netxen/netxen_nic_main.c @@ -1388,10 +1388,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } - err = netxen_check_flash_fw_compatibility(adapter); - if (err) - goto err_out_iounmap; - if (adapter->portnum == 0) { val = NXRD32(adapter, NX_CRB_DEV_REF_COUNT); if (val != 0xffffffff && val != 0) { diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index 0c7321c35ad4..fbea637eb742 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -705,6 +705,14 @@ static void virtnet_netpoll(struct net_device *dev) } #endif +static void virtnet_free(struct net_device *dev) +{ + struct virtnet_info *vi = netdev_priv(dev); + + free_percpu(vi->stats); + free_netdev(dev); +} + static int virtnet_open(struct net_device *dev) { struct virtnet_info *vi = netdev_priv(dev); @@ -951,6 +959,7 @@ static int virtnet_probe(struct virtio_device *vdev) /* Set up network device as normal. */ dev->netdev_ops = &virtnet_netdev; dev->features = NETIF_F_HIGHDMA; + dev->destructor = virtnet_free; SET_ETHTOOL_OPS(dev, &virtnet_ethtool_ops); SET_NETDEV_DEV(dev, &vdev->dev); @@ -1113,7 +1122,6 @@ static void __devexit virtnet_remove(struct virtio_device *vdev) while (vi->pages) __free_pages(get_a_page(vi, GFP_KERNEL), 0); - free_percpu(vi->stats); free_netdev(vi->dev); } diff --git a/trunk/include/linux/random.h b/trunk/include/linux/random.h index ce29a040c8dc..fb7ab9de5f36 100644 --- a/trunk/include/linux/random.h +++ b/trunk/include/linux/random.h @@ -58,7 +58,6 @@ extern void get_random_bytes(void *buf, int nbytes); void generate_random_uuid(unsigned char uuid_out[16]); extern __u32 secure_ip_id(__be32 daddr); -extern __u32 secure_ipv6_id(const __be32 daddr[4]); extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); extern u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, __be16 dport); diff --git a/trunk/include/net/inetpeer.h b/trunk/include/net/inetpeer.h index 4233e6f9841d..39d123081e7e 100644 --- a/trunk/include/net/inetpeer.h +++ b/trunk/include/net/inetpeer.h @@ -71,7 +71,7 @@ static inline bool inet_metrics_new(const struct inet_peer *p) } /* can be called with or without local BH being disabled */ -struct inet_peer *inet_getpeer(const struct inetpeer_addr *daddr, int create); +struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create); static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create) { @@ -106,18 +106,11 @@ static inline void inet_peer_refcheck(const struct inet_peer *p) /* can be called with or without local BH being disabled */ -static inline int inet_getid(struct inet_peer *p, int more) +static inline __u16 inet_getid(struct inet_peer *p, int more) { - int old, new; more++; inet_peer_refcheck(p); - do { - old = atomic_read(&p->ip_id_count); - new = old + more; - if (!new) - new = 1; - } while (atomic_cmpxchg(&p->ip_id_count, old, new) != old); - return new; + return atomic_add_return(more, &p->ip_id_count) - more; } #endif /* _NET_INETPEER_H */ diff --git a/trunk/include/net/ipv6.h b/trunk/include/net/ipv6.h index 3b5ac1fbff39..c033ed00df7d 100644 --- a/trunk/include/net/ipv6.h +++ b/trunk/include/net/ipv6.h @@ -463,7 +463,17 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); } -extern void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt); +static __inline__ void ipv6_select_ident(struct frag_hdr *fhdr) +{ + static u32 ipv6_fragmentation_id = 1; + static DEFINE_SPINLOCK(ip6_id_lock); + + spin_lock_bh(&ip6_id_lock); + fhdr->identification = htonl(ipv6_fragmentation_id); + if (++ipv6_fragmentation_id == 0) + ipv6_fragmentation_id = 1; + spin_unlock_bh(&ip6_id_lock); +} /* * Prototypes exported by ipv6 diff --git a/trunk/net/ipv4/inetpeer.c b/trunk/net/ipv4/inetpeer.c index e38213817d0a..90c5f0d1bcf3 100644 --- a/trunk/net/ipv4/inetpeer.c +++ b/trunk/net/ipv4/inetpeer.c @@ -391,7 +391,7 @@ static int inet_peer_gc(struct inet_peer_base *base, return cnt; } -struct inet_peer *inet_getpeer(const struct inetpeer_addr *daddr, int create) +struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create) { struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; struct inet_peer_base *base = family_to_base(daddr->family); @@ -436,10 +436,7 @@ struct inet_peer *inet_getpeer(const struct inetpeer_addr *daddr, int create) p->daddr = *daddr; atomic_set(&p->refcnt, 1); atomic_set(&p->rid, 0); - atomic_set(&p->ip_id_count, - (daddr->family == AF_INET) ? - secure_ip_id(daddr->addr.a4) : - secure_ipv6_id(daddr->addr.a6)); + atomic_set(&p->ip_id_count, secure_ip_id(daddr->addr.a4)); p->tcp_ts_stamp = 0; p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; p->rate_tokens = 0; diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index ccaaa851ab42..be27e609a98b 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -734,7 +734,7 @@ static inline int ip_ufo_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), void *from, int length, int hh_len, int fragheaderlen, - int transhdrlen, int maxfraglen, unsigned int flags) + int transhdrlen, int mtu, unsigned int flags) { struct sk_buff *skb; int err; @@ -767,7 +767,7 @@ static inline int ip_ufo_append_data(struct sock *sk, skb->csum = 0; /* specify the length of each IP datagram fragment */ - skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen; + skb_shinfo(skb)->gso_size = mtu - fragheaderlen; skb_shinfo(skb)->gso_type = SKB_GSO_UDP; __skb_queue_tail(queue, skb); } @@ -831,7 +831,7 @@ static int __ip_append_data(struct sock *sk, (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) { err = ip_ufo_append_data(sk, queue, getfrag, from, length, hh_len, fragheaderlen, transhdrlen, - maxfraglen, flags); + mtu, flags); if (err) goto error; return 0; diff --git a/trunk/net/ipv6/ip6_output.c b/trunk/net/ipv6/ip6_output.c index 32e5339db0c8..8db0e4875ad8 100644 --- a/trunk/net/ipv6/ip6_output.c +++ b/trunk/net/ipv6/ip6_output.c @@ -596,31 +596,6 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) return offset; } -void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) -{ - static atomic_t ipv6_fragmentation_id; - int old, new; - - if (rt) { - struct inet_peer *peer; - - if (!rt->rt6i_peer) - rt6_bind_peer(rt, 1); - peer = rt->rt6i_peer; - if (peer) { - fhdr->identification = htonl(inet_getid(peer, 0)); - return; - } - } - do { - old = atomic_read(&ipv6_fragmentation_id); - new = old + 1; - if (!new) - new = 1; - } while (atomic_cmpxchg(&ipv6_fragmentation_id, old, new) != old); - fhdr->identification = htonl(new); -} - int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) { struct sk_buff *frag; @@ -705,7 +680,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) skb_reset_network_header(skb); memcpy(skb_network_header(skb), tmp_hdr, hlen); - ipv6_select_ident(fh, rt); + ipv6_select_ident(fh); fh->nexthdr = nexthdr; fh->reserved = 0; fh->frag_off = htons(IP6_MF); @@ -851,7 +826,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) fh->nexthdr = nexthdr; fh->reserved = 0; if (!frag_id) { - ipv6_select_ident(fh, rt); + ipv6_select_ident(fh); frag_id = fh->identification; } else fh->identification = frag_id; @@ -1101,8 +1076,7 @@ static inline int ip6_ufo_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), void *from, int length, int hh_len, int fragheaderlen, - int transhdrlen, int mtu,unsigned int flags, - struct rt6_info *rt) + int transhdrlen, int mtu,unsigned int flags) { struct sk_buff *skb; @@ -1146,7 +1120,7 @@ static inline int ip6_ufo_append_data(struct sock *sk, skb_shinfo(skb)->gso_size = (mtu - fragheaderlen - sizeof(struct frag_hdr)) & ~7; skb_shinfo(skb)->gso_type = SKB_GSO_UDP; - ipv6_select_ident(&fhdr, rt); + ipv6_select_ident(&fhdr); skb_shinfo(skb)->ip6_frag_id = fhdr.identification; __skb_queue_tail(&sk->sk_write_queue, skb); @@ -1312,7 +1286,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, err = ip6_ufo_append_data(sk, getfrag, from, length, hh_len, fragheaderlen, - transhdrlen, mtu, flags, rt); + transhdrlen, mtu, flags); if (err) goto error; return 0; diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index e8987da06667..ddef80f568b0 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -72,8 +72,7 @@ #define RT6_TRACE(x...) do { ; } while (0) #endif -static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, - const struct in6_addr *dest); +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 unsigned int ip6_default_advmss(const struct dst_entry *dst); static unsigned int ip6_default_mtu(const struct dst_entry *dst); @@ -691,8 +690,7 @@ int ip6_ins_rt(struct rt6_info *rt) return __ip6_ins_rt(rt, &info); } -static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort, - const struct in6_addr *daddr, +static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_addr *daddr, const struct in6_addr *saddr) { struct rt6_info *rt; @@ -701,7 +699,7 @@ static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort, * Clone the route. */ - rt = ip6_rt_copy(ort, daddr); + rt = ip6_rt_copy(ort); if (rt) { struct neighbour *neigh; @@ -709,11 +707,12 @@ static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort, if (!(rt->rt6i_flags&RTF_GATEWAY)) { if (rt->rt6i_dst.plen != 128 && - ipv6_addr_equal(&ort->rt6i_dst.addr, daddr)) + ipv6_addr_equal(&rt->rt6i_dst.addr, daddr)) rt->rt6i_flags |= RTF_ANYCAST; ipv6_addr_copy(&rt->rt6i_gateway, daddr); } + ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); rt->rt6i_dst.plen = 128; rt->rt6i_flags |= RTF_CACHE; rt->dst.flags |= DST_HOST; @@ -760,12 +759,11 @@ static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort, return rt; } -static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, - const struct in6_addr *daddr) +static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, const struct in6_addr *daddr) { - struct rt6_info *rt = ip6_rt_copy(ort, daddr); - + struct rt6_info *rt = ip6_rt_copy(ort); if (rt) { + ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); rt->rt6i_dst.plen = 128; rt->rt6i_flags |= RTF_CACHE; rt->dst.flags |= DST_HOST; @@ -909,10 +907,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori new->input = dst_discard; new->output = dst_discard; - if (dst_metrics_read_only(&ort->dst)) - new->_metrics = ort->dst._metrics; - else - dst_copy_metrics(new, &ort->dst); + dst_copy_metrics(new, &ort->dst); rt->rt6i_idev = ort->rt6i_idev; if (rt->rt6i_idev) in6_dev_hold(rt->rt6i_idev); @@ -1072,7 +1067,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, rt->rt6i_idev = idev; dst_set_neighbour(&rt->dst, neigh); atomic_set(&rt->dst.__refcnt, 1); - ipv6_addr_copy(&rt->rt6i_dst.addr, addr); dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); rt->dst.output = ip6_output; @@ -1590,7 +1584,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, if (neigh == dst_get_neighbour(&rt->dst)) goto out; - nrt = ip6_rt_copy(rt, dest); + nrt = ip6_rt_copy(rt); if (nrt == NULL) goto out; @@ -1598,6 +1592,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, if (on_link) nrt->rt6i_flags &= ~RTF_GATEWAY; + ipv6_addr_copy(&nrt->rt6i_dst.addr, dest); nrt->rt6i_dst.plen = 128; nrt->dst.flags |= DST_HOST; @@ -1735,8 +1730,7 @@ void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *sad * Misc support functions */ -static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, - const struct in6_addr *dest) +static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) { struct net *net = dev_net(ort->rt6i_dev); struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, @@ -1746,8 +1740,6 @@ static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, rt->dst.input = ort->dst.input; rt->dst.output = ort->dst.output; - ipv6_addr_copy(&rt->rt6i_dst.addr, dest); - rt->rt6i_dst.plen = ort->rt6i_dst.plen; dst_copy_metrics(&rt->dst, &ort->dst); rt->dst.error = ort->dst.error; rt->rt6i_idev = ort->rt6i_idev; @@ -1760,6 +1752,7 @@ static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; rt->rt6i_metric = 0; + memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key)); #ifdef CONFIG_IPV6_SUBTREES memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key)); #endif diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index 29213b51c499..328985c40883 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -1359,7 +1359,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, u32 features) fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen); fptr->nexthdr = nexthdr; fptr->reserved = 0; - ipv6_select_ident(fptr, (struct rt6_info *)skb_dst(skb)); + ipv6_select_ident(fptr); /* Fragment the skb. ipv6 header and the remaining fields of the * fragment header are updated in ipv6_gso_segment()