aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/proc.txt5
-rw-r--r--Documentation/networking/xfrm_proc.txt8
-rw-r--r--MAINTAINERS6
-rw-r--r--drivers/net/bnx2.c213
-rw-r--r--drivers/net/bnx2.h39
-rw-r--r--drivers/net/bnx2_fw.h1499
-rw-r--r--drivers/net/bnx2_fw2.h464
-rw-r--r--drivers/net/macvlan.c2
-rw-r--r--drivers/net/usb/asix.c3
-rw-r--r--drivers/net/usb/cdc_ether.c13
-rw-r--r--drivers/net/usb/cdc_subset.c3
-rw-r--r--drivers/net/usb/dm9601.c3
-rw-r--r--drivers/net/usb/gl620a.c3
-rw-r--r--drivers/net/usb/mcs7830.c3
-rw-r--r--drivers/net/usb/net1080.c3
-rw-r--r--drivers/net/usb/plusb.c3
-rw-r--r--drivers/net/usb/rndis_host.c303
-rw-r--r--drivers/net/usb/usbnet.c6
-rw-r--r--drivers/net/usb/zaurus.c3
-rw-r--r--drivers/net/wireless/Kconfig28
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/ath5k/base.c10
-rw-r--r--drivers/net/wireless/ath5k/debug.c124
-rw-r--r--drivers/net/wireless/ath5k/debug.h18
-rw-r--r--drivers/net/wireless/b43/dma.c30
-rw-r--r--drivers/net/wireless/b43/main.c19
-rw-r--r--drivers/net/wireless/b43/xmit.c23
-rw-r--r--drivers/net/wireless/b43/xmit.h10
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h31
-rw-r--r--drivers/net/wireless/b43legacy/main.c133
-rw-r--r--drivers/net/wireless/b43legacy/phy.c14
-rw-r--r--drivers/net/wireless/b43legacy/pio.c6
-rw-r--r--drivers/net/wireless/b43legacy/radio.c16
-rw-r--r--drivers/net/wireless/hostap/hostap_80211.h5
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c86
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c84
-rw-r--r--drivers/net/wireless/libertas/assoc.c6
-rw-r--r--drivers/net/wireless/libertas/dev.h2
-rw-r--r--drivers/net/wireless/libertas/if_cs.c6
-rw-r--r--drivers/net/wireless/rndis_wlan.c2757
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c3
-rw-r--r--drivers/net/wireless/rtl8180_dev.c1
-rw-r--r--include/asm-alpha/socket.h2
-rw-r--r--include/asm-arm/socket.h2
-rw-r--r--include/asm-avr32/socket.h2
-rw-r--r--include/asm-blackfin/socket.h3
-rw-r--r--include/asm-cris/socket.h2
-rw-r--r--include/asm-frv/socket.h2
-rw-r--r--include/asm-h8300/socket.h2
-rw-r--r--include/asm-ia64/socket.h2
-rw-r--r--include/asm-m32r/socket.h2
-rw-r--r--include/asm-m68k/socket.h2
-rw-r--r--include/asm-mips/socket.h2
-rw-r--r--include/asm-parisc/socket.h2
-rw-r--r--include/asm-powerpc/socket.h2
-rw-r--r--include/asm-s390/socket.h2
-rw-r--r--include/asm-sh/socket.h2
-rw-r--r--include/asm-sparc/socket.h2
-rw-r--r--include/asm-sparc64/socket.h1
-rw-r--r--include/asm-v850/socket.h2
-rw-r--r--include/asm-x86/socket.h2
-rw-r--r--include/asm-xtensa/socket.h2
-rw-r--r--include/linux/inetdevice.h2
-rw-r--r--include/linux/input.h2
-rw-r--r--include/linux/ipv6.h12
-rw-r--r--include/linux/netdevice.h4
-rw-r--r--include/linux/netfilter/nf_conntrack_pptp.h2
-rw-r--r--include/linux/netfilter/nf_conntrack_sip.h6
-rw-r--r--include/linux/netfilter/x_tables.h28
-rw-r--r--include/linux/netfilter/xt_conntrack.h30
-rw-r--r--include/linux/netfilter/xt_hashlimit.h37
-rw-r--r--include/linux/netfilter/xt_owner.h4
-rw-r--r--include/linux/netfilter_arp/arp_tables.h5
-rw-r--r--include/linux/netfilter_ipv4/ip_tables.h5
-rw-r--r--include/linux/netfilter_ipv6/ip6_tables.h5
-rw-r--r--include/linux/netlink.h2
-rw-r--r--include/linux/pfkeyv2.h6
-rw-r--r--include/linux/pkt_cls.h50
-rw-r--r--include/linux/pkt_sched.h5
-rw-r--r--include/linux/rfkill.h2
-rw-r--r--include/linux/skbuff.h3
-rw-r--r--include/linux/snmp.h3
-rw-r--r--include/linux/sysctl.h4
-rw-r--r--include/linux/types.h2
-rw-r--r--include/linux/usb/rndis_host.h274
-rw-r--r--include/linux/usb/usbnet.h (renamed from drivers/net/usb/usbnet.h)12
-rw-r--r--include/linux/xfrm.h8
-rw-r--r--include/net/arp.h8
-rw-r--r--include/net/esp.h54
-rw-r--r--include/net/inet6_hashtables.h17
-rw-r--r--include/net/inet_hashtables.h55
-rw-r--r--include/net/ip_fib.h4
-rw-r--r--include/net/net_namespace.h4
-rw-r--r--include/net/netfilter/nf_conntrack.h15
-rw-r--r--include/net/netfilter/nf_conntrack_core.h6
-rw-r--r--include/net/netfilter/nf_conntrack_expect.h2
-rw-r--r--include/net/netfilter/nf_conntrack_helper.h4
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h4
-rw-r--r--include/net/netfilter/nf_conntrack_l4proto.h25
-rw-r--r--include/net/netfilter/nf_conntrack_tuple.h17
-rw-r--r--include/net/netfilter/nf_log.h2
-rw-r--r--include/net/netns/ipv4.h6
-rw-r--r--include/net/netns/ipv6.h5
-rw-r--r--include/net/netns/x_tables.h10
-rw-r--r--include/net/pkt_cls.h6
-rw-r--r--include/net/raw.h5
-rw-r--r--include/net/route.h3
-rw-r--r--include/net/sock.h2
-rw-r--r--include/net/xfrm.h16
-rw-r--r--kernel/audit.c10
-rw-r--r--net/802/tr.c2
-rw-r--r--net/8021q/vlan_dev.c7
-rw-r--r--net/9p/conv.c5
-rw-r--r--net/ax25/af_ax25.c13
-rw-r--r--net/bluetooth/hci_sysfs.c52
-rw-r--r--net/bridge/br_netfilter.c4
-rw-r--r--net/bridge/netfilter/ebt_802_3.c10
-rw-r--r--net/bridge/netfilter/ebt_among.c27
-rw-r--r--net/bridge/netfilter/ebt_arp.c17
-rw-r--r--net/bridge/netfilter/ebt_arpreply.c17
-rw-r--r--net/bridge/netfilter/ebt_dnat.c8
-rw-r--r--net/bridge/netfilter/ebt_ip.c14
-rw-r--r--net/bridge/netfilter/ebt_limit.c6
-rw-r--r--net/bridge/netfilter/ebt_log.c19
-rw-r--r--net/bridge/netfilter/ebt_mark.c8
-rw-r--r--net/bridge/netfilter/ebt_mark_m.c8
-rw-r--r--net/bridge/netfilter/ebt_pkttype.c8
-rw-r--r--net/bridge/netfilter/ebt_redirect.c8
-rw-r--r--net/bridge/netfilter/ebt_snat.c11
-rw-r--r--net/bridge/netfilter/ebt_stp.c28
-rw-r--r--net/bridge/netfilter/ebt_ulog.c9
-rw-r--r--net/bridge/netfilter/ebt_vlan.c12
-rw-r--r--net/core/dev.c96
-rw-r--r--net/core/dev_mcast.c39
-rw-r--r--net/core/pktgen.c3
-rw-r--r--net/core/sock.c11
-rw-r--r--net/dccp/ipv4.c6
-rw-r--r--net/dccp/ipv6.c8
-rw-r--r--net/ipv4/Kconfig1
-rw-r--r--net/ipv4/ah4.c2
-rw-r--r--net/ipv4/arp.c9
-rw-r--r--net/ipv4/devinet.c37
-rw-r--r--net/ipv4/esp4.c554
-rw-r--r--net/ipv4/fib_frontend.c14
-rw-r--r--net/ipv4/fib_hash.c47
-rw-r--r--net/ipv4/fib_semantics.c116
-rw-r--r--net/ipv4/fib_trie.c104
-rw-r--r--net/ipv4/inet_connection_sock.c8
-rw-r--r--net/ipv4/inet_diag.c15
-rw-r--r--net/ipv4/inet_hashtables.c69
-rw-r--r--net/ipv4/ip_output.c7
-rw-r--r--net/ipv4/ipcomp.c7
-rw-r--r--net/ipv4/netfilter/arp_tables.c102
-rw-r--r--net/ipv4/netfilter/arptable_filter.c31
-rw-r--r--net/ipv4/netfilter/ip_queue.c18
-rw-r--r--net/ipv4/netfilter/ip_tables.c112
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c7
-rw-r--r--net/ipv4/netfilter/ipt_recent.c6
-rw-r--r--net/ipv4/netfilter/iptable_filter.c33
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c33
-rw-r--r--net/ipv4/netfilter/iptable_raw.c33
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c14
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c40
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c22
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c42
-rw-r--r--net/ipv4/netfilter/nf_nat_h323.c5
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c3
-rw-r--r--net/ipv4/netfilter/nf_nat_pptp.c10
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_gre.c16
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_icmp.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_tcp.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_udp.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c16
-rw-r--r--net/ipv4/netfilter/nf_nat_sip.c4
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_tftp.c2
-rw-r--r--net/ipv4/raw.c42
-rw-r--r--net/ipv4/route.c211
-rw-r--r--net/ipv4/sysctl_net_ipv4.c2
-rw-r--r--net/ipv4/tcp_input.c2
-rw-r--r--net/ipv4/tcp_ipv4.c15
-rw-r--r--net/ipv4/tcp_output.c1
-rw-r--r--net/ipv4/udp.c25
-rw-r--r--net/ipv4/xfrm4_policy.c1
-rw-r--r--net/ipv4/xfrm4_tunnel.c4
-rw-r--r--net/ipv6/Kconfig1
-rw-r--r--net/ipv6/ah6.c2
-rw-r--r--net/ipv6/esp6.c515
-rw-r--r--net/ipv6/inet6_hashtables.c135
-rw-r--r--net/ipv6/ip6_output.c6
-rw-r--r--net/ipv6/ipcomp6.c7
-rw-r--r--net/ipv6/mip6.c4
-rw-r--r--net/ipv6/netfilter/ip6_queue.c18
-rw-r--r--net/ipv6/netfilter/ip6_tables.c113
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c33
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c33
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c31
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c7
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c22
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c16
-rw-r--r--net/ipv6/raw.c5
-rw-r--r--net/ipv6/route.c5
-rw-r--r--net/ipv6/tcp_ipv6.c19
-rw-r--r--net/ipv6/udp.c10
-rw-r--r--net/ipv6/xfrm6_policy.c1
-rw-r--r--net/ipv6/xfrm6_tunnel.c2
-rw-r--r--net/mac80211/rx.c48
-rw-r--r--net/netfilter/nf_conntrack_core.c234
-rw-r--r--net/netfilter/nf_conntrack_expect.c53
-rw-r--r--net/netfilter/nf_conntrack_h323_asn1.c156
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c23
-rw-r--r--net/netfilter/nf_conntrack_h323_types.c346
-rw-r--r--net/netfilter/nf_conntrack_helper.c60
-rw-r--r--net/netfilter/nf_conntrack_irc.c2
-rw-r--r--net/netfilter/nf_conntrack_netlink.c68
-rw-r--r--net/netfilter/nf_conntrack_pptp.c14
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c6
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c6
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c6
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c192
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c19
-rw-r--r--net/netfilter/nf_conntrack_proto_udplite.c19
-rw-r--r--net/netfilter/nf_conntrack_sane.c9
-rw-r--r--net/netfilter/nf_conntrack_sip.c29
-rw-r--r--net/netfilter/nf_conntrack_standalone.c66
-rw-r--r--net/netfilter/nf_conntrack_tftp.c5
-rw-r--r--net/netfilter/nf_log.c2
-rw-r--r--net/netfilter/nfnetlink_log.c4
-rw-r--r--net/netfilter/nfnetlink_queue.c6
-rw-r--r--net/netfilter/x_tables.c313
-rw-r--r--net/netfilter/xt_TCPMSS.c62
-rw-r--r--net/netfilter/xt_connlimit.c6
-rw-r--r--net/netfilter/xt_conntrack.c50
-rw-r--r--net/netfilter/xt_hashlimit.c326
-rw-r--r--net/netfilter/xt_iprange.c2
-rw-r--r--net/netfilter/xt_owner.c14
-rw-r--r--net/netlink/af_netlink.c52
-rw-r--r--net/rfkill/rfkill-input.c9
-rw-r--r--net/rfkill/rfkill.c3
-rw-r--r--net/rxrpc/ar-call.c2
-rw-r--r--net/rxrpc/ar-internal.h6
-rw-r--r--net/rxrpc/ar-proc.c6
-rw-r--r--net/sched/Kconfig13
-rw-r--r--net/sched/Makefile1
-rw-r--r--net/sched/cls_api.c6
-rw-r--r--net/sched/cls_basic.c2
-rw-r--r--net/sched/cls_flow.c660
-rw-r--r--net/sched/cls_fw.c2
-rw-r--r--net/sched/cls_route.c2
-rw-r--r--net/sched/cls_tcindex.c2
-rw-r--r--net/sched/cls_u32.c2
-rw-r--r--net/sched/sch_ingress.c79
-rw-r--r--net/sched/sch_sfq.c134
-rw-r--r--net/sched/sch_teql.c2
-rw-r--r--net/sctp/sm_make_chunk.c2
-rw-r--r--net/x25/af_x25.c2
-rw-r--r--net/xfrm/xfrm_algo.c144
-rw-r--r--net/xfrm/xfrm_input.c5
-rw-r--r--net/xfrm/xfrm_output.c1
-rw-r--r--net/xfrm/xfrm_proc.c3
-rw-r--r--net/xfrm/xfrm_state.c18
-rw-r--r--net/xfrm/xfrm_user.c71
-rw-r--r--security/selinux/ss/services.c1
271 files changed, 9495 insertions, 4036 deletions
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 4413a2d4646..11fe51c036b 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -1919,11 +1919,6 @@ max_size
Maximum size of the routing cache. Old entries will be purged once the cache
reached has this size.
-max_delay, min_delay
---------------------
-
-Delays for flushing the routing cache.
-
redirect_load, redirect_number
------------------------------
diff --git a/Documentation/networking/xfrm_proc.txt b/Documentation/networking/xfrm_proc.txt
index 53c1a58b02f..d0d8bafa901 100644
--- a/Documentation/networking/xfrm_proc.txt
+++ b/Documentation/networking/xfrm_proc.txt
@@ -26,8 +26,9 @@ XfrmInStateProtoError:
e.g. SA key is wrong
XfrmInStateModeError:
Transformation mode specific error
-XfrmInSeqOutOfWindow:
- Sequence out of window
+XfrmInStateSeqError:
+ Sequence error
+ i.e. Sequence number is out of window
XfrmInStateExpired:
State is expired
XfrmInStateMismatch:
@@ -60,6 +61,9 @@ XfrmOutStateProtoError:
Transformation protocol specific error
XfrmOutStateModeError:
Transformation mode specific error
+XfrmOutStateSeqError:
+ Sequence error
+ i.e. Sequence number overflow
XfrmOutStateExpired:
State is expired
XfrmOutPolBlock:
diff --git a/MAINTAINERS b/MAINTAINERS
index 093cf04e9ca..91082e60d28 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4085,6 +4085,12 @@ L: video4linux-list@redhat.com
W: http://www.linux-projects.org
S: Maintained
+USB WIRELESS RNDIS DRIVER (rndis_wlan)
+P: Jussi Kivilinna
+M: jussi.kivilinna@mbnet.fi
+L: linux-wireless@vger.kernel.org
+S: Maintained
+
USB ZC0301 DRIVER
P: Luca Risolia
M: luca.risolia@studio.unibo.it
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 34aebc6e758..8b552c6dd2e 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -56,8 +56,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.7.2"
-#define DRV_MODULE_RELDATE "January 21, 2008"
+#define DRV_MODULE_VERSION "1.7.3"
+#define DRV_MODULE_RELDATE "January 29, 2008"
#define RUN_AT(x) (jiffies + (x))
@@ -266,6 +266,18 @@ bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val)
}
static void
+bnx2_shmem_wr(struct bnx2 *bp, u32 offset, u32 val)
+{
+ bnx2_reg_wr_ind(bp, bp->shmem_base + offset, val);
+}
+
+static u32
+bnx2_shmem_rd(struct bnx2 *bp, u32 offset)
+{
+ return (bnx2_reg_rd_ind(bp, bp->shmem_base + offset));
+}
+
+static void
bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
{
offset += cid_addr;
@@ -685,7 +697,7 @@ bnx2_report_fw_link(struct bnx2 *bp)
else
fw_link_status = BNX2_LINK_STATUS_LINK_DOWN;
- REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status);
+ bnx2_shmem_wr(bp, BNX2_LINK_STATUS, fw_link_status);
}
static char *
@@ -980,6 +992,42 @@ bnx2_copper_linkup(struct bnx2 *bp)
return 0;
}
+static void
+bnx2_init_rx_context0(struct bnx2 *bp)
+{
+ u32 val, rx_cid_addr = GET_CID_ADDR(RX_CID);
+
+ val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
+ val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
+ val |= 0x02 << 8;
+
+ if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ u32 lo_water, hi_water;
+
+ if (bp->flow_ctrl & FLOW_CTRL_TX)
+ lo_water = BNX2_L2CTX_LO_WATER_MARK_DEFAULT;
+ else
+ lo_water = BNX2_L2CTX_LO_WATER_MARK_DIS;
+ if (lo_water >= bp->rx_ring_size)
+ lo_water = 0;
+
+ hi_water = bp->rx_ring_size / 4;
+
+ if (hi_water <= lo_water)
+ lo_water = 0;
+
+ hi_water /= BNX2_L2CTX_HI_WATER_MARK_SCALE;
+ lo_water /= BNX2_L2CTX_LO_WATER_MARK_SCALE;
+
+ if (hi_water > 0xf)
+ hi_water = 0xf;
+ else if (hi_water == 0)
+ lo_water = 0;
+ val |= lo_water | (hi_water << BNX2_L2CTX_HI_WATER_MARK_SHIFT);
+ }
+ bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val);
+}
+
static int
bnx2_set_mac_link(struct bnx2 *bp)
{
@@ -1044,6 +1092,9 @@ bnx2_set_mac_link(struct bnx2 *bp)
/* Acknowledge the interrupt. */
REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE);
+ if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ bnx2_init_rx_context0(bp);
+
return 0;
}
@@ -1378,14 +1429,14 @@ bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
if (pause_adv & (ADVERTISE_1000XPAUSE | ADVERTISE_PAUSE_CAP))
speed_arg |= BNX2_NETLINK_SET_LINK_FC_SYM_PAUSE;
- if (pause_adv & (ADVERTISE_1000XPSE_ASYM | ADVERTISE_1000XPSE_ASYM))
+ if (pause_adv & (ADVERTISE_1000XPSE_ASYM | ADVERTISE_PAUSE_ASYM))
speed_arg |= BNX2_NETLINK_SET_LINK_FC_ASYM_PAUSE;
if (port == PORT_TP)
speed_arg |= BNX2_NETLINK_SET_LINK_PHY_APP_REMOTE |
BNX2_NETLINK_SET_LINK_ETH_AT_WIRESPEED;
- REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB_ARG0, speed_arg);
+ bnx2_shmem_wr(bp, BNX2_DRV_MB_ARG0, speed_arg);
spin_unlock_bh(&bp->phy_lock);
bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_CMD_SET_LINK, 0);
@@ -1530,9 +1581,9 @@ bnx2_set_default_remote_link(struct bnx2 *bp)
u32 link;
if (bp->phy_port == PORT_TP)
- link = REG_RD_IND(bp, bp->shmem_base + BNX2_RPHY_COPPER_LINK);
+ link = bnx2_shmem_rd(bp, BNX2_RPHY_COPPER_LINK);
else
- link = REG_RD_IND(bp, bp->shmem_base + BNX2_RPHY_SERDES_LINK);
+ link = bnx2_shmem_rd(bp, BNX2_RPHY_SERDES_LINK);
if (link & BNX2_NETLINK_SET_LINK_ENABLE_AUTONEG) {
bp->req_line_speed = 0;
@@ -1584,7 +1635,7 @@ bnx2_set_default_link(struct bnx2 *bp)
bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
- reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
+ reg = bnx2_shmem_rd(bp, BNX2_PORT_HW_CFG_CONFIG);
reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
bp->autoneg = 0;
@@ -1616,7 +1667,7 @@ bnx2_remote_phy_event(struct bnx2 *bp)
u8 link_up = bp->link_up;
u8 old_port;
- msg = REG_RD_IND(bp, bp->shmem_base + BNX2_LINK_STATUS);
+ msg = bnx2_shmem_rd(bp, BNX2_LINK_STATUS);
if (msg & BNX2_LINK_STATUS_HEART_BEAT_EXPIRED)
bnx2_send_heart_beat(bp);
@@ -1693,7 +1744,7 @@ bnx2_set_remote_link(struct bnx2 *bp)
{
u32 evt_code;
- evt_code = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_EVT_CODE_MB);
+ evt_code = bnx2_shmem_rd(bp, BNX2_FW_EVT_CODE_MB);
switch (evt_code) {
case BNX2_FW_EVT_CODE_LINK_EVENT:
bnx2_remote_phy_event(bp);
@@ -1905,14 +1956,13 @@ bnx2_init_5708s_phy(struct bnx2 *bp)
bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
}
- val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) &
+ val = bnx2_shmem_rd(bp, BNX2_PORT_HW_CFG_CONFIG) &
BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK;
if (val) {
u32 is_backplane;
- is_backplane = REG_RD_IND(bp, bp->shmem_base +
- BNX2_SHARED_HW_CFG_CONFIG);
+ is_backplane = bnx2_shmem_rd(bp, BNX2_SHARED_HW_CFG_CONFIG);
if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) {
bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
BCM5708S_BLK_ADDR_TX_MISC);
@@ -2111,13 +2161,13 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
bp->fw_wr_seq++;
msg_data |= bp->fw_wr_seq;
- REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
+ bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data);
/* wait for an acknowledgement. */
for (i = 0; i < (FW_ACK_TIME_OUT_MS / 10); i++) {
msleep(10);
- val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB);
+ val = bnx2_shmem_rd(bp, BNX2_FW_MB);
if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ))
break;
@@ -2134,7 +2184,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
msg_data &= ~BNX2_DRV_MSG_CODE;
msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
- REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
+ bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data);
return -EBUSY;
}
@@ -2226,7 +2276,7 @@ bnx2_init_context(struct bnx2 *bp)
/* Zero out the context. */
for (offset = 0; offset < PHY_CTX_SIZE; offset += 4)
- CTX_WR(bp, vcid_addr, offset, 0);
+ bnx2_ctx_wr(bp, vcid_addr, offset, 0);
}
}
}
@@ -2251,11 +2301,12 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp)
good_mbuf_cnt = 0;
/* Allocate a bunch of mbufs and save the good ones in an array. */
- val = REG_RD_IND(bp, BNX2_RBUF_STATUS1);
+ val = bnx2_reg_rd_ind(bp, BNX2_RBUF_STATUS1);
while (val & BNX2_RBUF_STATUS1_FREE_COUNT) {
- REG_WR_IND(bp, BNX2_RBUF_COMMAND, BNX2_RBUF_COMMAND_ALLOC_REQ);
+ bnx2_reg_wr_ind(bp, BNX2_RBUF_COMMAND,
+ BNX2_RBUF_COMMAND_ALLOC_REQ);
- val = REG_RD_IND(bp, BNX2_RBUF_FW_BUF_ALLOC);
+ val = bnx2_reg_rd_ind(bp, BNX2_RBUF_FW_BUF_ALLOC);
val &= BNX2_RBUF_FW_BUF_ALLOC_VALUE;
@@ -2265,7 +2316,7 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp)
good_mbuf_cnt++;
}
- val = REG_RD_IND(bp, BNX2_RBUF_STATUS1);
+ val = bnx2_reg_rd_ind(bp, BNX2_RBUF_STATUS1);
}
/* Free the good ones back to the mbuf pool thus discarding
@@ -2276,7 +2327,7 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp)
val = good_mbuf[good_mbuf_cnt];
val = (val << 9) | val | 1;
- REG_WR_IND(bp, BNX2_RBUF_FW_BUF_FREE, val);
+ bnx2_reg_wr_ind(bp, BNX2_RBUF_FW_BUF_FREE, val);
}
kfree(good_mbuf);
return 0;
@@ -3151,10 +3202,10 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
int rc;
/* Halt the CPU. */
- val = REG_RD_IND(bp, cpu_reg->mode);
+ val = bnx2_reg_rd_ind(bp, cpu_reg->mode);
val |= cpu_reg->mode_value_halt;
- REG_WR_IND(bp, cpu_reg->mode, val);
- REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear);
+ bnx2_reg_wr_ind(bp, cpu_reg->mode, val);
+ bnx2_reg_wr_ind(bp, cpu_reg->state, cpu_reg->state_value_clear);
/* Load the Text area. */
offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
@@ -3167,7 +3218,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
return rc;
for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
- REG_WR_IND(bp, offset, le32_to_cpu(fw->text[j]));
+ bnx2_reg_wr_ind(bp, offset, le32_to_cpu(fw->text[j]));
}
}
@@ -3177,7 +3228,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
int j;
for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
- REG_WR_IND(bp, offset, fw->data[j]);
+ bnx2_reg_wr_ind(bp, offset, fw->data[j]);
}
}
@@ -3187,7 +3238,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
int j;
for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
- REG_WR_IND(bp, offset, 0);
+ bnx2_reg_wr_ind(bp, offset, 0);
}
}
@@ -3197,7 +3248,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
int j;
for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
- REG_WR_IND(bp, offset, 0);
+ bnx2_reg_wr_ind(bp, offset, 0);
}
}
@@ -3208,19 +3259,19 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
int j;
for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
- REG_WR_IND(bp, offset, fw->rodata[j]);
+ bnx2_reg_wr_ind(bp, offset, fw->rodata[j]);
}
}
/* Clear the pre-fetch instruction. */
- REG_WR_IND(bp, cpu_reg->inst, 0);
- REG_WR_IND(bp, cpu_reg->pc, fw->start_addr);
+ bnx2_reg_wr_ind(bp, cpu_reg->inst, 0);
+ bnx2_reg_wr_ind(bp, cpu_reg->pc, fw->start_addr);
/* Start the CPU. */
- val = REG_RD_IND(bp, cpu_reg->mode);
+ val = bnx2_reg_rd_ind(bp, cpu_reg->mode);
val &= ~cpu_reg->mode_value_halt;
- REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear);
- REG_WR_IND(bp, cpu_reg->mode, val);
+ bnx2_reg_wr_ind(bp, cpu_reg->state, cpu_reg->state_value_clear);
+ bnx2_reg_wr_ind(bp, cpu_reg->mode, val);
return 0;
}
@@ -3833,7 +3884,7 @@ bnx2_init_nvram(struct bnx2 *bp)
}
get_flash_size:
- val = REG_RD_IND(bp, bp->shmem_base + BNX2_SHARED_HW_CFG_CONFIG2);
+ val = bnx2_shmem_rd(bp, BNX2_SHARED_HW_CFG_CONFIG2);
val &= BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK;
if (val)
bp->flash_size = val;
@@ -4142,14 +4193,14 @@ bnx2_init_remote_phy(struct bnx2 *bp)
if (!(bp->phy_flags & BNX2_PHY_FLAG_SERDES))
return;
- val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_CAP_MB);
+ val = bnx2_shmem_rd(bp, BNX2_FW_CAP_MB);
if ((val & BNX2_FW_CAP_SIGNATURE_MASK) != BNX2_FW_CAP_SIGNATURE)
return;
if (val & BNX2_FW_CAP_REMOTE_PHY_CAPABLE) {
bp->phy_flags |= BNX2_PHY_FLAG_REMOTE_PHY_CAP;
- val = REG_RD_IND(bp, bp->shmem_base + BNX2_LINK_STATUS);
+ val = bnx2_shmem_rd(bp, BNX2_LINK_STATUS);
if (val & BNX2_LINK_STATUS_SERDES_LINK)
bp->phy_port = PORT_FIBRE;
else
@@ -4167,8 +4218,7 @@ bnx2_init_remote_phy(struct bnx2 *bp)
}
sig = BNX2_DRV_ACK_CAP_SIGNATURE |
BNX2_FW_CAP_REMOTE_PHY_CAPABLE;
- REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_ACK_CAP_MB,
- sig);
+ bnx2_shmem_wr(bp, BNX2_DRV_ACK_CAP_MB, sig);
}
}
}
@@ -4204,8 +4254,8 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
/* Deposit a driver reset signature so the firmware knows that
* this is a soft reset. */
- REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE,
- BNX2_DRV_RESET_SIGNATURE_MAGIC);
+ bnx2_shmem_wr(bp, BNX2_DRV_RESET_SIGNATURE,
+ BNX2_DRV_RESET_SIGNATURE_MAGIC);
/* Do a dummy read to force the chip to complete all current transaction
* before we issue a reset. */
@@ -4438,18 +4488,21 @@ bnx2_init_chip(struct bnx2 *bp)
}
if (bp->flags & BNX2_FLAG_USING_MSIX) {
+ u32 base = ((BNX2_TX_VEC - 1) * BNX2_HC_SB_CONFIG_SIZE) +
+ BNX2_HC_SB_CONFIG_1;
+
REG_WR(bp, BNX2_HC_MSIX_BIT_VECTOR,
BNX2_HC_MSIX_BIT_VECTOR_VAL);
- REG_WR(bp, BNX2_HC_SB_CONFIG_1,
+ REG_WR(bp, base,
BNX2_HC_SB_CONFIG_1_TX_TMR_MODE |
BNX2_HC_SB_CONFIG_1_ONE_SHOT);
- REG_WR(bp, BNX2_HC_TX_QUICK_CONS_TRIP_1,
+ REG_WR(bp, base + BNX2_HC_TX_QUICK_CONS_TRIP_OFF,
(bp->tx_quick_cons_trip_int << 16) |
bp->tx_quick_cons_trip);
- REG_WR(bp, BNX2_HC_TX_TICKS_1,
+ REG_WR(bp, base + BNX2_HC_TX_TICKS_OFF,
(bp->tx_ticks_int << 16) | bp->tx_ticks);
val |= BNX2_HC_CONFIG_SB_ADDR_INC_128B;
@@ -4509,6 +4562,7 @@ static void
bnx2_init_tx_context(struct bnx2 *bp, u32 cid)
{
u32 val, offset0, offset1, offset2, offset3;
+ u32 cid_addr = GET_CID_ADDR(cid);
if (CHIP_NUM(bp) == CHIP_NUM_5709) {
offset0 = BNX2_L2CTX_TYPE_XI;
@@ -4522,16 +4576,16 @@ bnx2_init_tx_context(struct bnx2 *bp, u32 cid)
offset3 = BNX2_L2CTX_TBDR_BHADDR_LO;
}
val = BNX2_L2CTX_TYPE_TYPE_L2 | BNX2_L2CTX_TYPE_SIZE_L2;
- CTX_WR(bp, GET_CID_ADDR(cid), offset0, val);
+ bnx2_ctx_wr(bp, cid_addr, offset0, val);
val = BNX2_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16);
- CTX_WR(bp, GET_CID_ADDR(cid), offset1, val);
+ bnx2_ctx_wr(bp, cid_addr, offset1, val);
val = (u64) bp->tx_desc_mapping >> 32;
- CTX_WR(bp, GET_CID_ADDR(cid), offset2, val);
+ bnx2_ctx_wr(bp, cid_addr, offset2, val);
val = (u64) bp->tx_desc_mapping & 0xffffffff;
- CTX_WR(bp, GET_CID_ADDR(cid), offset3, val);
+ bnx2_ctx_wr(bp, cid_addr, offset3, val);
}
static void
@@ -4601,36 +4655,38 @@ bnx2_init_rx_ring(struct bnx2 *bp)
bnx2_init_rxbd_rings(bp->rx_desc_ring, bp->rx_desc_mapping,
bp->rx_buf_use_size, bp->rx_max_ring);
- CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, 0);
+ bnx2_init_rx_context0(bp);
+
+ if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ val = REG_RD(bp, BNX2_MQ_MAP_L2_5);
+ REG_WR(bp, BNX2_MQ_MAP_L2_5, val | BNX2_MQ_MAP_L2_5_ARM);
+ }
+
+ bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, 0);
if (bp->rx_pg_ring_size) {
bnx2_init_rxbd_rings(bp->rx_pg_desc_ring,
bp->rx_pg_desc_mapping,
PAGE_SIZE, bp->rx_max_pg_ring);
val = (bp->rx_buf_use_size << 16) | PAGE_SIZE;
- CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, val);
- CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_RBDC_KEY,
+ bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, val);
+ bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_RBDC_KEY,
BNX2_L2CTX_RBDC_JUMBO_KEY);
val = (u64) bp->rx_pg_desc_mapping[0] >> 32;
- CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_HI, val);
+ bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_HI, val);
val = (u64) bp->rx_pg_desc_mapping[0] & 0xffffffff;
- CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_LO, val);
+ bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_LO, val);
if (CHIP_NUM(bp) == CHIP_NUM_5709)
REG_WR(bp, BNX2_MQ_MAP_L2_3, BNX2_MQ_MAP_L2_3_DEFAULT);
}
- val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
- val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
- val |= 0x02 << 8;
- CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val);
-
val = (u64) bp->rx_desc_mapping[0] >> 32;
- CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val);
+ bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val);
val = (u64) bp->rx_desc_mapping[0] & 0xffffffff;
- CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val);
+ bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val);
ring_prod = prod = bnapi->rx_pg_prod;
for (i = 0; i < bp->rx_pg_ring_size; i++) {
@@ -5003,9 +5059,9 @@ bnx2_do_mem_test(struct bnx2 *bp, u32 start, u32 size)
for (offset = 0; offset < size; offset += 4) {
- REG_WR_IND(bp, start + offset, test_pattern[i]);
+ bnx2_reg_wr_ind(bp, start + offset, test_pattern[i]);
- if (REG_RD_IND(bp, start + offset) !=
+ if (bnx2_reg_rd_ind(bp, start + offset) !=
test_pattern[i]) {
return -ENODEV;
}
@@ -5315,7 +5371,7 @@ bnx2_5706_serdes_has_link(struct bnx2 *bp)
bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
- if (an_dbg & MISC_SHDW_AN_DBG_NOSYNC)
+ if (an_dbg & (MISC_SHDW_AN_DBG_NOSYNC | MISC_SHDW_AN_DBG_RUDI_INVALID))
return 0;
bnx2_write_phy(bp, MII_BNX2_DSP_ADDRESS, MII_EXPAND_REG1);
@@ -5440,7 +5496,8 @@ bnx2_timer(unsigned long data)
bnx2_send_heart_beat(bp);
- bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT);
+ bp->stats_blk->stat_FwRxDrop =
+ bnx2_reg_rd_ind(bp, BNX2_FW_RX_DROP_COUNT);
/* workaround occasional corrupted counters */
if (CHIP_NUM(bp) == CHIP_NUM_5708 && bp->stats_ticks)
@@ -7155,20 +7212,20 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bnx2_init_nvram(bp);
- reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE);
+ reg = bnx2_reg_rd_ind(bp, BNX2_SHM_HDR_SIGNATURE);
if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) ==
BNX2_SHM_HDR_SIGNATURE_SIG) {
u32 off = PCI_FUNC(pdev->devfn) << 2;
- bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0 + off);
+ bp->shmem_base = bnx2_reg_rd_ind(bp, BNX2_SHM_HDR_ADDR_0 + off);
} else
bp->shmem_base = HOST_VIEW_SHMEM_BASE;
/* Get the permanent MAC address. First we need to make sure the
* firmware is actually running.
*/
- reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE);
+ reg = bnx2_shmem_rd(bp, BNX2_DEV_INFO_SIGNATURE);
if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
BNX2_DEV_INFO_SIGNATURE_MAGIC) {
@@ -7177,7 +7234,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
goto err_out_unmap;
}
- reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);
+ reg = bnx2_shmem_rd(bp, BNX2_DEV_INFO_BC_REV);
for (i = 0, j = 0; i < 3; i++) {
u8 num, k, skip0;
@@ -7191,7 +7248,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
if (i != 2)
bp->fw_version[j++] = '.';
}
- reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_FEATURE);
+ reg = bnx2_shmem_rd(bp, BNX2_PORT_FEATURE);
if (reg & BNX2_PORT_FEATURE_WOL_ENABLED)
bp->wol = 1;
@@ -7199,34 +7256,33 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->flags |= BNX2_FLAG_ASF_ENABLE;
for (i = 0; i < 30; i++) {
- reg = REG_RD_IND(bp, bp->shmem_base +
- BNX2_BC_STATE_CONDITION);
+ reg = bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION);
if (reg & BNX2_CONDITION_MFW_RUN_MASK)
break;
msleep(10);
}
}
- reg = REG_RD_IND(bp, bp->shmem_base + BNX2_BC_STATE_CONDITION);
+ reg = bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION);
reg &= BNX2_CONDITION_MFW_RUN_MASK;
if (reg != BNX2_CONDITION_MFW_RUN_UNKNOWN &&
reg != BNX2_CONDITION_MFW_RUN_NONE) {
int i;
- u32 addr = REG_RD_IND(bp, bp->shmem_base + BNX2_MFW_VER_PTR);
+ u32 addr = bnx2_shmem_rd(bp, BNX2_MFW_VER_PTR);
bp->fw_version[j++] = ' ';
for (i = 0; i < 3; i++) {
- reg = REG_RD_IND(bp, addr + i * 4);
+ reg = bnx2_reg_rd_ind(bp, addr + i * 4);
reg = swab32(reg);
memcpy(&bp->fw_version[j], &reg, 4);
j += 4;
}
}
- reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER);
+ reg = bnx2_shmem_rd(bp, BNX2_PORT_HW_CFG_MAC_UPPER);
bp->mac_addr[0] = (u8) (reg >> 8);
bp->mac_addr[1] = (u8) reg;
- reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER);
+ reg = bnx2_shmem_rd(bp, BNX2_PORT_HW_CFG_MAC_LOWER);
bp->mac_addr[2] = (u8) (reg >> 24);
bp->mac_addr[3] = (u8) (reg >> 16);
bp->mac_addr[4] = (u8) (reg >> 8);
@@ -7265,8 +7321,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->phy_port = PORT_TP;
if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
bp->phy_port = PORT_FIBRE;
- reg = REG_RD_IND(bp, bp->shmem_base +
- BNX2_SHARED_HW_CFG_CONFIG);
+ reg = bnx2_shmem_rd(bp, BNX2_SHARED_HW_CFG_CONFIG);
if (!(reg & BNX2_SHARED_HW_CFG_GIG_LINK_ON_VAUX)) {
bp->flags |= BNX2_FLAG_NO_WOL;
bp->wol = 0;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index d8e034700c3..3aa0364942e 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -348,6 +348,12 @@ struct l2_fhdr {
#define BNX2_L2CTX_BD_PRE_READ 0x00000000
#define BNX2_L2CTX_CTX_SIZE 0x00000000
#define BNX2_L2CTX_CTX_TYPE 0x00000000
+#define BNX2_L2CTX_LO_WATER_MARK_DEFAULT 32
+#define BNX2_L2CTX_LO_WATER_MARK_SCALE 4
+#define BNX2_L2CTX_LO_WATER_MARK_DIS 0
+#define BNX2_L2CTX_HI_WATER_MARK_SHIFT 4
+#define BNX2_L2CTX_HI_WATER_MARK_SCALE 16
+#define BNX2_L2CTX_WATER_MARKS_MSK 0x000000ff
#define BNX2_L2CTX_CTX_TYPE_SIZE_L2 ((0x20/20)<<16)
#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE (0xf<<28)
#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_UNDEFINED (0<<28)
@@ -4494,6 +4500,9 @@ struct l2_fhdr {
#define BNX2_MQ_MAP_L2_3_ENA (0x1L<<31)
#define BNX2_MQ_MAP_L2_3_DEFAULT 0x82004646
+#define BNX2_MQ_MAP_L2_5 0x00003d34
+#define BNX2_MQ_MAP_L2_5_ARM (0x3L<<26)
+
/*
* tsch_reg definition
* offset: 0x4c00
@@ -5510,6 +5519,15 @@ struct l2_fhdr {
#define BNX2_HC_PERIODIC_TICKS_8_HC_PERIODIC_TICKS (0xffffL<<0)
#define BNX2_HC_PERIODIC_TICKS_8_HC_INT_PERIODIC_TICKS (0xffffL<<16)
+#define BNX2_HC_SB_CONFIG_SIZE (BNX2_HC_SB_CONFIG_2 - BNX2_HC_SB_CONFIG_1)
+#define BNX2_HC_COMP_PROD_TRIP_OFF (BNX2_HC_COMP_PROD_TRIP_1 - \
+ BNX2_HC_SB_CONFIG_1)
+#define BNX2_HC_COM_TICKS_OFF (BNX2_HC_COM_TICKS_1 - BNX2_HC_SB_CONFIG_1)
+#define BNX2_HC_CMD_TICKS_OFF (BNX2_HC_CMD_TICKS_1 - BNX2_HC_SB_CONFIG_1)
+#define BNX2_HC_TX_QUICK_CONS_TRIP_OFF (BNX2_HC_TX_QUICK_CONS_TRIP_1 - \
+ BNX2_HC_SB_CONFIG_1)
+#define BNX2_HC_TX_TICKS_OFF (BNX2_HC_TX_TICKS_1 - BNX2_HC_SB_CONFIG_1)
+
/*
* txp_reg definition
@@ -6346,11 +6364,12 @@ struct l2_fhdr {
#define MII_BNX2_DSP_EXPAND_REG 0x0f00
#define MII_EXPAND_REG1 (MII_BNX2_DSP_EXPAND_REG | 1)
#define MII_EXPAND_REG1_RUDI_C 0x20
-#define MII_EXPAND_SERDES_CTL (MII_BNX2_DSP_EXPAND_REG | 2)
+#define MII_EXPAND_SERDES_CTL (MII_BNX2_DSP_EXPAND_REG | 3)
#define MII_BNX2_MISC_SHADOW 0x1c
#define MISC_SHDW_AN_DBG 0x6800
#define MISC_SHDW_AN_DBG_NOSYNC 0x0002
+#define MISC_SHDW_AN_DBG_RUDI_INVALID 0x0100
#define MISC_SHDW_MODE_CTL 0x7c00
#define MISC_SHDW_MODE_CTL_SIG_DET 0x0010
@@ -6395,7 +6414,7 @@ struct l2_fhdr {
#define RX_COPY_THRESH 128
-#define BNX2_MISC_ENABLE_DEFAULT 0x7ffffff
+#define BNX2_MISC_ENABLE_DEFAULT 0x17ffffff
#define DMA_READ_CHANS 5
#define DMA_WRITE_CHANS 3
@@ -6795,9 +6814,6 @@ struct bnx2 {
int irq_nvecs;
};
-static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset);
-static void bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val);
-
#define REG_RD(bp, offset) \
readl(bp->regview + offset)
@@ -6807,19 +6823,6 @@ static void bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val);
#define REG_WR16(bp, offset, val) \
writew(val, bp->regview + offset)
-#define REG_RD_IND(bp, offset) \
- bnx2_reg_rd_ind(bp, offset)
-
-#define REG_WR_IND(bp, offset, val) \
- bnx2_reg_wr_ind(bp, offset, val)
-
-/* Indirect context access. Unlike the MBQ_WR, these macros will not
- * trigger a chip event. */
-static void bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val);
-
-#define CTX_WR(bp, cid_addr, offset, val) \
- bnx2_ctx_wr(bp, cid_addr, offset, val)
-
struct cpu_reg {
u32 mode;
u32 mode_value_halt;
diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h
index c1ad4dd38c3..3b839d4626f 100644
--- a/drivers/net/bnx2_fw.h
+++ b/drivers/net/bnx2_fw.h
@@ -2168,760 +2168,761 @@ static struct fw_info bnx2_cp_fw_06 = {
};
static u8 bnx2_RXP_b06FwText[] = {
- 0xec, 0x5b, 0x6d, 0x6c, 0x5c, 0x57, 0x5a, 0x7e, 0xef, 0x99, 0xb1, 0x3d,
- 0x76, 0x6c, 0xe7, 0xda, 0x99, 0xa6, 0x93, 0xe2, 0x6e, 0x67, 0xec, 0x6b,
- 0x7b, 0xba, 0x36, 0xe5, 0x3a, 0x4c, 0x5b, 0xaf, 0x18, 0xb6, 0xc3, 0x1d,
- 0x27, 0x75, 0x77, 0x83, 0xe4, 0xb6, 0x61, 0x37, 0x82, 0xae, 0xb0, 0x66,
- 0x12, 0x51, 0x84, 0x10, 0x21, 0x82, 0xaa, 0x2c, 0x5d, 0x65, 0x34, 0x76,
- 0x53, 0xb7, 0x3b, 0xf1, 0x0c, 0x89, 0x4b, 0xf8, 0xd8, 0x1f, 0xee, 0xd8,
- 0x4e, 0x0a, 0x9a, 0x78, 0xba, 0xcb, 0x8f, 0x5d, 0x56, 0x4d, 0x63, 0xd2,
- 0x12, 0xfa, 0x03, 0x89, 0x16, 0x56, 0x50, 0x89, 0x85, 0x86, 0x24, 0xdb,
- 0x14, 0x09, 0x41, 0x77, 0x01, 0x6d, 0xa1, 0x69, 0x2f, 0xcf, 0x73, 0xee,
- 0xbd, 0xc9, 0xc4, 0x35, 0x6c, 0x7f, 0xf0, 0xf3, 0x1e, 0xc9, 0xba, 0xf7,
- 0x9e, 0xf3, 0x9e, 0xf7, 0xbc, 0xdf, 0x1f, 0x67, 0x92, 0xdf, 0xe8, 0x96,
- 0x2e, 0xf1, 0x47, 0x0f, 0xfe, 0x32, 0x87, 0x9f, 0x3c, 0x72, 0xef, 0x3d,
- 0xf6, 0x3d, 0xfc, 0x8e, 0xb4, 0x49, 0x94, 0x4f, 0x43, 0xc2, 0x11, 0x8e,
- 0x70, 0x84, 0x23, 0x1c, 0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70,
- 0x84, 0x23, 0x1c, 0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70, 0x84,
- 0x23, 0x1c, 0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70, 0x84, 0x23,
- 0x1c, 0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70, 0x84, 0x23, 0x1c,
- 0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70, 0x84, 0x23, 0x1c, 0xe1,
- 0x08, 0x47, 0x38, 0xc2, 0xf1, 0xff, 0x39, 0x22, 0x22, 0x26, 0x9f, 0x3d,
- 0xfe, 0x9f, 0xc4, 0x54, 0x56, 0x8e, 0x38, 0x96, 0xc4, 0x22, 0xd9, 0xd5,
- 0x27, 0x8a, 0x96, 0x48, 0xae, 0x31, 0x96, 0xcc, 0xcb, 0x87, 0x6e, 0x29,
- 0x1e, 0x15, 0xce, 0xdf, 0x99, 0xbd, 0x7e, 0xf4, 0xdc, 0xfd, 0xa9, 0xf7,
- 0x96, 0x23, 0x12, 0x33, 0xb3, 0x6f, 0x4c, 0x98, 0x23, 0x12, 0x1b, 0xc0,
- 0x9e, 0xaf, 0x8d, 0xbe, 0xbc, 0x5d, 0x7a, 0x03, 0x5c, 0x22, 0xf5, 0x4a,
- 0xca, 0xde, 0x2b, 0x63, 0xe6, 0x05, 0x89, 0x4a, 0x0e, 0x67, 0x9c, 0x6e,
- 0x88, 0x94, 0x2b, 0x06, 0x71, 0x48, 0xb9, 0x11, 0x93, 0x4b, 0x11, 0x42,
- 0x7d, 0xcb, 0x70, 0xaa, 0x1f, 0xb9, 0xb9, 0x28, 0xce, 0xb5, 0xf0, 0xde,
- 0x0c, 0xe6, 0x63, 0xa2, 0xb2, 0xa9, 0x84, 0x13, 0x99, 0x96, 0xc2, 0x92,
- 0xeb, 0xce, 0xdb, 0xb7, 0x03, 0x47, 0xbf, 0xcc, 0x5b, 0xde, 0xb7, 0x63,
- 0x7f, 0xda, 0x9c, 0x92, 0x1d, 0x98, 0x8b, 0x88, 0xb2, 0xee, 0xc0, 0xdf,
- 0x57, 0x0d, 0x67, 0xa5, 0x5b, 0xca, 0x55, 0xc9, 0x39, 0x76, 0x0c, 0xf3,
- 0x09, 0x99, 0xab, 0x26, 0x0d, 0xe7, 0xa4, 0x21, 0xc5, 0x0c, 0xde, 0x9b,
- 0xae, 0x38, 0xf6, 0x47, 0xae, 0x63, 0x11, 0xff, 0x92, 0xe1, 0x9c, 0xf9,
- 0xc8, 0x55, 0x96, 0x65, 0x16, 0x84, 0xdf, 0x09, 0x29, 0x37, 0x89, 0x87,
- 0xef, 0xc4, 0x73, 0xc9, 0x3d, 0x37, 0x9a, 0x90, 0x6f, 0x34, 0xe3, 0xf2,
- 0xf5, 0xa6, 0x29, 0x2f, 0x35, 0x07, 0xe4, 0x7c, 0xd3, 0x75, 0xbf, 0x6e,
- 0xbb, 0xee, 0x1b, 0xf8, 0xfb, 0x81, 0x7d, 0x83, 0x66, 0x8c, 0x92, 0x31,
- 0xd5, 0xfc, 0xc3, 0x6e, 0xe9, 0x4d, 0x25, 0x45, 0x75, 0xe3, 0xcc, 0x84,
- 0xcc, 0x57, 0x2b, 0xc6, 0xc3, 0x67, 0x16, 0x8d, 0x99, 0x33, 0x35, 0x23,
- 0x7f, 0x26, 0x8a, 0x39, 0x29, 0x95, 0xed, 0x17, 0x8d, 0x7c, 0x73, 0xc1,
- 0x78, 0xe4, 0x4c, 0xaf, 0xa6, 0xad, 0x5c, 0xdd, 0x09, 0xda, 0xae, 0x83,
- 0x26, 0xca, 0x34, 0x65, 0xfe, 0x3c, 0xc4, 0xec, 0x54, 0xc8, 0x57, 0xbb,
- 0xe4, 0xe2, 0x5c, 0x77, 0x5d, 0x95, 0x75, 0x8f, 0x3a, 0x19, 0xcb, 0x2c,
- 0x0b, 0xe9, 0xd3, 0x73, 0xe7, 0x23, 0xa0, 0x39, 0x2f, 0xa7, 0x41, 0x7f,
- 0xb7, 0x91, 0x3f, 0x15, 0x05, 0x1d, 0x32, 0x10, 0x11, 0xee, 0x1b, 0x4e,
- 0x14, 0xa4, 0x81, 0x33, 0xc4, 0x54, 0x59, 0xca, 0x11, 0x34, 0x83, 0x96,
- 0x6f, 0x54, 0xc1, 0x43, 0x15, 0x3c, 0x54, 0xc9, 0x5b, 0x52, 0xce, 0x8d,
- 0x06, 0xbc, 0xb9, 0xee, 0x5f, 0xdb, 0xa4, 0x3d, 0x95, 0xcc, 0xa9, 0x80,
- 0x4f, 0xd7, 0xfd, 0xbe, 0x4d, 0x5e, 0xc9, 0x8f, 0xeb, 0xbe, 0x64, 0x53,
- 0x86, 0xee, 0x79, 0x65, 0x55, 0xc0, 0x8b, 0x05, 0xfc, 0x94, 0xef, 0x22,
- 0x78, 0x58, 0x00, 0x7f, 0xa7, 0xc1, 0x5b, 0x0d, 0x74, 0xfc, 0xa8, 0xf3,
- 0x4a, 0x46, 0x7e, 0xf4, 0x86, 0xbc, 0x92, 0x94, 0x71, 0x61, 0x55, 0x41,
- 0xd6, 0xdb, 0xa4, 0xb0, 0x6c, 0xca, 0xec, 0x6a, 0xb0, 0x3f, 0xd0, 0xfb,
- 0x61, 0xd9, 0x57, 0xed, 0x87, 0x6c, 0x28, 0xcb, 0x94, 0x2d, 0x42, 0xbd,
- 0x95, 0xd3, 0x4a, 0xc4, 0x28, 0xd8, 0x47, 0xb5, 0xbe, 0x57, 0x2d, 0xc9,
- 0x15, 0x6c, 0xca, 0x51, 0x92, 0x05, 0xbb, 0x94, 0x88, 0xc2, 0xbe, 0x56,
- 0xad, 0x92, 0x19, 0x15, 0xca, 0x31, 0x95, 0xf8, 0x32, 0x64, 0x79, 0xa8,
- 0x22, 0xb9, 0xcf, 0x55, 0x02, 0x19, 0x7b, 0xf2, 0xfd, 0x7c, 0xe5, 0xa7,
- 0x7b, 0xa4, 0x4b, 0x7d, 0xaa, 0x4d, 0x7e, 0x15, 0x7b, 0x89, 0xfb, 0x96,
- 0xbd, 0xd8, 0xe7, 0xc1, 0x79, 0x7b, 0x53, 0x07, 0x44, 0x08, 0x5b, 0x1e,
- 0x6a, 0xf3, 0x7c, 0xc2, 0x70, 0xac, 0x52, 0x22, 0x02, 0xb8, 0x82, 0x94,
- 0x27, 0xfc, 0xb9, 0x36, 0xc7, 0xba, 0x1e, 0x99, 0xb7, 0x53, 0xc9, 0xb2,
- 0x5c, 0x8f, 0x5c, 0xb4, 0xf5, 0x5c, 0xa7, 0x63, 0xb9, 0xb2, 0x06, 0xec,
- 0xcf, 0xc0, 0xfe, 0x2f, 0x80, 0xa3, 0x5f, 0xae, 0xe8, 0xf9, 0x1e, 0xec,
- 0x4f, 0xb7, 0x01, 0x67, 0x97, 0xa4, 0xd2, 0x75, 0xcc, 0x5f, 0xf4, 0xe6,
- 0xfb, 0x3c, 0xbc, 0xe5, 0xa1, 0x2e, 0x8d, 0x5b, 0xe4, 0x45, 0x6f, 0xfe,
- 0x36, 0x0f, 0x77, 0xf9, 0x6e, 0xcc, 0x03, 0xff, 0xc8, 0xf4, 0xa8, 0xa1,
- 0xe7, 0x77, 0xd1, 0x7f, 0x7e, 0xa9, 0x72, 0x3d, 0xb2, 0x66, 0xbb, 0x92,
- 0x9f, 0x18, 0x99, 0x1e, 0x31, 0x3c, 0x7c, 0xc7, 0xbc, 0x7d, 0x77, 0x7a,
- 0xf8, 0x46, 0xa6, 0xd3, 0x86, 0x87, 0x6f, 0xb5, 0xa2, 0xf7, 0x4a, 0xa1,
- 0x42, 0xd8, 0x91, 0x69, 0xcb, 0xb8, 0x53, 0x66, 0xfb, 0x46, 0xa6, 0x07,
- 0x0d, 0xf5, 0xa9, 0x6d, 0x1e, 0x1f, 0xa9, 0x80, 0x86, 0x6d, 0x9a, 0x06,
- 0x9e, 0xab, 0xe7, 0x87, 0x1d, 0xab, 0x7c, 0xf7, 0x36, 0x7d, 0x3e, 0xcf,
- 0xd4, 0x73, 0x77, 0x93, 0x2e, 0x9e, 0x5d, 0x9c, 0xb8, 0xe5, 0xdc, 0x1f,
- 0xbf, 0x29, 0x9f, 0xad, 0xce, 0xe4, 0x79, 0x12, 0x8b, 0x66, 0xa3, 0x13,
- 0xf3, 0x95, 0xc3, 0xe2, 0x54, 0x93, 0x32, 0x37, 0xde, 0x29, 0xb3, 0xe6,
- 0xd0, 0xec, 0x3e, 0x61, 0xac, 0x89, 0x4d, 0x14, 0x7d, 0x1d, 0xe6, 0xc5,
- 0x90, 0x39, 0xf0, 0xb8, 0xaf, 0x21, 0x31, 0x03, 0xf0, 0x43, 0x8d, 0xa8,
- 0x3c, 0xdb, 0x34, 0xa4, 0x5d, 0xfb, 0x67, 0xca, 0xdc, 0x80, 0x1d, 0x3e,
- 0x5d, 0xa5, 0x1d, 0xd3, 0x66, 0x25, 0x57, 0x87, 0x9d, 0x9e, 0xd7, 0xbe,
- 0xda, 0x45, 0xbd, 0x96, 0x4a, 0x02, 0x57, 0xcc, 0x5a, 0x66, 0x5d, 0x3a,
- 0x24, 0x37, 0x23, 0x25, 0xae, 0xfb, 0xbe, 0x93, 0x58, 0x91, 0x73, 0xb0,
- 0x01, 0x31, 0x9d, 0x0c, 0xe7, 0x09, 0xdf, 0x02, 0x6b, 0x7a, 0x7e, 0x17,
- 0x81, 0xdf, 0x15, 0x33, 0x84, 0x95, 0x92, 0x93, 0xa1, 0xef, 0xc1, 0x16,
- 0x9b, 0xbb, 0x7a, 0xbc, 0xd8, 0x86, 0xd8, 0x12, 0xef, 0x86, 0x8f, 0x7f,
- 0x0a, 0xfe, 0x37, 0x60, 0x38, 0xa7, 0x5c, 0xb7, 0x68, 0x4b, 0x5c, 0x09,
- 0xfd, 0x0f, 0xbe, 0xde, 0xe4, 0x5a, 0x37, 0xe6, 0xc5, 0x9c, 0xb3, 0xfb,
- 0xc0, 0x9f, 0xeb, 0x4e, 0xdb, 0x49, 0x29, 0xdb, 0xdb, 0xb1, 0xaf, 0x4d,
- 0xfa, 0x2c, 0xda, 0x3b, 0x7d, 0x7a, 0x1b, 0xce, 0x33, 0xf8, 0xdd, 0x8b,
- 0xf3, 0x7a, 0x30, 0x97, 0x98, 0xa3, 0x1f, 0x67, 0xc6, 0xc0, 0xbf, 0x17,
- 0x2f, 0x45, 0xde, 0x06, 0xad, 0xdc, 0xa3, 0xe1, 0x62, 0x1d, 0xd9, 0x8c,
- 0x5c, 0xab, 0xec, 0x92, 0x4b, 0x71, 0xf2, 0x0f, 0x9c, 0x55, 0xc4, 0xc4,
- 0xb8, 0x01, 0xfa, 0x13, 0x7e, 0xdc, 0xdb, 0xe1, 0x7f, 0x1b, 0x77, 0x79,
- 0x67, 0x88, 0x19, 0xc9, 0xf6, 0x4a, 0x5e, 0xcf, 0x89, 0x52, 0x13, 0xdb,
- 0xfc, 0xf5, 0x5e, 0x63, 0xef, 0x29, 0x25, 0xa3, 0xf7, 0x21, 0x66, 0xe1,
- 0xac, 0x8b, 0x96, 0xeb, 0x5e, 0xb4, 0xbf, 0x0f, 0x9f, 0x57, 0xd2, 0x66,
- 0xfd, 0x63, 0xaf, 0x74, 0x41, 0x9e, 0x55, 0xa3, 0x45, 0x86, 0x09, 0x39,
- 0x56, 0xe5, 0x9e, 0x92, 0x44, 0x2d, 0xc2, 0x10, 0xfe, 0xef, 0x01, 0x17,
- 0x91, 0x0e, 0xf8, 0xe2, 0x05, 0x3b, 0x4e, 0x7a, 0xb7, 0x7b, 0xf0, 0x7d,
- 0x38, 0x83, 0xb4, 0xd3, 0xf7, 0x5c, 0xed, 0x7b, 0x4e, 0x44, 0xe5, 0xa6,
- 0x96, 0xe0, 0x49, 0xe3, 0x94, 0xb7, 0xd3, 0x87, 0x50, 0x2f, 0x73, 0xa3,
- 0x25, 0x53, 0x69, 0x5d, 0x8b, 0xe4, 0x2b, 0x77, 0xc9, 0xbc, 0x8d, 0xf3,
- 0xac, 0x28, 0x68, 0x66, 0x9c, 0x19, 0x2e, 0x45, 0x14, 0x3c, 0xac, 0x9f,
- 0xb2, 0x0a, 0x68, 0x7d, 0x0b, 0xe7, 0x95, 0x8c, 0xa8, 0xc5, 0x33, 0xbe,
- 0xe4, 0xcb, 0x87, 0x76, 0x67, 0x8b, 0x53, 0xe9, 0xe6, 0x37, 0xe8, 0xe8,
- 0xd2, 0x74, 0x44, 0xb2, 0x5a, 0x77, 0x86, 0xca, 0x52, 0x96, 0x6d, 0x3e,
- 0x3d, 0xb7, 0xe0, 0x01, 0x1f, 0xdc, 0x6b, 0x61, 0x6f, 0x0c, 0x34, 0xf6,
- 0xb4, 0xd0, 0xdf, 0x45, 0x78, 0xc8, 0x2a, 0xe6, 0x9f, 0xa1, 0xf9, 0x36,
- 0x3c, 0xbe, 0x03, 0x59, 0x7d, 0x1b, 0xb2, 0xfa, 0xc0, 0x1d, 0xdd, 0x4d,
- 0x1c, 0x19, 0xe0, 0x60, 0x1e, 0x62, 0xbc, 0x62, 0x8c, 0x32, 0x6f, 0xe0,
- 0x82, 0x1f, 0xa8, 0x48, 0xb6, 0x5b, 0xf2, 0xa6, 0xce, 0x01, 0x80, 0x9d,
- 0x14, 0x1d, 0xe3, 0x2d, 0xf2, 0xe8, 0x7f, 0x5b, 0x29, 0x6d, 0x37, 0x85,
- 0x1a, 0xf3, 0xc0, 0x57, 0x40, 0xdb, 0x46, 0x4a, 0x69, 0xd6, 0xba, 0x21,
- 0x73, 0x89, 0xb5, 0x65, 0xdf, 0x90, 0xb5, 0x8a, 0xda, 0xd9, 0x2e, 0xdb,
- 0x65, 0x06, 0x32, 0xaa, 0x4f, 0x22, 0x7f, 0x8e, 0x77, 0x4b, 0xe4, 0x1e,
- 0xe6, 0x81, 0x04, 0x68, 0xdd, 0x48, 0x99, 0x72, 0xdd, 0x55, 0x23, 0xd8,
- 0x3f, 0x0e, 0x3d, 0xec, 0xa7, 0x4e, 0x95, 0x0f, 0x47, 0x98, 0x08, 0x65,
- 0xde, 0xdf, 0x2e, 0xc4, 0xcd, 0xb5, 0xb1, 0x84, 0x29, 0x9c, 0xef, 0x84,
- 0x5e, 0xb9, 0x97, 0xfc, 0x79, 0x7b, 0x3e, 0xce, 0x5f, 0xb0, 0x4e, 0x99,
- 0x51, 0x76, 0xb0, 0x31, 0xf0, 0xe8, 0xd8, 0x3f, 0xeb, 0xcb, 0xe6, 0x76,
- 0xb9, 0x64, 0x8a, 0x51, 0xb7, 0x6f, 0x6b, 0x91, 0x1f, 0x79, 0xee, 0xdb,
- 0xc4, 0x33, 0x71, 0x6c, 0xcd, 0xf7, 0xc1, 0x1a, 0xcf, 0xf4, 0xce, 0x9e,
- 0xb7, 0x36, 0x52, 0x51, 0xb9, 0x55, 0xbe, 0xd0, 0xa5, 0x14, 0x2b, 0xb4,
- 0x8d, 0x76, 0x29, 0xa0, 0xfe, 0xb0, 0x77, 0x23, 0xa8, 0x3c, 0xa2, 0x64,
- 0xe2, 0x3e, 0xe2, 0xfc, 0x3b, 0xf2, 0x34, 0x99, 0x54, 0x86, 0x14, 0xec,
- 0xce, 0x16, 0x7d, 0x71, 0xae, 0xd5, 0xb6, 0xbf, 0xed, 0xdb, 0xf6, 0x07,
- 0xee, 0xc4, 0xee, 0x40, 0xef, 0x90, 0xd7, 0xc7, 0xf6, 0x08, 0xf4, 0xfc,
- 0x7f, 0xed, 0xa1, 0xad, 0xc4, 0x36, 0xed, 0x29, 0x6d, 0xb1, 0x67, 0x87,
- 0xc8, 0x17, 0xe8, 0x43, 0x3d, 0x7e, 0xcc, 0x08, 0x7c, 0x2a, 0xc0, 0x03,
- 0xdd, 0x68, 0x5b, 0xe5, 0xdc, 0x56, 0xbe, 0x48, 0x1c, 0xc4, 0xc5, 0xbd,
- 0x84, 0x09, 0x72, 0x2a, 0xd4, 0x21, 0x5b, 0xe6, 0x55, 0x8c, 0x69, 0xbc,
- 0x2b, 0xc4, 0xa1, 0xd6, 0xfc, 0xca, 0x39, 0x13, 0xdf, 0x53, 0x78, 0x5a,
- 0x52, 0x68, 0xd0, 0x9f, 0xb8, 0x9f, 0xf9, 0xf6, 0x5d, 0x3f, 0x7e, 0x76,
- 0xcf, 0x46, 0xb3, 0x71, 0xc4, 0x4f, 0x99, 0x29, 0x57, 0x8e, 0xba, 0x11,
- 0x4b, 0x4a, 0x77, 0x64, 0x69, 0x1f, 0xdd, 0x93, 0x88, 0x91, 0x33, 0xe5,
- 0x06, 0xeb, 0x22, 0x84, 0x31, 0xec, 0x43, 0x8e, 0x8e, 0xa9, 0xc5, 0x58,
- 0xe9, 0xc7, 0xb2, 0x8c, 0xcb, 0x49, 0x49, 0x36, 0xde, 0x43, 0xdd, 0x61,
- 0x8a, 0xa3, 0x6d, 0xed, 0xf9, 0x5d, 0xa4, 0xb7, 0x8c, 0x1a, 0x22, 0x9a,
- 0x95, 0xa8, 0xca, 0xb6, 0xc7, 0xe6, 0x32, 0xdd, 0xe2, 0x64, 0xa6, 0x77,
- 0xa9, 0xf5, 0x7d, 0xbb, 0x22, 0xeb, 0x3b, 0x67, 0xdb, 0xb2, 0xa5, 0x5d,
- 0x6a, 0x51, 0x64, 0xa5, 0x22, 0x0a, 0x75, 0x4d, 0xe2, 0xa0, 0xe0, 0x7b,
- 0xfd, 0xd1, 0x47, 0x55, 0x36, 0x02, 0xdd, 0xca, 0x53, 0xab, 0x99, 0x28,
- 0x6b, 0xc6, 0xe4, 0x8c, 0x3c, 0x85, 0x3a, 0xf1, 0x49, 0x99, 0xab, 0x80,
- 0x2e, 0xcd, 0x77, 0x02, 0xfc, 0x0e, 0x00, 0x37, 0x69, 0x8f, 0x23, 0xc6,
- 0x7a, 0xb4, 0x83, 0xe6, 0x5c, 0x9e, 0x75, 0x52, 0x86, 0x79, 0xe5, 0x3d,
- 0xd8, 0x0f, 0xfd, 0xe5, 0x5f, 0x64, 0xcd, 0xea, 0x94, 0x82, 0x17, 0x1f,
- 0x68, 0xaf, 0x58, 0x7b, 0xd7, 0x5f, 0xbb, 0x8a, 0x35, 0xda, 0xef, 0xb6,
- 0x16, 0x1d, 0x7e, 0x55, 0xd7, 0x3a, 0x17, 0x6d, 0xbe, 0x13, 0xf6, 0x2f,
- 0x27, 0x3c, 0xd8, 0xd7, 0x27, 0xd6, 0xac, 0x47, 0xb7, 0x4b, 0x97, 0x49,
- 0xbd, 0xe1, 0x9c, 0x38, 0x63, 0x2c, 0xd6, 0x2f, 0xf9, 0xb8, 0xbe, 0x0b,
- 0x5c, 0xdd, 0xa4, 0x1b, 0x23, 0x8a, 0x75, 0xd0, 0x87, 0x9a, 0xa7, 0x70,
- 0x23, 0xd6, 0x10, 0xf6, 0x65, 0x1f, 0xd7, 0xb7, 0x5a, 0x70, 0x71, 0x8d,
- 0x4f, 0x9e, 0x89, 0xb3, 0xbb, 0xc8, 0x1b, 0xf9, 0xa1, 0x0e, 0xa8, 0x8f,
- 0xb4, 0x31, 0x83, 0xd8, 0x3e, 0xd3, 0xd4, 0xb5, 0x9d, 0x91, 0xaf, 0xa2,
- 0xe6, 0x6a, 0x3e, 0x0f, 0x1a, 0x59, 0xc3, 0x0e, 0xfa, 0xf5, 0x35, 0xed,
- 0x68, 0x43, 0xdb, 0x23, 0xe3, 0x4e, 0x59, 0xdb, 0xd5, 0x6b, 0x9e, 0x5d,
- 0x59, 0xd4, 0xcd, 0x6b, 0x32, 0xd8, 0xa8, 0x6c, 0xf7, 0xfe, 0xaf, 0xb6,
- 0x29, 0x11, 0xad, 0x4f, 0xe6, 0x37, 0xda, 0xd8, 0xed, 0x88, 0xeb, 0xee,
- 0x0f, 0x99, 0x67, 0x66, 0x98, 0x83, 0x66, 0x98, 0x3b, 0x0c, 0x3f, 0x1e,
- 0x26, 0x5b, 0x70, 0x24, 0x81, 0xa3, 0xee, 0xdb, 0xef, 0x73, 0x3e, 0xae,
- 0xa0, 0xfe, 0x0c, 0x62, 0xea, 0xef, 0xdf, 0x71, 0xeb, 0xfa, 0x47, 0x3e,
- 0x7d, 0xed, 0x3a, 0x1e, 0xc3, 0xd6, 0x41, 0x7f, 0x72, 0x56, 0xc1, 0xbe,
- 0xf2, 0x0d, 0x4f, 0x1f, 0xf0, 0x7d, 0xd8, 0x1e, 0x5f, 0x03, 0xdd, 0x7a,
- 0xf5, 0xb7, 0x27, 0x03, 0xea, 0x34, 0x47, 0xbe, 0x73, 0x51, 0xd2, 0xd2,
- 0x9c, 0xc6, 0x7e, 0x39, 0xcc, 0xdc, 0x58, 0x00, 0x1f, 0x07, 0xcd, 0x31,
- 0x73, 0x8e, 0xb8, 0xe3, 0x02, 0x9c, 0xa8, 0x25, 0xb3, 0x1d, 0xbe, 0x9e,
- 0xbf, 0xc9, 0xf3, 0x81, 0x7b, 0x1b, 0xbf, 0xf1, 0xfc, 0xa6, 0x4f, 0xcf,
- 0x95, 0x5e, 0x8f, 0x9e, 0x60, 0x7d, 0xd0, 0xbc, 0xf5, 0xbb, 0xbe, 0xcb,
- 0x97, 0x27, 0xde, 0x9f, 0xf4, 0xe9, 0xa2, 0x6e, 0x5a, 0x69, 0xa2, 0x5e,
- 0xfe, 0x1d, 0x78, 0x74, 0xad, 0x51, 0x52, 0x59, 0xd4, 0x2e, 0x19, 0xe6,
- 0xac, 0xd4, 0x64, 0x4e, 0x2c, 0xe8, 0x24, 0x65, 0xcf, 0x62, 0xd7, 0xbb,
- 0x15, 0xea, 0xf9, 0x3a, 0x62, 0x35, 0xf5, 0xfe, 0xbe, 0xcc, 0x57, 0x86,
- 0xec, 0x76, 0x83, 0xfe, 0x9a, 0x4a, 0x9f, 0x96, 0x31, 0xfb, 0xb4, 0xae,
- 0xa1, 0x52, 0xc9, 0x63, 0x42, 0xd9, 0x5e, 0x97, 0x61, 0x5d, 0xdb, 0xbc,
- 0x2f, 0x16, 0xe4, 0x32, 0x53, 0x85, 0x8f, 0xed, 0xfe, 0x57, 0x57, 0xd7,
- 0xa4, 0x08, 0x6f, 0xef, 0x6c, 0x81, 0xeb, 0x75, 0x8d, 0x87, 0xf8, 0x5a,
- 0x71, 0x19, 0xd2, 0xb1, 0x3b, 0xc0, 0x67, 0xc9, 0x42, 0x33, 0xc0, 0x19,
- 0x45, 0x5c, 0x46, 0x0c, 0xd8, 0xfd, 0x05, 0x5f, 0x1f, 0x7c, 0x7f, 0xd3,
- 0x65, 0x2d, 0xa4, 0xb2, 0xa7, 0xfc, 0xb9, 0x3f, 0xa3, 0x0c, 0xf0, 0x1d,
- 0xc8, 0xfd, 0x79, 0x3f, 0xde, 0x94, 0x8c, 0x5c, 0x93, 0x32, 0xa0, 0xad,
- 0x40, 0xff, 0xda, 0x3e, 0xe1, 0x33, 0xd5, 0xcf, 0x22, 0x66, 0xf5, 0x79,
- 0xf5, 0x03, 0x7a, 0xb0, 0x5c, 0x93, 0x73, 0x1b, 0x1d, 0x8e, 0xdd, 0xe6,
- 0xfb, 0xd2, 0x3e, 0xcc, 0xcd, 0xe0, 0x8f, 0xb2, 0x23, 0xcc, 0x7e, 0xbc,
- 0xe7, 0x7c, 0x38, 0x99, 0x74, 0x90, 0xbb, 0x72, 0xfb, 0xa7, 0xf0, 0x6d,
- 0xf8, 0x7d, 0x96, 0x96, 0x7b, 0x0d, 0xb5, 0x0a, 0xe4, 0x39, 0x0c, 0x7e,
- 0x92, 0x32, 0xd5, 0x84, 0xce, 0x6f, 0xc4, 0xb3, 0x1b, 0x30, 0xa5, 0x9b,
- 0x30, 0x5e, 0xec, 0x9b, 0x6a, 0xbe, 0xe5, 0x32, 0x1e, 0xfc, 0x89, 0xf6,
- 0x97, 0x24, 0x68, 0x0f, 0x7a, 0xb5, 0x9c, 0xf1, 0x70, 0x75, 0xda, 0x78,
- 0xa4, 0xca, 0x3d, 0xea, 0x6b, 0xfd, 0x62, 0x25, 0x1d, 0x85, 0x3a, 0x75,
- 0x77, 0x2f, 0xce, 0x3c, 0x06, 0xdb, 0x28, 0x19, 0x33, 0xa3, 0xdb, 0xa5,
- 0x90, 0xee, 0x07, 0xcd, 0xf7, 0xe3, 0xd9, 0x8e, 0xf9, 0x9f, 0xc2, 0x3c,
- 0xec, 0x28, 0x4d, 0xff, 0xe8, 0xd4, 0xbd, 0xe4, 0xac, 0x49, 0x1a, 0x87,
- 0x7d, 0xdb, 0xfa, 0x8e, 0xe9, 0xd9, 0xd2, 0x13, 0xf8, 0xde, 0x86, 0xf9,
- 0x5f, 0xc0, 0x13, 0xb9, 0x6c, 0x77, 0x30, 0x4f, 0x1f, 0x9c, 0xc4, 0xfc,
- 0xbd, 0xc0, 0xf1, 0xdb, 0x78, 0xbf, 0x0b, 0xef, 0xbf, 0xb5, 0x69, 0xef,
- 0x6f, 0xf2, 0x6c, 0xcc, 0x3b, 0x9b, 0xe6, 0x83, 0xf8, 0xcd, 0xf3, 0x44,
- 0xfa, 0xd6, 0xc1, 0xf8, 0x7a, 0x4c, 0x76, 0x9c, 0xee, 0x12, 0x55, 0xf7,
- 0x62, 0xb8, 0xaa, 0x9b, 0xd2, 0x7f, 0x9a, 0xf1, 0xfb, 0xaf, 0xb0, 0xc7,
- 0x12, 0xb5, 0x0e, 0xa5, 0x51, 0xb7, 0xda, 0x47, 0x0f, 0x1c, 0x19, 0x5c,
- 0xe6, 0x73, 0xf6, 0xc8, 0x44, 0x83, 0x30, 0x7c, 0x7f, 0xec, 0xc8, 0x60,
- 0xe3, 0x6f, 0x01, 0x0b, 0xb9, 0x54, 0x03, 0xfc, 0x84, 0xff, 0xd3, 0x4d,
- 0x67, 0x6a, 0xd9, 0xe2, 0x4c, 0xfa, 0xfd, 0x81, 0x23, 0x4e, 0x8d, 0x75,
- 0x42, 0x2a, 0x21, 0xba, 0x16, 0x9f, 0x3d, 0x52, 0x44, 0x7e, 0x8c, 0x68,
- 0x5a, 0x82, 0x75, 0xae, 0x51, 0x0f, 0x5b, 0xd1, 0x46, 0xba, 0x5a, 0xf1,
- 0x30, 0xcf, 0x10, 0xcf, 0x63, 0xc0, 0x93, 0x06, 0x1e, 0xe6, 0x1b, 0x8f,
- 0xde, 0xe4, 0xf2, 0x56, 0xb4, 0x11, 0x17, 0xcf, 0x0a, 0xf0, 0xf5, 0x8b,
- 0x3a, 0xfd, 0x26, 0xe9, 0x35, 0x59, 0xdb, 0x7a, 0xb1, 0xa6, 0x4d, 0x0a,
- 0x27, 0x99, 0xb3, 0x77, 0xfb, 0xdf, 0x71, 0x93, 0x3d, 0x77, 0x52, 0x71,
- 0x9e, 0x4f, 0xac, 0x65, 0xee, 0xc4, 0x1c, 0xbe, 0x57, 0x02, 0x58, 0xe5,
- 0xc3, 0xf6, 0xb4, 0xf0, 0xdd, 0xe6, 0xcb, 0x9a, 0x67, 0x06, 0xbd, 0x67,
- 0x2b, 0x2d, 0x00, 0x85, 0x1e, 0xfa, 0x6e, 0xe8, 0x21, 0xe0, 0x13, 0x0b,
- 0xeb, 0xa4, 0x2d, 0x0d, 0x5e, 0x03, 0xda, 0x3e, 0xa9, 0xfe, 0xb8, 0x37,
- 0x8d, 0xbf, 0xe0, 0xbc, 0x40, 0x06, 0xa4, 0x8b, 0x4f, 0xd8, 0xf2, 0xc7,
- 0x7a, 0xe7, 0x34, 0xfc, 0x8e, 0xf7, 0x1e, 0xae, 0xbb, 0x66, 0x53, 0xf6,
- 0x1d, 0xd0, 0x3b, 0x79, 0x31, 0xd0, 0x4b, 0x28, 0xd6, 0x74, 0x49, 0xf6,
- 0xac, 0x87, 0xe4, 0x6d, 0xe0, 0xca, 0xa1, 0xaf, 0xf4, 0x7a, 0xa3, 0x59,
- 0xc4, 0xc7, 0x0d, 0xd8, 0xe7, 0x45, 0x8b, 0xf7, 0x2f, 0x51, 0xe6, 0x3b,
- 0x29, 0x37, 0xfe, 0x19, 0x30, 0xac, 0xaf, 0x6e, 0xde, 0xad, 0x2c, 0x03,
- 0x66, 0x05, 0x6b, 0xc7, 0xbc, 0xb8, 0xcc, 0xd8, 0xee, 0x2a, 0xd4, 0x1e,
- 0x45, 0xeb, 0xbf, 0x5d, 0xd6, 0x59, 0x37, 0x61, 0xb7, 0xba, 0x0b, 0x41,
- 0xce, 0x59, 0x4a, 0x2d, 0x2c, 0x23, 0x86, 0xd7, 0x2c, 0xb5, 0x43, 0x69,
- 0x8b, 0x4c, 0xd5, 0x10, 0x93, 0xd0, 0xf5, 0xa6, 0x92, 0xcb, 0xf2, 0x03,
- 0xad, 0x87, 0x36, 0x6b, 0xcc, 0xec, 0x57, 0x5f, 0xa4, 0x5d, 0x69, 0xca,
- 0x23, 0x27, 0x90, 0x97, 0xc7, 0x1f, 0x46, 0xce, 0x81, 0xbc, 0x4e, 0x94,
- 0xd0, 0xc9, 0xd3, 0x46, 0x36, 0x7e, 0xbd, 0x68, 0x79, 0x7d, 0x80, 0xce,
- 0x67, 0xe2, 0xf1, 0x18, 0x39, 0xd1, 0xad, 0xe3, 0x4c, 0x41, 0xc7, 0x9b,
- 0x21, 0x73, 0x46, 0x75, 0xa1, 0xc6, 0x40, 0x01, 0x8a, 0x0a, 0xc7, 0x1c,
- 0x11, 0x19, 0x5c, 0x44, 0x5c, 0x41, 0x1c, 0x1e, 0x5c, 0x47, 0x74, 0x3b,
- 0x41, 0x78, 0x25, 0xd1, 0x13, 0x11, 0x69, 0x3b, 0xc1, 0xfb, 0x10, 0xd9,
- 0x89, 0x7e, 0x8c, 0x38, 0x07, 0xa3, 0x78, 0x4e, 0xe1, 0x6f, 0x0f, 0x6a,
- 0x2b, 0x13, 0x35, 0xf2, 0x16, 0xf0, 0x80, 0xe5, 0x9e, 0xad, 0xe0, 0xbb,
- 0xfb, 0xa4, 0x2b, 0x86, 0x3d, 0x84, 0x8f, 0x82, 0x8e, 0x9d, 0xa0, 0xc7,
- 0x3b, 0x9f, 0x38, 0xa2, 0x27, 0x44, 0x86, 0x16, 0xa5, 0x5f, 0xe9, 0x3d,
- 0x51, 0x29, 0x66, 0xb8, 0xd6, 0x0d, 0x78, 0xee, 0xc3, 0x9a, 0xde, 0xe7,
- 0xdd, 0x2b, 0x15, 0x6e, 0xd2, 0x8d, 0x39, 0x03, 0xef, 0xa8, 0xa7, 0x32,
- 0xa6, 0x0c, 0xd5, 0x3d, 0xd8, 0xc1, 0xf5, 0x43, 0x78, 0x92, 0x57, 0x8f,
- 0x36, 0x85, 0x9a, 0xb8, 0x00, 0xa9, 0x46, 0x47, 0x78, 0x3f, 0x43, 0x18,
- 0xf6, 0xb5, 0xdd, 0x1a, 0xc6, 0x1c, 0xa1, 0xfc, 0xbc, 0x39, 0xa5, 0xfe,
- 0xb7, 0x7b, 0x97, 0xd6, 0x9a, 0x42, 0xfb, 0x0a, 0xf6, 0x7f, 0x45, 0xfb,
- 0x8a, 0xa8, 0xa4, 0xef, 0x2b, 0xf8, 0x5e, 0xe1, 0x77, 0x90, 0x8b, 0x7f,
- 0xed, 0x0e, 0x2f, 0xde, 0xbb, 0x32, 0x67, 0xf3, 0x0e, 0xc3, 0x95, 0x8b,
- 0x76, 0xc9, 0x78, 0xf0, 0x96, 0x3a, 0x33, 0xad, 0xf3, 0x73, 0x11, 0xb2,
- 0xbf, 0xdc, 0xd0, 0x3d, 0x9b, 0x5c, 0x6a, 0xc4, 0xe4, 0xca, 0x6a, 0x97,
- 0x5c, 0x5e, 0xf6, 0x6c, 0xfe, 0xf2, 0x32, 0xed, 0xdc, 0x94, 0xef, 0xad,
- 0x5a, 0x58, 0x4b, 0xe3, 0xaf, 0x5f, 0xde, 0x59, 0xbd, 0xb5, 0xee, 0x3c,
- 0xdf, 0x7c, 0x00, 0xb4, 0xf4, 0x4b, 0xc4, 0x72, 0x75, 0xff, 0x95, 0x47,
- 0xee, 0x2b, 0xc9, 0x94, 0x14, 0xaa, 0x43, 0xe8, 0x01, 0x91, 0x9c, 0xa3,
- 0xcc, 0x41, 0xd0, 0x7f, 0xf5, 0x33, 0xa8, 0x4d, 0x52, 0x70, 0x9e, 0x21,
- 0x7d, 0x8f, 0xf8, 0x33, 0xd1, 0x7e, 0x69, 0xb7, 0xbe, 0xdc, 0xe7, 0xe5,
- 0x2a, 0xd3, 0xeb, 0x53, 0xad, 0x20, 0x5f, 0xbf, 0x0e, 0xdc, 0xe3, 0xb0,
- 0x53, 0xda, 0xa6, 0x0d, 0x9b, 0x35, 0x65, 0x6d, 0x34, 0x55, 0x2b, 0x09,
- 0xe3, 0x43, 0x06, 0x67, 0x7e, 0x08, 0x9e, 0xd3, 0x90, 0x47, 0xa7, 0xae,
- 0x85, 0x72, 0x0a, 0xba, 0x5d, 0x9c, 0x97, 0x42, 0xf3, 0x57, 0x80, 0x2f,
- 0x27, 0xb3, 0xcd, 0x49, 0x9c, 0x75, 0x1c, 0x76, 0x3b, 0xda, 0x2f, 0x5d,
- 0x3c, 0x27, 0x03, 0x1a, 0xef, 0x97, 0xe2, 0xc9, 0x79, 0x39, 0x58, 0x25,
- 0x9d, 0xc8, 0x25, 0x76, 0x2a, 0x9d, 0x97, 0xb1, 0xe4, 0x2a, 0x6a, 0x27,
- 0xcf, 0x1f, 0xb3, 0x52, 0x3c, 0x05, 0x1c, 0x55, 0xde, 0x03, 0x0c, 0xc1,
- 0x6e, 0xc6, 0x74, 0x5f, 0x33, 0xab, 0xe3, 0x0e, 0xe7, 0xdf, 0x84, 0x9e,
- 0x86, 0x4a, 0x7b, 0x00, 0x57, 0x40, 0x0f, 0x34, 0x83, 0x7a, 0x79, 0xa5,
- 0x8a, 0x7e, 0xcf, 0x8e, 0xb0, 0xf6, 0x52, 0xea, 0x9e, 0x01, 0xa9, 0x57,
- 0xc7, 0x4c, 0xa5, 0x58, 0x53, 0x51, 0x17, 0x5c, 0xa3, 0x7f, 0x27, 0x54,
- 0xd4, 0x1a, 0x90, 0xd5, 0x6a, 0x09, 0x7d, 0xb3, 0xf2, 0xef, 0x35, 0x4a,
- 0x62, 0x5a, 0x5e, 0xdc, 0xcb, 0x29, 0xf2, 0x8d, 0xfa, 0xb3, 0xf9, 0x59,
- 0xd0, 0x98, 0x4b, 0x9a, 0x72, 0x14, 0xf4, 0xe1, 0x7d, 0x05, 0x36, 0xbe,
- 0xc8, 0x1a, 0x2e, 0x87, 0xb5, 0xac, 0x1c, 0x3e, 0x33, 0x03, 0x1a, 0x7a,
- 0x65, 0xe8, 0x77, 0xe9, 0x63, 0x07, 0x30, 0xc7, 0xef, 0x14, 0xec, 0xf5,
- 0x31, 0xbc, 0x13, 0x36, 0x81, 0x27, 0xe5, 0x30, 0x80, 0xa7, 0x09, 0x5a,
- 0x62, 0x5e, 0x6f, 0xb2, 0x3f, 0x29, 0xf5, 0x93, 0xf7, 0xc9, 0xec, 0xca,
- 0x7d, 0xc0, 0xff, 0x36, 0xfa, 0x02, 0xe4, 0xb7, 0x15, 0x9e, 0xc5, 0xfa,
- 0x8f, 0xe7, 0x74, 0xf4, 0x6b, 0xdf, 0x58, 0xe4, 0x3c, 0x9f, 0xfb, 0xb0,
- 0x1f, 0x3d, 0x46, 0x35, 0x27, 0xc5, 0x2a, 0xcf, 0x82, 0xee, 0x50, 0x4f,
- 0x15, 0x4e, 0xce, 0xf8, 0x3a, 0xee, 0x97, 0x7c, 0xbc, 0xc4, 0xfe, 0x02,
- 0x79, 0x62, 0x79, 0xc2, 0xa9, 0xa4, 0x4c, 0x47, 0x11, 0x57, 0x5a, 0x98,
- 0x1b, 0xbc, 0xb9, 0x98, 0x58, 0x8b, 0xe8, 0x6d, 0xb3, 0x5c, 0x3b, 0xea,
- 0xdf, 0x1d, 0x10, 0xd7, 0x5b, 0x32, 0x05, 0x1b, 0x1b, 0x5a, 0x1c, 0x47,
- 0x2d, 0xfc, 0x5d, 0xd4, 0x92, 0x77, 0xfa, 0x32, 0x98, 0xf4, 0x6d, 0xa3,
- 0xab, 0xc5, 0x26, 0xa0, 0xe7, 0x2a, 0x74, 0x5f, 0x85, 0x1d, 0x20, 0x56,
- 0xbf, 0x74, 0xc3, 0x3e, 0x26, 0x5b, 0x6a, 0xcc, 0x1e, 0xf9, 0x8b, 0x5a,
- 0x2a, 0xbd, 0x01, 0xfb, 0x79, 0x07, 0xbd, 0xc0, 0x06, 0x7a, 0xd5, 0xcb,
- 0xe8, 0xeb, 0x56, 0x2a, 0xfb, 0x41, 0x3f, 0x6b, 0x4a, 0x7e, 0x27, 0x74,
- 0xad, 0xd3, 0x61, 0x1d, 0xbb, 0x43, 0xdf, 0xed, 0xca, 0xfe, 0x7e, 0xf6,
- 0x9a, 0xec, 0xcb, 0x79, 0x0f, 0x7d, 0x05, 0x7a, 0xdc, 0x30, 0xb9, 0x1e,
- 0xec, 0x63, 0x2f, 0x10, 0xd8, 0x0f, 0x69, 0xa1, 0xfd, 0x70, 0x0f, 0x61,
- 0xfa, 0xb5, 0x9f, 0x14, 0x34, 0x3e, 0xda, 0xec, 0x8b, 0x7d, 0x9e, 0x9f,
- 0xe9, 0x3a, 0xcb, 0xbc, 0x24, 0x81, 0xfd, 0xbe, 0xef, 0xb2, 0xaf, 0x73,
- 0x46, 0x11, 0xbb, 0x9b, 0xae, 0x3c, 0x67, 0xdf, 0xea, 0x77, 0x7b, 0xab,
- 0x81, 0x9c, 0x28, 0xc7, 0xfd, 0x72, 0xac, 0x99, 0x82, 0x4f, 0x50, 0x86,
- 0x56, 0x8b, 0x0c, 0x45, 0xfe, 0xa8, 0x2a, 0xf2, 0x62, 0x95, 0x6b, 0x5a,
- 0x86, 0x09, 0x27, 0xd2, 0xa5, 0xef, 0xd2, 0x0b, 0xf2, 0x1d, 0x39, 0xb8,
- 0x24, 0x72, 0x06, 0xeb, 0x6b, 0x55, 0xfa, 0xea, 0x38, 0xea, 0xd7, 0x6d,
- 0x52, 0x5f, 0x46, 0x4f, 0x56, 0x95, 0x59, 0xe7, 0x5e, 0xe6, 0x9b, 0x98,
- 0x5c, 0xd6, 0x77, 0xb2, 0x22, 0x23, 0x67, 0xa3, 0x12, 0x3d, 0x8b, 0xe6,
- 0x0f, 0xb2, 0x3f, 0x37, 0x1a, 0xdc, 0xd1, 0x7a, 0x3e, 0x5f, 0xae, 0x60,
- 0x6f, 0x75, 0x48, 0xc7, 0xc9, 0x72, 0xa3, 0x28, 0x85, 0x1a, 0xcf, 0xc2,
- 0x73, 0x39, 0x89, 0xb5, 0x8c, 0xcc, 0x9d, 0x1c, 0x97, 0xa7, 0x71, 0x06,
- 0xfa, 0x3f, 0x9c, 0x31, 0x25, 0xa5, 0x33, 0x98, 0x6f, 0x5c, 0x95, 0xe5,
- 0xd5, 0xa2, 0xd4, 0x6b, 0xe7, 0x5d, 0xaf, 0x8f, 0x20, 0x3e, 0x7c, 0x2f,
- 0xb7, 0xf6, 0xb2, 0xfb, 0xd9, 0xcf, 0xa0, 0x57, 0xb5, 0xf0, 0x0d, 0x99,
- 0x35, 0xe6, 0x66, 0x6f, 0xbd, 0x33, 0x6e, 0xed, 0x61, 0xa7, 0x65, 0xa1,
- 0x9a, 0x91, 0xf2, 0xc9, 0x71, 0x7d, 0xd7, 0xd0, 0x91, 0x3d, 0xfc, 0xc4,
- 0x35, 0xe4, 0x8a, 0x69, 0x7d, 0x67, 0x7c, 0x5d, 0x1e, 0xb2, 0x17, 0xe4,
- 0x90, 0xb5, 0x4f, 0x8e, 0xa1, 0xbe, 0xfe, 0x1c, 0x7a, 0xfd, 0x64, 0x1f,
- 0xf5, 0x08, 0x7a, 0x2d, 0xf6, 0xa0, 0xae, 0x4c, 0xd9, 0x9f, 0x36, 0x9f,
- 0x65, 0x97, 0xd0, 0x60, 0x9e, 0xfc, 0x2f, 0x37, 0x87, 0xbc, 0x77, 0x0d,
- 0xbd, 0x63, 0x4e, 0xc3, 0x19, 0x1e, 0x5c, 0x8d, 0x70, 0x63, 0xe6, 0x73,
- 0x84, 0x5b, 0x36, 0x7c, 0x38, 0x03, 0x70, 0x11, 0xb9, 0x60, 0x47, 0x61,
- 0x23, 0xd3, 0xe0, 0x13, 0x31, 0x7e, 0xa2, 0xc7, 0xaf, 0x83, 0x3b, 0x91,
- 0x5b, 0x6f, 0xee, 0x7f, 0xd5, 0xdf, 0xff, 0xb4, 0xbf, 0xff, 0xe2, 0x8d,
- 0xfd, 0x41, 0x7e, 0xfd, 0xd0, 0x95, 0x16, 0xba, 0x5e, 0xad, 0x78, 0xf0,
- 0x0b, 0x3e, 0x5d, 0x17, 0x6f, 0xd0, 0x15, 0xc0, 0x43, 0x9e, 0x9a, 0x67,
- 0xc6, 0x66, 0xc6, 0xe8, 0x21, 0xc8, 0xd1, 0x95, 0xbc, 0x0d, 0xdf, 0xa8,
- 0xa6, 0x26, 0x4b, 0xfa, 0x4e, 0x4d, 0xc9, 0x46, 0x7c, 0x41, 0xa6, 0xad,
- 0xd4, 0xe4, 0x9c, 0x44, 0x60, 0xcb, 0x8c, 0x2d, 0x11, 0xa9, 0x33, 0xe6,
- 0xe0, 0x59, 0xb0, 0xb7, 0xa6, 0xf5, 0x4a, 0x0b, 0xad, 0x91, 0x17, 0x48,
- 0xa3, 0x47, 0x6b, 0x6c, 0xf8, 0x26, 0xad, 0x1e, 0xbc, 0x47, 0xeb, 0x95,
- 0x4a, 0x0b, 0xfc, 0xd9, 0xa8, 0x0f, 0x1f, 0x6d, 0x81, 0xa7, 0x3d, 0xb3,
- 0xae, 0xa0, 0x3d, 0x93, 0xb6, 0x9f, 0x80, 0x6f, 0x48, 0xac, 0x33, 0x7b,
- 0xf8, 0xc8, 0xdd, 0xc3, 0xae, 0xc4, 0x50, 0x6f, 0xb4, 0x63, 0xed, 0x72,
- 0x8d, 0xb5, 0x88, 0x1a, 0x6c, 0x97, 0x11, 0xd8, 0x2c, 0x75, 0xe7, 0xdd,
- 0x0d, 0x3e, 0xa4, 0x6b, 0x02, 0x57, 0x0e, 0xd9, 0xa4, 0xe5, 0x3f, 0xdd,
- 0x17, 0xe3, 0x23, 0x76, 0x59, 0x46, 0xcd, 0x76, 0x9c, 0x5f, 0x6f, 0x6a,
- 0x9c, 0x69, 0xd2, 0x72, 0x7a, 0x74, 0xc8, 0xfc, 0x73, 0xf0, 0x39, 0x55,
- 0x33, 0xa4, 0x6e, 0xa5, 0x12, 0xe7, 0x80, 0x63, 0x0f, 0x74, 0x53, 0x1f,
- 0x27, 0x3d, 0x22, 0x07, 0x61, 0xdf, 0x75, 0x9d, 0x17, 0x69, 0xc7, 0xa9,
- 0xe9, 0x12, 0x6a, 0x9d, 0x3f, 0xd6, 0xb9, 0xcd, 0x75, 0xaf, 0x21, 0xbf,
- 0x4d, 0x6f, 0xb2, 0x3d, 0x75, 0xd6, 0xb3, 0x3d, 0x75, 0x16, 0x3d, 0xf0,
- 0xf1, 0x98, 0x74, 0xac, 0xc1, 0x7f, 0x5e, 0xd8, 0xe9, 0xd5, 0x73, 0x2f,
- 0x24, 0x8d, 0xfc, 0x49, 0xc4, 0xbb, 0xe3, 0x51, 0xb1, 0x8e, 0xeb, 0x7c,
- 0x00, 0x79, 0x4f, 0xc9, 0xdc, 0x29, 0xc6, 0x54, 0x4b, 0x86, 0x8f, 0x53,
- 0x1f, 0xac, 0x6b, 0x96, 0x27, 0x8a, 0xf0, 0x91, 0x79, 0xc4, 0x05, 0xb5,
- 0xf6, 0xae, 0x14, 0x2d, 0xca, 0xa1, 0x57, 0xba, 0xd6, 0xd0, 0x8f, 0xaf,
- 0x21, 0x36, 0xac, 0x25, 0xa4, 0x0d, 0xbe, 0xa5, 0xce, 0xc6, 0x8d, 0xf2,
- 0xd2, 0x0f, 0xe1, 0x0f, 0xfc, 0x0d, 0x07, 0xb5, 0xe5, 0xd9, 0x84, 0x41,
- 0xdf, 0x52, 0x67, 0x69, 0xe7, 0x28, 0xa7, 0xce, 0xd2, 0xce, 0x49, 0x47,
- 0xe0, 0x2f, 0x78, 0x3f, 0x3b, 0xae, 0xef, 0xa9, 0xaf, 0xd9, 0xe4, 0xe5,
- 0x6f, 0xc4, 0xa9, 0xb1, 0x46, 0x24, 0x3f, 0xd2, 0x87, 0x5a, 0x66, 0xbb,
- 0x63, 0x0f, 0x4f, 0x5e, 0x96, 0x4f, 0xca, 0xd7, 0xed, 0x9f, 0x80, 0x2f,
- 0xf2, 0xd1, 0xca, 0x17, 0x79, 0xea, 0x95, 0x36, 0xcd, 0x57, 0xc0, 0x0f,
- 0x04, 0x0d, 0x7e, 0x06, 0x8f, 0x27, 0x80, 0xff, 0x31, 0xc4, 0x80, 0x01,
- 0x3c, 0x0f, 0xe0, 0x89, 0x94, 0x76, 0x96, 0xbc, 0x93, 0xd7, 0x77, 0x50,
- 0x37, 0x06, 0x7c, 0xce, 0xe2, 0xfd, 0x15, 0x99, 0x5b, 0x72, 0x8f, 0x22,
- 0xaf, 0xf2, 0x0e, 0xbd, 0xdf, 0xbb, 0x0f, 0xde, 0xcc, 0xfb, 0x2b, 0xe2,
- 0xc9, 0x27, 0x65, 0xd6, 0x05, 0xef, 0xab, 0x9b, 0x65, 0xd1, 0x1a, 0x3b,
- 0x12, 0xba, 0x0e, 0x3f, 0xd8, 0x60, 0x9c, 0xa0, 0x8c, 0xde, 0x11, 0x67,
- 0x89, 0xf7, 0x5f, 0x1e, 0xbe, 0xd9, 0x46, 0x10, 0x37, 0x5a, 0xf7, 0xd8,
- 0x80, 0x1b, 0x00, 0x1c, 0xe9, 0xda, 0xa0, 0xfc, 0x10, 0x73, 0x76, 0xb5,
- 0xc4, 0x9a, 0xd6, 0x7d, 0x93, 0xf2, 0x0c, 0xea, 0x80, 0x57, 0xed, 0x5b,
- 0xe4, 0x3a, 0xcb, 0x5a, 0xa8, 0xde, 0x98, 0x81, 0x4f, 0xb6, 0x21, 0x96,
- 0x99, 0x72, 0xb9, 0xd2, 0x2e, 0x75, 0xd4, 0x3b, 0x2b, 0xab, 0x8c, 0x85,
- 0xa4, 0xbd, 0x0b, 0xf3, 0x5e, 0xfc, 0x62, 0xac, 0xbd, 0x5c, 0x41, 0x9e,
- 0x85, 0x6f, 0x5f, 0xae, 0xc4, 0xf1, 0x1c, 0xc0, 0xd3, 0xc2, 0x33, 0x89,
- 0x67, 0x1a, 0xcf, 0x71, 0x3c, 0xc7, 0xf1, 0xb4, 0xb0, 0x37, 0x81, 0x67,
- 0xd0, 0x33, 0x10, 0xd7, 0x4d, 0xbe, 0xcb, 0xfa, 0x3c, 0xd4, 0x8a, 0x16,
- 0x73, 0x5a, 0xd4, 0xce, 0xa3, 0x8f, 0x70, 0xc6, 0x75, 0xad, 0x87, 0xfc,
- 0xf6, 0x91, 0x6b, 0x5a, 0xec, 0xcb, 0x4b, 0xc6, 0x9e, 0x51, 0xe6, 0x85,
- 0x1a, 0xf2, 0xc2, 0x7f, 0xec, 0x40, 0xff, 0x68, 0xee, 0xd5, 0x77, 0x47,
- 0x4b, 0xf8, 0xe6, 0x3b, 0x7a, 0xde, 0xf8, 0x3c, 0xf2, 0x14, 0xe3, 0xa7,
- 0x8b, 0x3d, 0x05, 0xc4, 0xf1, 0xed, 0xf0, 0xbf, 0x1c, 0xe2, 0x36, 0xde,
- 0x97, 0x37, 0x76, 0x78, 0x39, 0x15, 0xf5, 0xbb, 0xda, 0x7c, 0x5f, 0x63,
- 0x63, 0xcf, 0x56, 0xbd, 0x41, 0x0f, 0x70, 0xa4, 0x6a, 0xcb, 0xf0, 0xc1,
- 0x37, 0xed, 0xa3, 0xba, 0xb6, 0xa3, 0x2e, 0x9e, 0x46, 0x8d, 0x9a, 0x5f,
- 0x64, 0x0d, 0xf3, 0x14, 0xfa, 0x12, 0xf4, 0x67, 0x71, 0xf6, 0xe4, 0xcc,
- 0x05, 0xba, 0x16, 0x8d, 0x4b, 0x17, 0xf3, 0xc0, 0x15, 0x9c, 0x07, 0xbe,
- 0x56, 0x5c, 0xc8, 0xec, 0x41, 0xd4, 0x84, 0xae, 0x1b, 0xb5, 0xf6, 0x48,
- 0xf2, 0x11, 0xc6, 0x1c, 0xc1, 0x7e, 0x53, 0xbc, 0x7b, 0x75, 0xc4, 0xdd,
- 0x19, 0xfd, 0xfb, 0x30, 0x8c, 0x6b, 0x1c, 0x7b, 0x6f, 0x13, 0xef, 0xb7,
- 0x5c, 0xde, 0x69, 0x8b, 0xec, 0x59, 0xf4, 0x6a, 0x5a, 0x65, 0xb5, 0xe2,
- 0xfb, 0x49, 0x1f, 0x1f, 0xd7, 0x95, 0xff, 0xdb, 0xc6, 0x4e, 0xc8, 0x08,
- 0xfe, 0x00, 0x1d, 0x1f, 0x43, 0xfd, 0x7c, 0x01, 0x7a, 0x79, 0x15, 0x3a,
- 0x79, 0xad, 0x42, 0x5b, 0x1f, 0x83, 0xdd, 0x43, 0x86, 0x33, 0xfa, 0x0c,
- 0x7d, 0xf6, 0x85, 0x0a, 0x62, 0x27, 0xe3, 0x9f, 0xfa, 0x52, 0x9c, 0xf5,
- 0x21, 0xf3, 0xa0, 0x87, 0x67, 0xc0, 0x83, 0x93, 0x60, 0x6d, 0x87, 0xa6,
- 0xa7, 0xae, 0xef, 0xc1, 0x28, 0x27, 0xd8, 0x20, 0x7f, 0x23, 0xd0, 0x30,
- 0x5f, 0x8c, 0xeb, 0x7b, 0x78, 0xc5, 0x39, 0xf2, 0x31, 0x2e, 0xce, 0x62,
- 0xb0, 0xaf, 0x0f, 0xfb, 0x3a, 0x5b, 0x70, 0xdd, 0xbe, 0x89, 0x07, 0xe5,
- 0xf3, 0xc0, 0xf5, 0xcd, 0x75, 0x7f, 0xca, 0x2c, 0xdd, 0xb8, 0x1b, 0x66,
- 0xfe, 0xa5, 0x6e, 0x32, 0xd8, 0x1f, 0xe8, 0x67, 0xc0, 0xef, 0x05, 0x52,
- 0x0b, 0xe8, 0x23, 0x20, 0x7f, 0xea, 0x68, 0x92, 0xf1, 0x09, 0xf8, 0x6d,
- 0xa9, 0x55, 0x3a, 0x44, 0xf5, 0xb3, 0x37, 0x66, 0xad, 0xdc, 0x7a, 0xe6,
- 0x2f, 0xfa, 0x67, 0xa2, 0x9f, 0x3e, 0xc1, 0xba, 0x59, 0xe7, 0x19, 0xc0,
- 0x74, 0x6f, 0xa2, 0xed, 0xe7, 0x7c, 0x38, 0xae, 0xa7, 0xa5, 0x84, 0x3a,
- 0x34, 0xbf, 0x88, 0x8a, 0x1e, 0xf1, 0x5b, 0x65, 0xf9, 0xbb, 0x16, 0xef,
- 0xf0, 0xc6, 0x92, 0x73, 0xa0, 0xb1, 0x64, 0xe6, 0x78, 0x6f, 0x06, 0x1c,
- 0xbb, 0x36, 0xe1, 0x98, 0xf2, 0x71, 0x4c, 0x49, 0xf9, 0xd4, 0x34, 0x7c,
- 0x2d, 0x87, 0xfc, 0x3e, 0x64, 0x3e, 0x28, 0x9f, 0x41, 0x73, 0x8d, 0xb9,
- 0x33, 0xe3, 0xd0, 0x93, 0xeb, 0xee, 0xb1, 0xf7, 0x83, 0xee, 0x97, 0x91,
- 0x5b, 0x83, 0x9a, 0xa7, 0x9c, 0x88, 0x20, 0x87, 0x1d, 0xd6, 0xbf, 0xc3,
- 0x96, 0x4c, 0x13, 0xf6, 0xaa, 0x8c, 0xb1, 0x34, 0xda, 0x7b, 0xe4, 0xb7,
- 0x05, 0xe4, 0x2a, 0xf2, 0xd9, 0x23, 0x65, 0xd3, 0x78, 0x20, 0x82, 0xba,
- 0xc6, 0x59, 0xa4, 0x1f, 0xc9, 0x70, 0x24, 0xdb, 0x8e, 0x9a, 0xd4, 0x95,
- 0xef, 0xd9, 0xfc, 0x77, 0x09, 0x0b, 0x72, 0xa1, 0x61, 0xe2, 0x79, 0x0e,
- 0x7a, 0xf8, 0x3d, 0xbc, 0xff, 0x53, 0x3f, 0xea, 0x3e, 0xac, 0xe4, 0x60,
- 0xbb, 0x69, 0x5d, 0xcf, 0xb0, 0x8e, 0xa8, 0x23, 0xdf, 0x2a, 0xe4, 0x1a,
- 0xd4, 0x55, 0x93, 0xac, 0x5d, 0x9f, 0x59, 0xb9, 0x2a, 0xaf, 0x2d, 0xf1,
- 0x77, 0x50, 0xe6, 0xe5, 0x7d, 0x8c, 0x07, 0xe6, 0x7c, 0x06, 0x73, 0xab,
- 0x8c, 0x65, 0xf8, 0x6e, 0xc2, 0x81, 0xfa, 0x51, 0x23, 0xa0, 0xd6, 0xbe,
- 0x6c, 0xa5, 0xc1, 0xe7, 0x55, 0xb9, 0xb0, 0x14, 0x95, 0x15, 0x8b, 0x75,
- 0x91, 0x24, 0x1d, 0xc0, 0x5e, 0x58, 0xfd, 0x07, 0xcf, 0x26, 0x08, 0x8f,
- 0x9e, 0xa7, 0x84, 0xba, 0xee, 0x41, 0xbd, 0xf7, 0x47, 0xe9, 0x99, 0x34,
- 0xb5, 0xf6, 0x79, 0x45, 0xb9, 0x40, 0x7f, 0xd2, 0xbf, 0x51, 0xb0, 0x36,
- 0x78, 0x0a, 0x36, 0xcb, 0xda, 0x9d, 0xfd, 0x00, 0xde, 0x1b, 0x5c, 0x27,
- 0xef, 0x78, 0x2e, 0x0f, 0x41, 0x36, 0xf4, 0x7b, 0xde, 0x89, 0x21, 0x8f,
- 0x2a, 0xfa, 0x7a, 0x59, 0xc7, 0x82, 0x72, 0xb5, 0x88, 0x9c, 0x82, 0x18,
- 0x60, 0xef, 0x82, 0x2d, 0xce, 0x40, 0x97, 0x93, 0x80, 0xdb, 0x94, 0x4b,
- 0xd6, 0xcb, 0xba, 0x2e, 0x53, 0xa7, 0x6f, 0xde, 0xdf, 0x14, 0xe0, 0x3f,
- 0x6a, 0x1d, 0xb6, 0x05, 0x1f, 0x52, 0xeb, 0x71, 0x3c, 0x11, 0x8f, 0xd7,
- 0xd1, 0x5f, 0x54, 0x78, 0x3f, 0x84, 0xde, 0xa0, 0xc2, 0xbb, 0x93, 0x34,
- 0x9e, 0xe3, 0xbc, 0x2f, 0xf2, 0xe3, 0x1a, 0xf1, 0x93, 0x8e, 0x20, 0xbe,
- 0xb0, 0x96, 0x64, 0x7c, 0x09, 0xea, 0x49, 0xcf, 0x16, 0x8e, 0x55, 0x19,
- 0x43, 0x68, 0xd7, 0x43, 0x88, 0x5b, 0xb4, 0x05, 0xaf, 0x96, 0x5c, 0xad,
- 0x79, 0x32, 0x9b, 0x6b, 0x9e, 0xd7, 0x39, 0x62, 0xaf, 0x58, 0xb0, 0x31,
- 0xca, 0x0e, 0x6b, 0x3a, 0x07, 0x9c, 0x93, 0x9c, 0x7e, 0x52, 0x66, 0xaf,
- 0x48, 0x6e, 0x75, 0x5c, 0x9e, 0xd3, 0x71, 0x2b, 0x88, 0x59, 0xac, 0x21,
- 0xf9, 0xfb, 0x71, 0x5a, 0x9e, 0x3d, 0x79, 0x55, 0x9c, 0xe7, 0x19, 0xb7,
- 0xc6, 0x12, 0x9d, 0x06, 0x63, 0x95, 0x2b, 0x0d, 0xe4, 0xa6, 0x07, 0x6d,
- 0xfe, 0x5b, 0x80, 0x08, 0x7a, 0x3a, 0x57, 0xda, 0x27, 0x52, 0x76, 0xd2,
- 0x18, 0x3a, 0xd0, 0x69, 0x30, 0x37, 0x8e, 0x99, 0x8f, 0x4b, 0x70, 0x1f,
- 0xd5, 0x21, 0x8f, 0xeb, 0xbb, 0x0a, 0xb8, 0xed, 0xe2, 0x07, 0xfa, 0x77,
- 0x94, 0x6b, 0x19, 0xca, 0x1a, 0xdf, 0xeb, 0x9c, 0x2f, 0xc5, 0xae, 0x65,
- 0xda, 0xa4, 0x7c, 0x9b, 0xeb, 0x1e, 0x9a, 0x98, 0xd8, 0xe1, 0xfd, 0x7b,
- 0x91, 0x23, 0xb7, 0x79, 0xb1, 0xa0, 0xe0, 0x7f, 0xaf, 0xe1, 0x49, 0xdb,
- 0x66, 0xbe, 0x65, 0x7e, 0xa4, 0xde, 0xf0, 0x5c, 0xe5, 0x3b, 0x73, 0xef,
- 0x02, 0x72, 0x2f, 0xf3, 0xe5, 0x76, 0xc9, 0xf3, 0x77, 0x3e, 0xa5, 0xe7,
- 0x4b, 0x5e, 0x2d, 0xed, 0xc3, 0xd5, 0x66, 0x65, 0xae, 0xc6, 0x1a, 0xea,
- 0x02, 0x72, 0xd9, 0x28, 0x6c, 0x95, 0x39, 0xed, 0x28, 0xf2, 0x39, 0x7f,
- 0x9f, 0xc6, 0xda, 0x32, 0xf7, 0xa5, 0xd2, 0x49, 0xd5, 0xfa, 0xbb, 0xd2,
- 0xd5, 0x38, 0xef, 0xa3, 0xce, 0x8d, 0x42, 0xef, 0xbf, 0xc3, 0xde, 0x62,
- 0x58, 0xdb, 0x88, 0xf3, 0x02, 0x65, 0xef, 0xfd, 0x7e, 0x2d, 0x7d, 0x9e,
- 0x0f, 0xb0, 0x0e, 0xf8, 0x3c, 0xe4, 0xb2, 0xd7, 0xbe, 0xca, 0xdc, 0xfd,
- 0x6f, 0xca, 0x1a, 0x4b, 0x3f, 0x6e, 0xd0, 0xb7, 0xf1, 0xbd, 0x1a, 0x91,
- 0xe5, 0x38, 0xf9, 0x87, 0xbc, 0x0c, 0xfa, 0xce, 0x56, 0x72, 0xd8, 0x2c,
- 0x83, 0x3f, 0x80, 0x0c, 0x28, 0xcb, 0x40, 0x06, 0x7c, 0x9f, 0x86, 0xbe,
- 0xd8, 0x33, 0x0c, 0xe9, 0x3e, 0xb2, 0xdc, 0xf4, 0xce, 0x2e, 0x57, 0x5b,
- 0x69, 0x26, 0xbd, 0xd4, 0xe9, 0x39, 0xc9, 0x6b, 0xfd, 0x2e, 0x48, 0xbe,
- 0x76, 0x4e, 0xf6, 0xd4, 0x16, 0xe4, 0x21, 0xeb, 0x01, 0xf0, 0x7b, 0xc9,
- 0x2d, 0x5a, 0xba, 0x57, 0x99, 0x2c, 0xe0, 0xec, 0xe2, 0xff, 0x74, 0x6e,
- 0xb5, 0xbf, 0x6d, 0x55, 0x67, 0xfc, 0xf1, 0xb5, 0x9d, 0xa4, 0xa1, 0x09,
- 0xb7, 0xae, 0x93, 0xb8, 0x69, 0x0a, 0x76, 0x7c, 0xdb, 0x46, 0x24, 0xad,
- 0x6e, 0x43, 0x46, 0xa3, 0x2e, 0x53, 0x4c, 0x12, 0xba, 0x74, 0xeb, 0x44,
- 0xda, 0x75, 0x5d, 0x37, 0xd0, 0x64, 0x9c, 0xb4, 0x14, 0x98, 0x54, 0x28,
- 0xac, 0x43, 0x08, 0xa9, 0xc6, 0x6d, 0x35, 0xa6, 0xa5, 0x71, 0xfa, 0x46,
- 0x10, 0x5f, 0xb0, 0x92, 0xb4, 0x65, 0x52, 0x84, 0x5b, 0x04, 0xdb, 0x3e,
- 0xb0, 0xd1, 0xa5, 0x8c, 0x3f, 0x60, 0xfb, 0x30, 0x26, 0xb1, 0x29, 0x2b,
- 0xb0, 0xb1, 0x7d, 0xea, 0x07, 0x26, 0x75, 0xda, 0x8a, 0xf7, 0xfb, 0x3d,
- 0xe7, 0x5e, 0xc7, 0x36, 0x41, 0x48, 0x8b, 0x14, 0xf9, 0x9e, 0x97, 0x7b,
- 0xee, 0xb9, 0xe7, 0x79, 0x7f, 0x9e, 0xdf, 0xed, 0x59, 0x27, 0x9f, 0xc0,
- 0xef, 0x38, 0x35, 0x67, 0x4b, 0xda, 0xee, 0x97, 0x9f, 0x6a, 0x2e, 0x9f,
- 0xf1, 0x49, 0x00, 0x3e, 0xa9, 0xc1, 0x16, 0x48, 0x8b, 0x13, 0xbb, 0x21,
- 0xf4, 0x29, 0xc3, 0xa0, 0x75, 0xdc, 0xf8, 0xcd, 0xb6, 0x19, 0xdf, 0x74,
- 0x06, 0xbe, 0xbb, 0xbb, 0xad, 0xc5, 0xcf, 0xf9, 0x1a, 0xff, 0xf6, 0x7d,
- 0xaf, 0x86, 0xd6, 0x2f, 0xd3, 0xd8, 0xcf, 0x9b, 0xaa, 0x67, 0x1d, 0xf0,
- 0x12, 0x73, 0xd3, 0x31, 0xcd, 0x3f, 0x84, 0xa7, 0xa8, 0xa3, 0xae, 0x40,
- 0x47, 0x0d, 0x50, 0x77, 0x0d, 0xce, 0xb9, 0xcc, 0x0f, 0x44, 0xe5, 0x0f,
- 0x93, 0xd4, 0xc3, 0x71, 0xf9, 0xfd, 0xe4, 0xb3, 0xd8, 0x4f, 0xa2, 0xc0,
- 0x1c, 0xe5, 0xf5, 0xe9, 0xac, 0x62, 0x92, 0x86, 0xd5, 0x07, 0x7e, 0x5a,
- 0xed, 0x40, 0xdc, 0xca, 0xad, 0x0d, 0xab, 0xbe, 0x39, 0xa2, 0xb5, 0xdd,
- 0xb8, 0xd5, 0x21, 0xd7, 0xcf, 0x1b, 0x1d, 0x1b, 0x9e, 0x8a, 0x06, 0x86,
- 0xe7, 0x69, 0x97, 0x92, 0xb1, 0x8c, 0x55, 0x2f, 0x07, 0xa3, 0xcc, 0x3d,
- 0xa7, 0xa8, 0x9f, 0x61, 0x0b, 0xbb, 0xed, 0x8c, 0xd5, 0xe0, 0xd9, 0x9f,
- 0x58, 0x8d, 0x9e, 0x3d, 0xe2, 0xe9, 0x59, 0x8e, 0xa5, 0x40, 0x53, 0xda,
- 0xa2, 0xc4, 0xf4, 0x88, 0x95, 0x84, 0xcd, 0xc3, 0xf5, 0x02, 0xd7, 0x8f,
- 0xcb, 0xd1, 0x85, 0xc3, 0xf0, 0xbf, 0xbb, 0xed, 0xbd, 0xb4, 0xab, 0xf6,
- 0x00, 0xf1, 0x38, 0x78, 0xfe, 0x86, 0x9a, 0xb5, 0x1e, 0xf6, 0xd6, 0xe2,
- 0x38, 0xe4, 0x7c, 0x8a, 0xf5, 0xda, 0x7a, 0xe6, 0x73, 0x74, 0xaf, 0xd5,
- 0x73, 0xf7, 0x94, 0x9f, 0x7b, 0x32, 0xef, 0x78, 0x58, 0x30, 0xfc, 0xc2,
- 0x17, 0xfa, 0x76, 0x84, 0xcf, 0xe4, 0xf3, 0x9a, 0x65, 0x68, 0x3f, 0xf4,
- 0xcb, 0x14, 0xff, 0xb3, 0x5e, 0xed, 0x0a, 0xf1, 0x4a, 0xb4, 0x7d, 0x05,
- 0xdb, 0xf4, 0x35, 0x6f, 0xbd, 0xad, 0xad, 0xd2, 0x18, 0xad, 0x98, 0xcf,
- 0xdc, 0x0a, 0xdb, 0x71, 0xc9, 0x2e, 0xf0, 0xb7, 0x54, 0x8a, 0x38, 0x75,
- 0xb2, 0xd7, 0x5e, 0x5f, 0xb3, 0xc6, 0x16, 0xf4, 0x19, 0x9f, 0x20, 0x38,
- 0x15, 0xf0, 0x7c, 0x8b, 0xbb, 0xe9, 0x37, 0x79, 0xd7, 0x0d, 0x9a, 0x93,
- 0x89, 0x5b, 0xed, 0x35, 0xef, 0x71, 0x77, 0xd9, 0x0e, 0xc7, 0x2d, 0xea,
- 0xce, 0x60, 0x54, 0x9a, 0xc9, 0x43, 0x25, 0xf5, 0xe3, 0x43, 0x8e, 0xc1,
- 0x5c, 0x44, 0x9d, 0xf1, 0x56, 0xe6, 0xec, 0xdf, 0xd1, 0x73, 0x6b, 0xa2,
- 0x4f, 0x80, 0x6b, 0xf0, 0xc9, 0xe7, 0xf2, 0xbd, 0xcc, 0xf5, 0x62, 0xfd,
- 0x46, 0xae, 0xef, 0x7a, 0xe7, 0x9c, 0x70, 0xb3, 0xd6, 0x7d, 0x92, 0x39,
- 0x6f, 0xf8, 0x6f, 0xc8, 0x01, 0xef, 0x35, 0xa3, 0x3d, 0x4f, 0x9b, 0xf0,
- 0x45, 0xeb, 0xf8, 0xb6, 0xa1, 0x4b, 0x6d, 0xc3, 0x89, 0x3c, 0xf9, 0x93,
- 0x7c, 0xe9, 0xf3, 0xa3, 0xaf, 0xf3, 0xc8, 0xa3, 0xd4, 0xb3, 0xfd, 0x72,
- 0x26, 0xcf, 0xb3, 0x49, 0x69, 0x4d, 0x6b, 0xe3, 0xd9, 0x71, 0xc5, 0x64,
- 0x75, 0x4e, 0x25, 0x5e, 0xce, 0xca, 0xa0, 0x5c, 0x71, 0x79, 0x66, 0x89,
- 0x42, 0x3a, 0xd8, 0x54, 0xf1, 0xfe, 0xfb, 0xf5, 0xcc, 0xc2, 0xea, 0x33,
- 0xc6, 0x30, 0xf7, 0x79, 0x8f, 0xde, 0xcd, 0x7a, 0xb6, 0xe9, 0x2a, 0xfa,
- 0x7c, 0x53, 0xcf, 0x29, 0x0c, 0x9d, 0xc8, 0xfa, 0x7e, 0x38, 0xc2, 0x7b,
- 0xf8, 0x5c, 0xfa, 0x7c, 0x7c, 0x16, 0x79, 0xaf, 0x13, 0x16, 0xbb, 0x57,
- 0x82, 0x3b, 0x20, 0xfa, 0x3b, 0x58, 0x47, 0x0e, 0x40, 0x56, 0x37, 0x1a,
- 0x0c, 0xcc, 0x98, 0xf1, 0x35, 0xd2, 0xd6, 0x55, 0x9c, 0x23, 0x62, 0x15,
- 0xf8, 0xd1, 0x27, 0x5e, 0xba, 0x8d, 0xf5, 0xd2, 0x9e, 0xbf, 0xde, 0x87,
- 0xf5, 0x1d, 0xaf, 0xae, 0x3e, 0xb9, 0x8d, 0xbc, 0x3a, 0xa2, 0xf5, 0x41,
- 0xde, 0x43, 0x39, 0xe6, 0x99, 0x91, 0x2e, 0xef, 0xe3, 0x7e, 0xb6, 0xb7,
- 0xd4, 0xd0, 0x31, 0xe9, 0xed, 0xcf, 0x1f, 0x0f, 0x4b, 0xb8, 0x95, 0x3a,
- 0x2e, 0x2a, 0xc9, 0x29, 0xc6, 0x2c, 0xb0, 0x5d, 0x63, 0x5c, 0xeb, 0xcb,
- 0x75, 0x71, 0xfa, 0xff, 0xd4, 0xc5, 0x69, 0xeb, 0x23, 0xe5, 0x9d, 0xb0,
- 0xe6, 0xb1, 0xbe, 0x98, 0xae, 0x85, 0x2a, 0xba, 0xfa, 0xb5, 0xfb, 0x68,
- 0x99, 0x8e, 0x3f, 0xc9, 0xd3, 0x5e, 0xa5, 0x34, 0xa7, 0xfc, 0xb7, 0x49,
- 0x9e, 0x2d, 0xf7, 0x78, 0x85, 0x7b, 0x1c, 0x5c, 0x74, 0x89, 0x83, 0xf9,
- 0x96, 0xca, 0xf0, 0xa9, 0x3c, 0x75, 0x4c, 0x93, 0xcc, 0x4d, 0xfb, 0x7a,
- 0x66, 0xd4, 0xf3, 0x71, 0x73, 0x6b, 0xeb, 0x54, 0xcf, 0xc0, 0xbb, 0x71,
- 0x86, 0x3d, 0xfb, 0xd2, 0x21, 0xb3, 0xe7, 0x69, 0x77, 0x93, 0xe8, 0x8b,
- 0x06, 0x66, 0xe7, 0x59, 0x9b, 0x24, 0x16, 0x65, 0x50, 0x58, 0xf7, 0x1f,
- 0xb6, 0x4f, 0x40, 0xde, 0x62, 0xf2, 0xe1, 0x24, 0x7d, 0xfa, 0x3a, 0xf8,
- 0xc6, 0xcd, 0x35, 0xe7, 0xbb, 0xbd, 0xec, 0x13, 0x56, 0xd3, 0xbd, 0xa3,
- 0x4d, 0x1a, 0xc9, 0xe7, 0x8e, 0x7d, 0x5d, 0xe8, 0x83, 0xf1, 0x3a, 0x83,
- 0x58, 0x80, 0xb1, 0x47, 0x5c, 0x63, 0x8f, 0xd9, 0x02, 0xfb, 0x9a, 0xbc,
- 0xbc, 0x52, 0x93, 0xf2, 0x0a, 0xf9, 0x2d, 0xad, 0xfe, 0xf7, 0x80, 0xea,
- 0xac, 0xdc, 0x64, 0xb7, 0xc1, 0xb1, 0xd8, 0x31, 0xe5, 0x3d, 0xa9, 0xe2,
- 0xbd, 0x98, 0xef, 0x4b, 0xb6, 0x19, 0xdf, 0xca, 0x56, 0x7d, 0x13, 0xd6,
- 0x79, 0xb4, 0x2b, 0x5c, 0x9f, 0xbc, 0x41, 0x1e, 0xa1, 0xce, 0xf3, 0xe7,
- 0xf9, 0xf4, 0xf0, 0xdb, 0x9c, 0x4f, 0xfe, 0xaf, 0xc4, 0x22, 0xf8, 0xb2,
- 0xea, 0xf7, 0xf9, 0x72, 0xc7, 0xb1, 0x4a, 0x9b, 0x40, 0xb9, 0xab, 0xac,
- 0x4f, 0xda, 0x12, 0x99, 0x5a, 0xa6, 0xcb, 0x50, 0x2f, 0xf7, 0xff, 0x3c,
- 0x73, 0xbb, 0x90, 0xb7, 0x95, 0x68, 0x73, 0x4c, 0x69, 0x93, 0x06, 0x6d,
- 0x22, 0x4a, 0x1b, 0xc6, 0x7b, 0x4f, 0x79, 0xfc, 0xd6, 0x84, 0xf3, 0x62,
- 0xae, 0x16, 0xba, 0x6e, 0x1f, 0x75, 0xfe, 0x33, 0x6d, 0x5a, 0x1f, 0x74,
- 0xa8, 0xfb, 0x56, 0x43, 0x9f, 0xb1, 0xbd, 0x59, 0xfd, 0x11, 0x13, 0x6f,
- 0xc5, 0x35, 0x0f, 0x1a, 0x84, 0x7e, 0x9e, 0x9d, 0x84, 0xaf, 0x46, 0xdc,
- 0x5b, 0x15, 0xad, 0x1e, 0xf7, 0xce, 0xeb, 0x55, 0xa5, 0x0d, 0x65, 0x80,
- 0x7a, 0x73, 0x0d, 0xd6, 0xdb, 0x13, 0xed, 0x01, 0x7f, 0xbd, 0x82, 0xfe,
- 0x8d, 0x1a, 0x4f, 0x04, 0x21, 0xf3, 0x37, 0x26, 0x5b, 0xbd, 0x18, 0xce,
- 0x41, 0x1b, 0x71, 0xeb, 0x64, 0x84, 0x31, 0x05, 0xda, 0x5d, 0x52, 0x37,
- 0x85, 0xf8, 0x15, 0x7a, 0x7c, 0x51, 0xed, 0x51, 0x0f, 0xc6, 0xef, 0x20,
- 0xce, 0x0f, 0xd7, 0x87, 0x71, 0x5f, 0xb7, 0xc1, 0x22, 0x44, 0x37, 0xe9,
- 0x99, 0xce, 0x4e, 0x26, 0x62, 0x87, 0xc4, 0xeb, 0x1b, 0x73, 0x55, 0x1f,
- 0x2c, 0xef, 0xeb, 0x01, 0xd9, 0x53, 0xb6, 0x17, 0x8c, 0xa3, 0xe1, 0xc3,
- 0x4f, 0x1b, 0x7b, 0x90, 0x2b, 0xf4, 0x28, 0x3e, 0x2a, 0x38, 0xb0, 0x80,
- 0xb3, 0xa4, 0x4f, 0xba, 0x04, 0x3f, 0xdc, 0xc5, 0x19, 0xd2, 0xef, 0x2e,
- 0x1d, 0x3f, 0xe9, 0xa6, 0x58, 0x1f, 0x83, 0x3e, 0x38, 0x2e, 0xc3, 0x88,
- 0x0b, 0x86, 0x83, 0xcd, 0xcc, 0x2b, 0xc3, 0x37, 0xcc, 0x7a, 0xb9, 0xc7,
- 0x1e, 0xe6, 0x4c, 0xe5, 0xec, 0x3c, 0xf7, 0x4e, 0xd9, 0x36, 0xb1, 0xf7,
- 0xec, 0x24, 0xf7, 0x6b, 0xf2, 0x10, 0x6c, 0x5b, 0x53, 0x2e, 0x7e, 0x79,
- 0x16, 0x7d, 0xf8, 0xed, 0x87, 0x3c, 0x70, 0x2e, 0x7e, 0xe7, 0x97, 0xe4,
- 0xbd, 0xf3, 0xbe, 0x6d, 0x0f, 0xc8, 0xbb, 0x4e, 0xe9, 0xf8, 0x09, 0x77,
- 0x2d, 0xcf, 0xc0, 0xcd, 0xb2, 0x66, 0xed, 0x38, 0x6e, 0x4e, 0x4a, 0xa5,
- 0x45, 0x77, 0x71, 0xad, 0xa5, 0xb4, 0xa4, 0xfc, 0x7f, 0x80, 0x33, 0xbc,
- 0x76, 0xaf, 0x25, 0x86, 0x7e, 0xa4, 0xcd, 0xe7, 0x6b, 0x7f, 0x95, 0xb6,
- 0xc0, 0xd7, 0x7f, 0xe4, 0x47, 0xf2, 0xe5, 0x92, 0xec, 0x54, 0xfd, 0xbf,
- 0xd2, 0x7d, 0x95, 0xba, 0xdf, 0xf7, 0x6f, 0xa9, 0xdf, 0xc9, 0x8b, 0x31,
- 0x8d, 0x0f, 0x36, 0x4d, 0xd5, 0xea, 0x84, 0x1f, 0x78, 0x75, 0x85, 0x95,
- 0x78, 0xef, 0x80, 0xa7, 0x17, 0x52, 0xea, 0x3b, 0xa7, 0x6c, 0xea, 0x07,
- 0xee, 0xa7, 0x51, 0xc6, 0x67, 0x6e, 0x83, 0x26, 0xbe, 0x0e, 0x66, 0xdc,
- 0xe7, 0xeb, 0x8e, 0x66, 0xcf, 0x17, 0xb6, 0xa4, 0xf3, 0x2c, 0x7d, 0x27,
- 0x07, 0x7a, 0xb4, 0x45, 0xd2, 0x63, 0x41, 0x49, 0x9e, 0x6d, 0x89, 0x19,
- 0x5f, 0x97, 0xfc, 0x07, 0x79, 0xd3, 0x3e, 0xb6, 0x37, 0xa0, 0xff, 0x4e,
- 0xe1, 0xb3, 0x0d, 0x3f, 0x43, 0x9e, 0xf7, 0xf9, 0x63, 0x76, 0x0d, 0x8f,
- 0xee, 0xf0, 0x78, 0x94, 0xe3, 0x96, 0xa9, 0x7f, 0x60, 0x6e, 0xe7, 0x59,
- 0xee, 0xd1, 0xdc, 0xd7, 0x79, 0xd6, 0xc4, 0xeb, 0xd5, 0xf7, 0xf5, 0x94,
- 0xef, 0xc3, 0x78, 0x97, 0x62, 0xc3, 0xb0, 0xf6, 0xce, 0x7e, 0xf8, 0x74,
- 0x3d, 0xb4, 0x39, 0xb4, 0xdf, 0x1b, 0xdd, 0x9d, 0x42, 0x7e, 0x4f, 0x78,
- 0x3c, 0x47, 0x7d, 0x13, 0xf1, 0xf4, 0xcd, 0xb2, 0x7d, 0x19, 0x36, 0xf8,
- 0x13, 0xe6, 0x44, 0x2a, 0xec, 0xcb, 0x43, 0xe6, 0xdd, 0xaa, 0xec, 0xcb,
- 0x9d, 0xde, 0x3a, 0xfe, 0x98, 0xaf, 0x57, 0xfc, 0xb6, 0xaf, 0x57, 0x6a,
- 0x7d, 0x5a, 0x9f, 0xf6, 0xd5, 0xb8, 0xaf, 0xca, 0x98, 0x2f, 0xb7, 0x62,
- 0xde, 0x25, 0x83, 0x98, 0x8d, 0x3e, 0x65, 0x22, 0x6b, 0x30, 0xd3, 0xd6,
- 0x19, 0x8b, 0xb8, 0x0f, 0xe7, 0x67, 0x32, 0x14, 0xb9, 0xad, 0xb1, 0xf5,
- 0xa9, 0x99, 0x51, 0xcd, 0xf3, 0xcc, 0xba, 0x9e, 0xde, 0x89, 0xee, 0x86,
- 0x5c, 0xcd, 0x47, 0x96, 0x31, 0x45, 0x4f, 0x1e, 0x1b, 0x82, 0x1d, 0x4a,
- 0x69, 0xbd, 0xec, 0x71, 0xec, 0xb7, 0x5f, 0xf1, 0x5c, 0xab, 0x9c, 0xe7,
- 0x64, 0x97, 0x5d, 0xd2, 0xda, 0x4d, 0xc3, 0x40, 0xf6, 0x58, 0xc3, 0x69,
- 0x9f, 0xef, 0xc9, 0x4f, 0x4f, 0x1e, 0x1b, 0x9f, 0x2e, 0x0d, 0x86, 0xb6,
- 0x75, 0xdb, 0x39, 0x59, 0x0f, 0x9a, 0x0f, 0xca, 0xa3, 0x8a, 0x1d, 0x7e,
- 0x0d, 0xe3, 0xfb, 0x18, 0x5f, 0x26, 0x42, 0x8a, 0x09, 0x4e, 0xc4, 0x26,
- 0x20, 0x8b, 0x19, 0x37, 0xd1, 0x35, 0x14, 0x5c, 0xcd, 0xdc, 0x0d, 0x62,
- 0x66, 0xfa, 0x59, 0xc4, 0x14, 0x3c, 0x2b, 0x87, 0xdc, 0x8d, 0xee, 0xa2,
- 0x64, 0x3d, 0x4c, 0x3e, 0x6b, 0x42, 0xf5, 0x32, 0xe1, 0x86, 0x1a, 0x86,
- 0x8a, 0x46, 0x06, 0x46, 0x82, 0xa9, 0x55, 0x27, 0x9d, 0x68, 0xc3, 0xce,
- 0x22, 0x64, 0xbc, 0x08, 0xfd, 0x5f, 0x8c, 0x05, 0x86, 0x15, 0x9b, 0xf6,
- 0x55, 0x19, 0x6a, 0xa5, 0x9f, 0x4f, 0x7d, 0xf2, 0x35, 0xb9, 0x61, 0x6f,
- 0x96, 0x1b, 0x5d, 0xc4, 0x63, 0xf6, 0xa2, 0x4d, 0x5d, 0xd2, 0x8f, 0xbe,
- 0x24, 0xfa, 0x1a, 0x94, 0x1f, 0x35, 0x3e, 0x83, 0xce, 0xba, 0x61, 0x53,
- 0x57, 0xdd, 0xc5, 0x5f, 0xbc, 0xeb, 0x9f, 0x41, 0x13, 0x62, 0x3b, 0xb6,
- 0xa0, 0x4d, 0x1d, 0x67, 0xd7, 0xf4, 0xb7, 0xa3, 0x7d, 0x2f, 0xd6, 0xa8,
- 0xd3, 0xf7, 0xb3, 0x9c, 0x6d, 0xa6, 0xce, 0x59, 0x35, 0x67, 0x4d, 0x4d,
- 0xfb, 0xdd, 0x16, 0x83, 0x4f, 0xb8, 0x45, 0x7a, 0x67, 0x53, 0xb2, 0xab,
- 0xad, 0xba, 0xfd, 0xcf, 0x9a, 0x76, 0xb3, 0xac, 0x6a, 0x21, 0x19, 0x9e,
- 0x68, 0xad, 0xee, 0xf7, 0xf9, 0xc9, 0x6f, 0xb7, 0xe1, 0x7d, 0x13, 0x30,
- 0x78, 0x49, 0x8d, 0xa5, 0x6e, 0x44, 0xf9, 0xac, 0xbf, 0xd6, 0xdc, 0xc3,
- 0x6b, 0xde, 0xc3, 0x7b, 0x99, 0xd7, 0xfb, 0x37, 0xfb, 0x71, 0x0f, 0x73,
- 0x02, 0xcc, 0x6b, 0x90, 0x67, 0x57, 0x8a, 0xb3, 0x38, 0xe7, 0xf3, 0xf9,
- 0x86, 0x74, 0x99, 0xf7, 0x7c, 0xbd, 0x12, 0x2b, 0x63, 0xd5, 0x76, 0xe6,
- 0xfd, 0x9c, 0x30, 0x69, 0xa7, 0x35, 0xa9, 0xd8, 0x75, 0xd0, 0xf9, 0x20,
- 0xe8, 0xfc, 0x40, 0x90, 0x71, 0x61, 0xa3, 0x47, 0x6b, 0x47, 0x86, 0x8b,
- 0x6f, 0x43, 0xc6, 0xc9, 0xa3, 0xf0, 0x29, 0x8a, 0x96, 0x87, 0xcf, 0xe8,
- 0x83, 0x4d, 0x73, 0x25, 0xa8, 0x79, 0x07, 0xc4, 0xf7, 0x73, 0xd7, 0x64,
- 0x78, 0x92, 0x39, 0x01, 0xf2, 0x33, 0xe3, 0xfa, 0x14, 0xc6, 0x6e, 0x62,
- 0xae, 0x0b, 0x19, 0x1e, 0x05, 0xbf, 0x86, 0xc4, 0x99, 0xda, 0x22, 0xd9,
- 0xb1, 0x51, 0xf5, 0x01, 0x3a, 0x61, 0xa3, 0x4e, 0xb8, 0x23, 0x72, 0xf2,
- 0xf2, 0xdd, 0x90, 0x55, 0xc6, 0xfd, 0x9a, 0xd3, 0x28, 0x85, 0xd5, 0x37,
- 0xa7, 0xcf, 0xc1, 0x3c, 0x9c, 0xa9, 0x31, 0x1b, 0xb9, 0x7d, 0x24, 0x26,
- 0xcd, 0x23, 0x32, 0x3d, 0x63, 0x2b, 0xde, 0x25, 0x25, 0xb7, 0x4b, 0xa4,
- 0x5d, 0x66, 0x5f, 0x1c, 0xba, 0x8a, 0xbe, 0x7c, 0x2e, 0x62, 0xce, 0x72,
- 0x74, 0x1d, 0x63, 0xe2, 0xe4, 0x54, 0xe5, 0x1a, 0x8a, 0x91, 0xc1, 0xd8,
- 0xa5, 0x16, 0x23, 0x33, 0x8c, 0x8f, 0x3f, 0x2a, 0xa5, 0xa2, 0x7c, 0x26,
- 0xe7, 0xb2, 0x76, 0x4b, 0x1e, 0xe1, 0xde, 0xfe, 0xe3, 0xf1, 0xf2, 0x4b,
- 0x58, 0x2f, 0x2e, 0x9d, 0xaf, 0x8f, 0x6a, 0x5c, 0x7f, 0xa2, 0x2a, 0x86,
- 0x35, 0xf9, 0x02, 0x13, 0xc7, 0x5e, 0x93, 0x89, 0x05, 0xd2, 0x87, 0x36,
- 0x3e, 0x20, 0x3f, 0x77, 0xba, 0xed, 0xc7, 0xb4, 0xd6, 0x98, 0x48, 0xb1,
- 0x3e, 0xd3, 0xe8, 0x24, 0xed, 0x39, 0x09, 0xf5, 0x7f, 0x03, 0xd7, 0x8c,
- 0x6b, 0x73, 0x6e, 0xb7, 0xfb, 0x98, 0xf8, 0x38, 0x90, 0x8d, 0xa9, 0xfa,
- 0xc0, 0xad, 0xd2, 0xb5, 0x7d, 0x9c, 0x63, 0x70, 0x20, 0x12, 0x20, 0xad,
- 0x3e, 0xb8, 0x8b, 0xf8, 0x99, 0xea, 0xfc, 0xdf, 0xfd, 0x47, 0xf6, 0xf6,
- 0x25, 0x5e, 0x64, 0x0c, 0x1b, 0x76, 0x0e, 0xac, 0x33, 0xef, 0x9a, 0xcd,
- 0xae, 0x11, 0xad, 0x9f, 0x1d, 0xfd, 0xbb, 0x43, 0x3c, 0x44, 0x22, 0x56,
- 0x6f, 0x31, 0x0f, 0x4e, 0x1d, 0xc7, 0x9a, 0x0a, 0x73, 0x6e, 0xc4, 0xf2,
- 0x37, 0xc8, 0xa5, 0x1e, 0x4b, 0xee, 0x0f, 0xa5, 0xe2, 0x96, 0x6c, 0x8a,
- 0x9f, 0x15, 0x3c, 0x93, 0xf5, 0x95, 0x85, 0x44, 0x96, 0xf3, 0x43, 0x53,
- 0x5c, 0x2f, 0xae, 0xf1, 0x4a, 0x72, 0x53, 0xa9, 0xf4, 0x94, 0x2b, 0x81,
- 0xe4, 0xd6, 0x8f, 0x4b, 0xac, 0x85, 0x5b, 0xaf, 0x7f, 0x11, 0x4e, 0x41,
- 0xbf, 0x1d, 0x98, 0x30, 0x98, 0xc3, 0x89, 0xa3, 0x9d, 0x0b, 0x6c, 0xa7,
- 0x77, 0x99, 0xf6, 0x61, 0xb4, 0xeb, 0x3c, 0xac, 0xd3, 0x0f, 0x8f, 0x76,
- 0x16, 0x9e, 0x58, 0x67, 0xe2, 0xef, 0x25, 0xc5, 0x7f, 0xbd, 0x53, 0x15,
- 0xd3, 0xa4, 0x02, 0x63, 0xf9, 0xd1, 0xc0, 0x68, 0xde, 0xea, 0x69, 0x00,
- 0xad, 0xe6, 0x5d, 0xe6, 0x6a, 0xfc, 0x9c, 0x15, 0xf3, 0xfd, 0x22, 0x4f,
- 0x2a, 0x46, 0x8a, 0x35, 0x45, 0x4b, 0x7d, 0xa1, 0x83, 0xf3, 0xcc, 0xf1,
- 0x47, 0x54, 0x1f, 0x1c, 0x5a, 0x68, 0x96, 0x9c, 0xbd, 0x56, 0x72, 0x2a,
- 0xe3, 0x51, 0xd5, 0x01, 0x96, 0xb3, 0x15, 0x7d, 0xdc, 0xf7, 0x43, 0x8a,
- 0x8b, 0x78, 0x23, 0xdf, 0x8e, 0x36, 0x73, 0xcd, 0xdb, 0x6b, 0xfa, 0x2b,
- 0xeb, 0xb2, 0x09, 0xdb, 0xb2, 0x6a, 0x6b, 0xb2, 0xec, 0xab, 0xad, 0xc5,
- 0x9e, 0x92, 0x6b, 0xe4, 0x9b, 0xa2, 0x9f, 0x73, 0x77, 0xbd, 0x9c, 0xfb,
- 0xf7, 0xb1, 0x26, 0xd7, 0x96, 0x74, 0x68, 0xa0, 0xa1, 0xe7, 0xc4, 0x64,
- 0xf0, 0xe6, 0x72, 0xfe, 0x14, 0xed, 0x85, 0x72, 0xad, 0x1c, 0x63, 0xcf,
- 0xc0, 0x17, 0xc9, 0xc1, 0xaf, 0xc8, 0x7a, 0xdf, 0x1f, 0x70, 0xbc, 0x7c,
- 0xff, 0x97, 0xec, 0xa9, 0x51, 0xeb, 0xec, 0x56, 0x55, 0x9d, 0xfd, 0x7b,
- 0xb8, 0x97, 0x35, 0xf6, 0x6c, 0xa9, 0x0e, 0xbc, 0x5b, 0x47, 0x9c, 0x48,
- 0x79, 0x3e, 0x75, 0xbc, 0xea, 0x72, 0x5d, 0x6b, 0xa7, 0xb7, 0x56, 0x10,
- 0x7a, 0x7e, 0x7c, 0xd2, 0x9f, 0x73, 0x5c, 0xea, 0x7b, 0x13, 0xb1, 0xa0,
- 0xc5, 0x39, 0x46, 0xdf, 0x0f, 0xb9, 0xc7, 0xa1, 0xc7, 0xa9, 0xf3, 0xf9,
- 0xde, 0x0e, 0x7c, 0x3d, 0xea, 0x02, 0xea, 0x73, 0xb5, 0x01, 0xf1, 0x1c,
- 0x74, 0xfd, 0x70, 0xd1, 0x7c, 0xeb, 0xf5, 0xf5, 0x60, 0x62, 0x3a, 0xa3,
- 0xba, 0x01, 0xfe, 0x5e, 0xf1, 0x0d, 0xe6, 0x83, 0x5e, 0x94, 0x40, 0x65,
- 0x9d, 0x86, 0xb1, 0x19, 0x6b, 0x1a, 0x4d, 0xd0, 0x0d, 0x22, 0x57, 0xc0,
- 0x1b, 0x57, 0xe7, 0xc9, 0xaf, 0xc1, 0x56, 0x13, 0x5f, 0x2d, 0x6e, 0xb7,
- 0xa4, 0x55, 0x6b, 0x9f, 0x39, 0x27, 0x42, 0xff, 0x64, 0x30, 0xd9, 0x0b,
- 0x3f, 0x5b, 0xb1, 0x07, 0xcc, 0x57, 0x8e, 0x23, 0x1e, 0xab, 0xcc, 0xb1,
- 0x40, 0xbe, 0xc6, 0xd8, 0x9f, 0x81, 0x5f, 0xb9, 0x5c, 0xf7, 0xc8, 0x15,
- 0x4e, 0x6a, 0x6e, 0x73, 0x76, 0xbe, 0x49, 0x75, 0xec, 0x6c, 0x61, 0x04,
- 0xe7, 0x22, 0x9b, 0xad, 0x81, 0x9c, 0xd7, 0x1f, 0x96, 0x42, 0x81, 0x6d,
- 0xe9, 0xa8, 0xd3, 0x73, 0xf7, 0x6b, 0x3b, 0xb6, 0xcc, 0xc1, 0x57, 0x2c,
- 0x2c, 0x38, 0xf8, 0xef, 0xc2, 0x7f, 0x0f, 0xfe, 0x77, 0xcb, 0xd0, 0x14,
- 0xfd, 0x57, 0xd6, 0x72, 0x9a, 0x6a, 0x9e, 0x4f, 0x1f, 0xa9, 0x43, 0x71,
- 0x60, 0x39, 0x2f, 0xce, 0xc9, 0x15, 0x6a, 0xe5, 0x84, 0x79, 0x52, 0x5f,
- 0x47, 0x30, 0x5f, 0xea, 0xd7, 0xfa, 0x2a, 0x6b, 0x58, 0x96, 0x57, 0xf7,
- 0x22, 0x4f, 0x37, 0xca, 0xa1, 0x82, 0x5f, 0xbb, 0x8a, 0xc9, 0xa3, 0xe5,
- 0xda, 0x95, 0xa4, 0x83, 0x03, 0xb7, 0x1e, 0xcc, 0x4c, 0x2a, 0x9e, 0xc0,
- 0xb2, 0x06, 0xae, 0x3d, 0x38, 0xb1, 0xf0, 0xee, 0x83, 0xcb, 0x98, 0x70,
- 0x8c, 0x2d, 0xac, 0x84, 0x19, 0x22, 0x96, 0xee, 0x33, 0xf2, 0x10, 0x0d,
- 0x27, 0xf6, 0xed, 0xc7, 0x3c, 0xc4, 0xd9, 0x6d, 0xb0, 0x97, 0xf1, 0xcb,
- 0x7e, 0x3c, 0x4a, 0x1c, 0x29, 0xef, 0xab, 0xc4, 0x7e, 0x84, 0x70, 0xfe,
- 0x12, 0xb0, 0x9c, 0x2c, 0xf6, 0x71, 0xa1, 0xdd, 0xf8, 0x81, 0xc4, 0x99,
- 0x26, 0x2a, 0xb0, 0x47, 0x3e, 0xd6, 0xf4, 0x65, 0xac, 0x95, 0x96, 0xdf,
- 0x14, 0x1f, 0x96, 0x5f, 0x16, 0x47, 0x21, 0xdf, 0x13, 0x58, 0xf3, 0x80,
- 0xfc, 0xa2, 0xb8, 0x4f, 0xde, 0x2a, 0x8e, 0xc9, 0x9b, 0xc5, 0xdd, 0x88,
- 0xa9, 0x46, 0x88, 0xf5, 0xf4, 0xb0, 0xd2, 0x83, 0x32, 0x7e, 0x4e, 0x31,
- 0x80, 0x37, 0xe9, 0xf7, 0x1c, 0x55, 0x3f, 0x9b, 0xf8, 0xfa, 0xc4, 0xaf,
- 0x18, 0xcf, 0x13, 0x9b, 0x59, 0x28, 0xfa, 0x18, 0x8e, 0x89, 0x0e, 0x3c,
- 0xdb, 0xe6, 0xb7, 0x29, 0xc3, 0xe7, 0x22, 0x81, 0x91, 0x73, 0xa1, 0xc0,
- 0x03, 0xfa, 0x9d, 0x0b, 0xeb, 0x9d, 0x25, 0x39, 0xe9, 0x3a, 0xe4, 0xcd,
- 0xfe, 0x61, 0xc8, 0xc2, 0x08, 0x54, 0xfd, 0x2e, 0x67, 0xad, 0x80, 0xa4,
- 0xa9, 0x4f, 0xe0, 0x67, 0x26, 0x4f, 0xbb, 0x92, 0xc9, 0xcf, 0x05, 0x0c,
- 0x1e, 0xcd, 0x46, 0xbb, 0x07, 0xed, 0x57, 0xbd, 0xf6, 0x0e, 0xc9, 0xcc,
- 0x48, 0xea, 0x43, 0xf5, 0x87, 0x5f, 0xf1, 0xfa, 0xfa, 0xd1, 0x07, 0xce,
- 0xbc, 0xc0, 0xbe, 0x0b, 0x5e, 0x1f, 0xcf, 0x84, 0xb5, 0xfa, 0xb8, 0xf2,
- 0x55, 0xc6, 0x1e, 0x13, 0xfd, 0xae, 0x41, 0x6b, 0xf1, 0x4b, 0xed, 0x46,
- 0xb7, 0x11, 0x13, 0xf8, 0x8f, 0x76, 0xc6, 0x60, 0x05, 0xc8, 0xd7, 0x5d,
- 0xd0, 0x89, 0x7f, 0xd9, 0xbc, 0xdc, 0xb6, 0x06, 0x3e, 0xad, 0xc0, 0x68,
- 0x7f, 0x2a, 0x9d, 0x0b, 0xff, 0xf2, 0xf0, 0xbc, 0x07, 0xf1, 0x6e, 0x38,
- 0xab, 0x3c, 0x71, 0xe3, 0x71, 0xc8, 0x76, 0x93, 0xac, 0x3d, 0x43, 0x7a,
- 0x75, 0x43, 0x57, 0xa7, 0x20, 0xb7, 0xae, 0xcc, 0x17, 0x43, 0x81, 0xe1,
- 0x7c, 0x4a, 0x0c, 0x9e, 0xda, 0x92, 0x74, 0x34, 0x25, 0xa7, 0xfa, 0x12,
- 0x5d, 0xcc, 0x43, 0x66, 0x7a, 0x5d, 0xb9, 0x58, 0xa4, 0x3d, 0xce, 0xca,
- 0xa5, 0xbe, 0x84, 0x5b, 0x10, 0xe2, 0x62, 0x5c, 0xb9, 0x04, 0xd9, 0xfc,
- 0xdd, 0xb9, 0xdd, 0xf2, 0x68, 0x5e, 0xfd, 0xe0, 0xee, 0xb0, 0xbc, 0x20,
- 0x17, 0xfb, 0x5e, 0xb8, 0x79, 0xd1, 0x7d, 0x04, 0x67, 0x4a, 0x3e, 0xcc,
- 0x74, 0x98, 0x7d, 0x2b, 0x0e, 0x49, 0x98, 0x0f, 0xd1, 0x9a, 0x9a, 0x53,
- 0x2f, 0x43, 0xfb, 0x23, 0x5e, 0x5c, 0x0e, 0x9f, 0x3b, 0xe0, 0x9a, 0x7a,
- 0x4a, 0xc0, 0xdf, 0x67, 0x18, 0x7e, 0x0c, 0xef, 0xf3, 0x69, 0xe3, 0xaf,
- 0xd3, 0x1e, 0x18, 0x9a, 0x69, 0x96, 0xd0, 0x85, 0xaf, 0x80, 0xae, 0x21,
- 0x39, 0xd8, 0x5b, 0x2a, 0x7d, 0xc7, 0x0d, 0xc5, 0x27, 0x10, 0xa3, 0x60,
- 0xff, 0xb2, 0xe6, 0x74, 0x0b, 0x68, 0xd2, 0x20, 0xd1, 0xd3, 0xfe, 0xf3,
- 0xea, 0x3d, 0x2c, 0xc3, 0x99, 0x35, 0xc6, 0x96, 0xf9, 0xd8, 0x06, 0x7f,
- 0x3d, 0x83, 0x29, 0xeb, 0xb4, 0x7a, 0x03, 0xde, 0x77, 0x12, 0x5e, 0x7b,
- 0x6b, 0xe0, 0xfe, 0x50, 0xab, 0x84, 0x9c, 0x67, 0xd7, 0x13, 0x1b, 0xb9,
- 0x98, 0xf7, 0xfb, 0xe1, 0x27, 0x86, 0x7c, 0x7f, 0x58, 0xb6, 0x2d, 0x9f,
- 0xb5, 0x6c, 0xeb, 0x5c, 0xf8, 0xae, 0xb7, 0x66, 0xca, 0x9b, 0x8b, 0x98,
- 0x23, 0xb6, 0x5a, 0xed, 0x93, 0x99, 0xfb, 0x5f, 0x79, 0xba, 0x37, 0xf1,
- 0x9a, 0xe2, 0x64, 0xcb, 0xf7, 0x70, 0x1c, 0x31, 0x64, 0x51, 0xef, 0x89,
- 0xed, 0x01, 0x7d, 0xd3, 0xb1, 0x7b, 0xec, 0x39, 0x2b, 0x18, 0x30, 0xfe,
- 0x48, 0x9d, 0xfc, 0x28, 0x0a, 0xbb, 0xcd, 0x6f, 0x58, 0x98, 0xff, 0x72,
- 0x6f, 0x7b, 0x7e, 0x0a, 0xfb, 0x12, 0x2f, 0x26, 0xad, 0x34, 0xf6, 0xc7,
- 0x33, 0x20, 0x06, 0xd4, 0x02, 0x9d, 0xda, 0xf1, 0x7e, 0x88, 0x9f, 0x7a,
- 0xfd, 0xf7, 0x5f, 0x03, 0x1d, 0xc6, 0xfd, 0x1b, 0x5c, 0x98, 0x58, 0xcc,
- 0x85, 0x0c, 0x7a, 0x18, 0xd8, 0x4a, 0xb9, 0xf5, 0xb1, 0xb1, 0x3e, 0x9e,
- 0x8e, 0x18, 0xa5, 0x18, 0xfc, 0x40, 0xca, 0x04, 0x79, 0xb3, 0x0d, 0xfd,
- 0xab, 0x6e, 0xa5, 0xf4, 0xd5, 0xfd, 0xbe, 0x8f, 0xcb, 0xd8, 0xee, 0x89,
- 0xfc, 0x3e, 0x83, 0xcd, 0xb3, 0x96, 0x24, 0xd5, 0x91, 0xb4, 0x4f, 0x62,
- 0xbf, 0x43, 0xa1, 0x44, 0x21, 0x2b, 0x31, 0x99, 0x83, 0xbe, 0xb8, 0x0a,
- 0xd9, 0x7f, 0xab, 0xc8, 0xef, 0x6d, 0x53, 0x72, 0x28, 0x0f, 0x83, 0x3e,
- 0xa3, 0xdf, 0x7e, 0x41, 0xef, 0x0f, 0xc8, 0x6c, 0x3e, 0xd1, 0x35, 0x07,
- 0xfe, 0x9b, 0xcb, 0x13, 0x5f, 0xd4, 0x1d, 0x1f, 0xc1, 0x8a, 0x8b, 0xf9,
- 0x8d, 0xb0, 0x0f, 0x92, 0xba, 0x08, 0xff, 0xe7, 0x62, 0xb1, 0x0b, 0x7c,
- 0x86, 0xf1, 0xa2, 0x83, 0x5f, 0xe8, 0xcc, 0x62, 0x1f, 0xe4, 0x9c, 0x7b,
- 0xb1, 0x65, 0x7e, 0x33, 0xce, 0x8e, 0x38, 0x22, 0xc5, 0x8f, 0x7f, 0x86,
- 0xf3, 0xf5, 0xdf, 0x7b, 0xbb, 0xda, 0xe9, 0x39, 0xdd, 0x17, 0xec, 0x32,
- 0x62, 0x80, 0x4c, 0xaf, 0xb1, 0xdb, 0x43, 0x91, 0x16, 0x19, 0xba, 0x87,
- 0x76, 0xbc, 0x55, 0x63, 0x44, 0xe5, 0xc5, 0x08, 0xc7, 0x7f, 0xbb, 0xde,
- 0xd0, 0x2f, 0x5c, 0xd3, 0x7e, 0x1b, 0xbf, 0xcd, 0xd2, 0xe6, 0xf0, 0xd7,
- 0xc6, 0xef, 0xb5, 0xf5, 0xac, 0xef, 0xb6, 0x39, 0x49, 0x3c, 0xeb, 0xd7,
- 0x5e, 0xbe, 0x00, 0xd7, 0x73, 0xbc, 0x67, 0x9d, 0xf7, 0x5c, 0xae, 0xdb,
- 0x8c, 0x75, 0x9a, 0xbc, 0x67, 0x35, 0x6b, 0x7e, 0xd2, 0x3c, 0x0b, 0x31,
- 0x6e, 0xfe, 0x4f, 0xeb, 0x79, 0x86, 0xfc, 0xde, 0xb8, 0xba, 0xfd, 0xc7,
- 0xf5, 0xc4, 0xcd, 0xb5, 0x39, 0xcd, 0x8a, 0xf1, 0xbc, 0xd1, 0xda, 0x8a,
- 0x6b, 0x3e, 0x93, 0x73, 0x4c, 0x3e, 0x7c, 0xb6, 0xc8, 0xf5, 0xd9, 0x4e,
- 0xc9, 0x31, 0xcd, 0x67, 0x18, 0x2c, 0xdf, 0x6c, 0xfe, 0x3e, 0x99, 0x38,
- 0xa7, 0xf8, 0xba, 0xe9, 0x9c, 0xc5, 0xef, 0x5e, 0xf8, 0xbd, 0x1c, 0x7d,
- 0x89, 0x51, 0x19, 0xc7, 0xf9, 0x5d, 0x82, 0x4f, 0xb5, 0x68, 0xbe, 0x8b,
- 0xc5, 0xdf, 0x01, 0x9c, 0x4b, 0x08, 0x32, 0x46, 0x19, 0xa5, 0x4c, 0xe1,
- 0xfc, 0xc6, 0x6c, 0x79, 0xaf, 0x8f, 0xf2, 0xdc, 0x27, 0x97, 0xcb, 0xf2,
- 0x9c, 0x85, 0x3c, 0x53, 0x96, 0xb3, 0x90, 0x69, 0xc3, 0xd7, 0xfb, 0x11,
- 0x63, 0xa4, 0x62, 0xb0, 0x57, 0xea, 0x43, 0xbc, 0x0c, 0xbe, 0xb6, 0xbd,
- 0x6f, 0xa5, 0x02, 0x9a, 0xc3, 0xc9, 0xcc, 0xd4, 0x79, 0xdf, 0x01, 0xe0,
- 0xfa, 0xf2, 0x73, 0x32, 0x34, 0xd3, 0x88, 0x7d, 0x6f, 0xe8, 0xe0, 0x99,
- 0x65, 0x2e, 0xf3, 0xdf, 0xe7, 0x45, 0xe2, 0x4d, 0xe9, 0xcf, 0xf2, 0x9a,
- 0x71, 0xde, 0x7a, 0xcc, 0xe9, 0x07, 0x9d, 0x1b, 0xb1, 0x3e, 0xf7, 0xb8,
- 0xd2, 0x3c, 0x8e, 0x87, 0x2a, 0xf0, 0xa9, 0x3e, 0xbd, 0x57, 0xeb, 0x33,
- 0x33, 0xbd, 0x8d, 0xde, 0xfb, 0xf1, 0x1c, 0xc8, 0xf7, 0x31, 0xf0, 0x2d,
- 0x7d, 0x62, 0xf2, 0x4b, 0x4a, 0xcf, 0x61, 0x36, 0x4f, 0xfe, 0x0d, 0x69,
- 0x0e, 0x23, 0x03, 0xdb, 0xb2, 0x57, 0xe7, 0xc7, 0x96, 0xe5, 0xbb, 0x23,
- 0xa0, 0x71, 0x77, 0x26, 0xbf, 0x4a, 0x3a, 0x55, 0x07, 0x75, 0x78, 0xbc,
- 0x0d, 0x7b, 0xa1, 0x58, 0xee, 0x03, 0x72, 0xb4, 0xd8, 0x0f, 0x3a, 0xc4,
- 0xe4, 0x29, 0xf8, 0xcd, 0xcf, 0x14, 0xef, 0x90, 0xa5, 0x08, 0xf6, 0x55,
- 0x96, 0xb1, 0x41, 0xf9, 0xf1, 0xdc, 0x06, 0xef, 0x3a, 0xe1, 0x2e, 0x59,
- 0xdb, 0xb1, 0x07, 0xca, 0x13, 0xe5, 0x8a, 0xf3, 0x82, 0x88, 0x45, 0xb8,
- 0xee, 0x11, 0xa3, 0xdb, 0xb0, 0x6e, 0x21, 0x42, 0xf9, 0xe5, 0xde, 0x42,
- 0x9e, 0xcc, 0x32, 0xae, 0xe2, 0x3b, 0x1b, 0x9b, 0x94, 0xae, 0x3a, 0x8b,
- 0x84, 0xe2, 0x40, 0x97, 0xcf, 0xc0, 0x5f, 0xc7, 0x97, 0x4b, 0xff, 0x3b,
- 0x0a, 0xea, 0x51, 0xd8, 0xca, 0x3c, 0x6c, 0x65, 0x1e, 0x36, 0x12, 0xb2,
- 0xf0, 0x56, 0x1e, 0x36, 0x32, 0x0f, 0x1b, 0x09, 0x7d, 0xf6, 0x06, 0x62,
- 0xbb, 0xab, 0xe0, 0x21, 0xe3, 0x6b, 0x1f, 0xa6, 0xaf, 0x8d, 0xbf, 0xff,
- 0x01, 0x88, 0x97, 0xee, 0xe9, 0xc4, 0x71, 0x00, 0x00, 0x00 };
+ 0xec, 0x5b, 0x5d, 0x70, 0x5c, 0xd7, 0x5d, 0xff, 0xdf, 0xb3, 0x2b, 0x69,
+ 0x2d, 0x4b, 0xf2, 0x95, 0xbc, 0x71, 0x56, 0xa9, 0x92, 0xec, 0x5a, 0x57,
+ 0xd2, 0xa6, 0x12, 0xe1, 0xca, 0x6c, 0x12, 0x75, 0xd8, 0x69, 0xb6, 0xbb,
+ 0xb2, 0xa3, 0xb4, 0x66, 0x46, 0x49, 0x0d, 0xcd, 0xb4, 0x65, 0x10, 0xbb,
+ 0x0e, 0xa4, 0x0f, 0x0c, 0xc6, 0x40, 0x26, 0x80, 0xc1, 0xcb, 0x4a, 0x71,
+ 0x94, 0x74, 0xad, 0xdd, 0xda, 0x0a, 0x86, 0x69, 0x61, 0x94, 0xd5, 0x87,
+ 0x53, 0x66, 0xad, 0x4d, 0xcb, 0x4b, 0x99, 0xd6, 0xb1, 0xea, 0xb8, 0x26,
+ 0x0f, 0x3c, 0xa4, 0x94, 0xce, 0x64, 0x20, 0x33, 0x35, 0xb2, 0x63, 0xfb,
+ 0x81, 0x8f, 0xc0, 0x4c, 0x49, 0x20, 0x6e, 0x2e, 0xbf, 0xdf, 0xb9, 0xf7,
+ 0xca, 0x2b, 0x45, 0xd0, 0x3c, 0xf0, 0x78, 0xcf, 0x8c, 0xe6, 0xde, 0x7b,
+ 0xce, 0xff, 0xfc, 0xcf, 0xff, 0xfb, 0xe3, 0xac, 0xfd, 0x3b, 0x1d, 0xd2,
+ 0x2e, 0xde, 0xe8, 0xc4, 0x5f, 0xea, 0xc8, 0x33, 0x47, 0x47, 0xef, 0x1f,
+ 0xbd, 0x9f, 0xdf, 0x21, 0xc3, 0x08, 0xf3, 0x69, 0x48, 0x30, 0x82, 0x11,
+ 0x8c, 0x60, 0x04, 0x23, 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c,
+ 0x60, 0x04, 0x23, 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c, 0x60,
+ 0x04, 0x23, 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c, 0x60, 0x04,
+ 0x23, 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c, 0x60, 0x04, 0x23,
+ 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c, 0x60, 0x04, 0x23, 0x18,
+ 0xc1, 0x08, 0x46, 0x30, 0xfe, 0x3f, 0x47, 0x48, 0xc4, 0xe4, 0xb3, 0xd3,
+ 0xfb, 0x93, 0x88, 0x4a, 0xc7, 0x8f, 0x66, 0x2d, 0x89, 0x84, 0xd2, 0x97,
+ 0x9e, 0x2e, 0x58, 0x22, 0x99, 0xfa, 0x70, 0x3c, 0x27, 0x3f, 0x71, 0x8a,
+ 0xd1, 0xb0, 0x70, 0xfe, 0xee, 0xf4, 0xad, 0xe3, 0xe7, 0x1f, 0x4a, 0xbc,
+ 0xb3, 0x10, 0x92, 0x88, 0x99, 0x7e, 0x63, 0xd4, 0x1c, 0x94, 0x48, 0x1f,
+ 0xf6, 0x7c, 0x6d, 0x68, 0x6d, 0x97, 0x74, 0xf9, 0xb8, 0x44, 0x6a, 0xe5,
+ 0x84, 0x7d, 0x40, 0x86, 0xcd, 0x8b, 0x12, 0x96, 0x0c, 0xce, 0x58, 0xa9,
+ 0x8b, 0x94, 0xca, 0x06, 0x71, 0x48, 0xa9, 0x1e, 0x91, 0x2b, 0x21, 0x42,
+ 0x7d, 0xcb, 0xc8, 0x56, 0x3e, 0x70, 0x32, 0x61, 0x9c, 0x6b, 0xe1, 0xbd,
+ 0xe1, 0xcf, 0x47, 0x44, 0xa5, 0x13, 0xc9, 0x6c, 0x68, 0x42, 0x6a, 0xf3,
+ 0x8e, 0x33, 0x63, 0x7f, 0x0c, 0x38, 0x7a, 0x64, 0xc6, 0x72, 0xbf, 0xb3,
+ 0xf6, 0xc7, 0xcd, 0x71, 0xb9, 0x13, 0x73, 0x21, 0x51, 0xd6, 0x5d, 0xf8,
+ 0x8b, 0x1b, 0xb9, 0xd3, 0x5f, 0x36, 0xb2, 0x8b, 0x1d, 0x52, 0xaa, 0x38,
+ 0x52, 0xb0, 0x25, 0x93, 0xb5, 0x77, 0x60, 0xfd, 0x03, 0xa7, 0xb0, 0xb1,
+ 0x67, 0xd8, 0xcc, 0x49, 0x8b, 0x64, 0xa2, 0x31, 0xc0, 0xcc, 0x1b, 0xb9,
+ 0xb3, 0x7f, 0xdd, 0x21, 0xed, 0xa0, 0x27, 0xc5, 0xef, 0x0f, 0x9c, 0x90,
+ 0x65, 0x61, 0x9d, 0xe7, 0xe3, 0xbb, 0x41, 0xbc, 0x7c, 0x27, 0xce, 0x2b,
+ 0xce, 0xf9, 0xa1, 0x98, 0x7c, 0xb3, 0x11, 0x95, 0x6f, 0x34, 0x4c, 0x79,
+ 0xa5, 0xd1, 0x27, 0x17, 0x1a, 0x8e, 0xf3, 0x0d, 0xdb, 0x71, 0xde, 0xc0,
+ 0xdf, 0x7f, 0xd8, 0x1b, 0x3c, 0x60, 0x14, 0x8d, 0xf1, 0xc6, 0x57, 0x3b,
+ 0xa4, 0x2b, 0x11, 0x17, 0xd5, 0x21, 0xd3, 0x95, 0x98, 0xcc, 0x54, 0xca,
+ 0xc6, 0x63, 0x67, 0xe7, 0x8c, 0xc9, 0xb3, 0x55, 0x9c, 0x19, 0xc6, 0x9c,
+ 0x14, 0x4b, 0xf6, 0xcb, 0x46, 0xae, 0x31, 0x6b, 0x3c, 0x7e, 0xb6, 0x0b,
+ 0x34, 0xf2, 0xfc, 0x3d, 0x46, 0xf6, 0xf4, 0x2d, 0xc9, 0xda, 0x94, 0x71,
+ 0xc2, 0xfc, 0x3c, 0xc4, 0x9e, 0x2d, 0x93, 0xe6, 0x56, 0x8f, 0x5e, 0xc7,
+ 0x51, 0x69, 0xe7, 0x78, 0x36, 0x65, 0x99, 0x25, 0x21, 0x7d, 0x7a, 0xee,
+ 0x82, 0x4b, 0xf3, 0x8a, 0x91, 0x3d, 0xdb, 0x61, 0xe4, 0xce, 0x84, 0x41,
+ 0x87, 0xf4, 0x85, 0x84, 0xfb, 0x06, 0x62, 0x79, 0xa9, 0xe3, 0x0c, 0x31,
+ 0x55, 0x9a, 0x72, 0x05, 0xcd, 0xa0, 0xe5, 0x9b, 0x15, 0xf0, 0x50, 0x01,
+ 0x0f, 0x15, 0xf2, 0x16, 0x97, 0xf3, 0x43, 0x3e, 0x6f, 0x8e, 0xf3, 0x77,
+ 0x36, 0x69, 0x4f, 0xc4, 0x33, 0xca, 0xe7, 0xd3, 0x71, 0xfe, 0xdd, 0x26,
+ 0xaf, 0xe4, 0xc7, 0x71, 0x5e, 0xb1, 0x63, 0xa0, 0xdd, 0xb9, 0xa0, 0xac,
+ 0x32, 0x78, 0xb1, 0x80, 0x9f, 0xb2, 0x9e, 0x03, 0x0f, 0xb3, 0xe0, 0x6f,
+ 0x05, 0xbc, 0x55, 0x41, 0xc7, 0x4f, 0x3b, 0xaf, 0x68, 0xe4, 0x86, 0x36,
+ 0xe4, 0x15, 0xa7, 0x8c, 0xf3, 0x4b, 0x0a, 0xb2, 0xde, 0x29, 0xf9, 0x05,
+ 0x53, 0xa6, 0x96, 0xfc, 0xfd, 0xbe, 0x1d, 0x1c, 0x91, 0x83, 0x95, 0x1e,
+ 0xc8, 0x86, 0xb2, 0x4c, 0xd8, 0x22, 0x0e, 0x64, 0x54, 0x4a, 0x2a, 0x11,
+ 0x23, 0x6f, 0x1f, 0xd7, 0xfa, 0x5f, 0xb2, 0x24, 0x93, 0xb7, 0x29, 0x47,
+ 0x89, 0xe7, 0xed, 0x62, 0x2c, 0x0c, 0x7b, 0x5b, 0xb2, 0x8a, 0x66, 0x58,
+ 0x28, 0xc7, 0x44, 0xec, 0xf7, 0x21, 0xcb, 0x27, 0xcb, 0x92, 0xf9, 0x74,
+ 0xd9, 0x97, 0xb1, 0x2b, 0xdf, 0xcf, 0x94, 0x3f, 0xd5, 0x29, 0xed, 0xea,
+ 0x9e, 0x16, 0xf9, 0x0d, 0xec, 0x25, 0xee, 0x4d, 0x7b, 0xb1, 0xcf, 0x85,
+ 0x73, 0xf7, 0x26, 0x9e, 0x10, 0x21, 0x6c, 0xa9, 0xbf, 0x45, 0xfb, 0x88,
+ 0x18, 0x59, 0xab, 0x18, 0x0b, 0x01, 0x2e, 0x2f, 0xa5, 0x51, 0x6f, 0xae,
+ 0x25, 0x6b, 0xdd, 0x0a, 0xcd, 0xd8, 0x89, 0x78, 0x49, 0x6e, 0x85, 0x2e,
+ 0xdb, 0x7a, 0x6e, 0x47, 0xd6, 0x72, 0x64, 0x19, 0xd8, 0x9f, 0x83, 0x3f,
+ 0x5c, 0x04, 0x47, 0x5f, 0x2a, 0xeb, 0xf9, 0x4e, 0xec, 0x4f, 0xb6, 0x00,
+ 0x67, 0xbb, 0x24, 0x92, 0x35, 0xcc, 0x5f, 0x76, 0xe7, 0xbb, 0x5d, 0xbc,
+ 0xa5, 0xfe, 0x76, 0x8d, 0x5b, 0xe4, 0x65, 0x77, 0xfe, 0x0e, 0x17, 0x77,
+ 0xe9, 0x3e, 0xcc, 0x03, 0xff, 0xe0, 0xc4, 0x90, 0xa1, 0xe7, 0x7b, 0xe9,
+ 0x4f, 0xbf, 0x5e, 0xbe, 0x15, 0x5a, 0xb6, 0x1d, 0xc9, 0x8d, 0x0e, 0x4e,
+ 0x0c, 0x1a, 0x2e, 0xbe, 0x13, 0xee, 0xbe, 0xbb, 0x5d, 0x7c, 0x83, 0x13,
+ 0x49, 0xc3, 0xc5, 0xb7, 0x54, 0xd6, 0x7b, 0x25, 0x5f, 0x26, 0xec, 0xe0,
+ 0x84, 0x65, 0xdc, 0x2d, 0x53, 0xdd, 0x83, 0x13, 0x7b, 0x0d, 0x75, 0xcf,
+ 0x4e, 0x97, 0x8f, 0x84, 0x4f, 0xc3, 0x4e, 0x4d, 0x03, 0xcf, 0xd5, 0xf3,
+ 0x03, 0x59, 0xab, 0x74, 0xdf, 0x4e, 0x7d, 0x3e, 0xcf, 0xd4, 0x73, 0xf7,
+ 0x91, 0x2e, 0x9e, 0x5d, 0x18, 0xdd, 0x74, 0xee, 0xcf, 0xdc, 0x96, 0xcf,
+ 0x76, 0x67, 0xf2, 0x3c, 0x89, 0x84, 0xd3, 0xe1, 0xd1, 0x99, 0xf2, 0x11,
+ 0xc9, 0x56, 0xe2, 0x32, 0x3d, 0xb2, 0x43, 0xa6, 0xcc, 0xfe, 0xa9, 0x83,
+ 0xc2, 0xd8, 0x13, 0x19, 0x2d, 0x78, 0x3a, 0xcc, 0x89, 0x21, 0xd3, 0xe0,
+ 0xf1, 0x60, 0x5d, 0x22, 0x06, 0xe0, 0xfb, 0xeb, 0x61, 0x79, 0xbe, 0x61,
+ 0x48, 0xab, 0xf6, 0xcf, 0x84, 0xb9, 0x06, 0x3b, 0x7c, 0xb6, 0x42, 0x3b,
+ 0xa6, 0xcd, 0x4a, 0xa6, 0x06, 0x3b, 0xbd, 0xa0, 0x7d, 0xb5, 0x9d, 0x7a,
+ 0x2d, 0x16, 0x05, 0xae, 0x98, 0xb6, 0xcc, 0x9a, 0xb4, 0x49, 0x66, 0x52,
+ 0x8a, 0x5c, 0xf7, 0x7c, 0x27, 0xb6, 0x28, 0xdf, 0x85, 0x0d, 0x88, 0x99,
+ 0x4d, 0x71, 0x9e, 0xf0, 0x4d, 0xb0, 0xa6, 0xeb, 0x77, 0x21, 0xf8, 0x5d,
+ 0x21, 0x45, 0x58, 0x29, 0xea, 0x58, 0xd1, 0x80, 0x2d, 0x36, 0xee, 0xee,
+ 0x74, 0x63, 0x5d, 0x04, 0xfe, 0xd9, 0x01, 0x1f, 0xbf, 0x07, 0xfe, 0xd7,
+ 0x67, 0x64, 0xcf, 0x38, 0x0e, 0x62, 0x4f, 0x54, 0x09, 0xfd, 0x0f, 0xbe,
+ 0xde, 0xe0, 0x5a, 0x07, 0xe6, 0xc5, 0x9c, 0xb6, 0xbb, 0xc1, 0x9f, 0xe3,
+ 0x4c, 0xd8, 0x71, 0x29, 0xd9, 0xbb, 0xb0, 0xaf, 0x45, 0xba, 0x2d, 0xda,
+ 0x3b, 0x7d, 0x7a, 0x27, 0xce, 0x33, 0xf8, 0xdd, 0x85, 0xf3, 0x3a, 0x31,
+ 0x17, 0x9b, 0xa6, 0x1f, 0xa7, 0x18, 0xb3, 0xdc, 0xf8, 0x29, 0x72, 0x15,
+ 0xb4, 0x72, 0x8f, 0x86, 0x8b, 0xb4, 0xa5, 0x53, 0x72, 0xa3, 0xdc, 0x2b,
+ 0x57, 0xa2, 0xe4, 0x1f, 0x38, 0x2b, 0x88, 0x87, 0x51, 0x03, 0xf4, 0x93,
+ 0x6e, 0xc6, 0xbf, 0xdd, 0xde, 0xb7, 0x71, 0xaf, 0x7b, 0x86, 0x98, 0xa1,
+ 0x74, 0x97, 0xe4, 0xf4, 0x9c, 0x28, 0x35, 0xba, 0xd3, 0x5b, 0xef, 0x32,
+ 0x0e, 0x9c, 0x51, 0x32, 0xf4, 0x20, 0x62, 0x16, 0xce, 0xba, 0x6c, 0x39,
+ 0xce, 0x65, 0xfb, 0xc7, 0xf0, 0x79, 0x25, 0x2d, 0xd6, 0x7a, 0x97, 0xb4,
+ 0x43, 0x9e, 0x15, 0xa3, 0x49, 0x86, 0x31, 0x39, 0x51, 0xe1, 0x9e, 0xa2,
+ 0x84, 0x2d, 0xc2, 0x10, 0xfe, 0x47, 0x80, 0x0b, 0x49, 0x1b, 0x7c, 0xf1,
+ 0xa2, 0x1d, 0x25, 0xbd, 0xbb, 0x5c, 0xf8, 0x6e, 0x9c, 0x41, 0xda, 0xe9,
+ 0x7b, 0x8e, 0xf6, 0xbd, 0x6c, 0x48, 0x65, 0xc6, 0xe7, 0xe1, 0x49, 0x23,
+ 0x94, 0x77, 0xb6, 0x1b, 0xa1, 0x5f, 0xa6, 0x87, 0x8a, 0xa6, 0xd2, 0xba,
+ 0x16, 0xc9, 0x95, 0xef, 0x95, 0x19, 0x1b, 0xe7, 0x59, 0x61, 0xd0, 0xcc,
+ 0x38, 0x33, 0x50, 0x0c, 0x29, 0x78, 0x58, 0x0f, 0x65, 0xe5, 0xd3, 0xfa,
+ 0x16, 0xce, 0x2b, 0x1a, 0x61, 0x8b, 0x67, 0xfc, 0xb2, 0x27, 0x1f, 0xda,
+ 0x9d, 0x2d, 0xd9, 0x72, 0x07, 0xbf, 0x41, 0x47, 0xbb, 0xa6, 0x23, 0x94,
+ 0xd6, 0xba, 0x33, 0x54, 0xda, 0x8f, 0xff, 0x04, 0xdd, 0x84, 0x07, 0x7c,
+ 0x70, 0xaf, 0x85, 0xbd, 0x11, 0xd0, 0xd8, 0xd9, 0x44, 0x7f, 0x3b, 0xe1,
+ 0x21, 0xab, 0x88, 0x77, 0x86, 0xe6, 0xdb, 0x70, 0xf9, 0xf6, 0x65, 0xf5,
+ 0x2a, 0x64, 0xf5, 0xbe, 0x33, 0xb4, 0x8f, 0x38, 0x52, 0xc0, 0x01, 0xb9,
+ 0x9b, 0x8c, 0x57, 0x8c, 0x51, 0xe6, 0x06, 0x2e, 0xf8, 0x81, 0x0a, 0xa5,
+ 0x3b, 0x24, 0x67, 0xea, 0x1c, 0x00, 0xd8, 0x31, 0xd1, 0x31, 0xde, 0x22,
+ 0x8f, 0xde, 0xb7, 0x95, 0xd0, 0x76, 0x93, 0xaf, 0x32, 0x0f, 0xfc, 0x31,
+ 0x68, 0x5b, 0x4b, 0x28, 0xcd, 0x5a, 0x07, 0x64, 0x2e, 0x91, 0x96, 0xf4,
+ 0x1b, 0xb2, 0x5c, 0x56, 0x7b, 0x5a, 0x65, 0x97, 0x4c, 0x42, 0x46, 0xb5,
+ 0x31, 0xe4, 0xaf, 0x91, 0x0e, 0x09, 0xdd, 0xcf, 0x3c, 0x10, 0x03, 0xad,
+ 0x6b, 0x09, 0x53, 0x6e, 0x39, 0x6a, 0x10, 0xfb, 0x47, 0xa0, 0x87, 0x43,
+ 0xd4, 0xa9, 0xf2, 0xe0, 0x08, 0x13, 0xa2, 0xcc, 0x7b, 0x5a, 0x85, 0xb8,
+ 0xb9, 0x36, 0x1c, 0x33, 0x85, 0xf3, 0xc8, 0x95, 0x93, 0xdc, 0x4b, 0xfe,
+ 0xdc, 0x3d, 0x1f, 0xe6, 0xcf, 0x5f, 0xa7, 0xcc, 0x28, 0x3b, 0xd8, 0x18,
+ 0x78, 0xcc, 0xda, 0xbf, 0xe0, 0xc9, 0xe6, 0x4e, 0xb9, 0x62, 0x8a, 0x51,
+ 0xb3, 0xef, 0x68, 0x92, 0x1f, 0x79, 0xee, 0xde, 0xc2, 0x33, 0x71, 0x6c,
+ 0xcf, 0xf7, 0xe1, 0x2a, 0xcf, 0x74, 0xcf, 0x9e, 0xb1, 0xd6, 0x12, 0x61,
+ 0xd9, 0x2c, 0x5f, 0xe8, 0x52, 0x0a, 0x65, 0xda, 0x46, 0xab, 0xe4, 0x51,
+ 0x8f, 0xd8, 0xfb, 0x10, 0x54, 0x1e, 0x57, 0x32, 0xfa, 0x20, 0x71, 0xfe,
+ 0x23, 0x79, 0x1a, 0x8b, 0x2b, 0x43, 0xf2, 0x3a, 0xf7, 0xfb, 0xfa, 0xe2,
+ 0x5c, 0xb3, 0x6d, 0xbf, 0xea, 0xd9, 0xf6, 0xfb, 0xce, 0xe8, 0x3e, 0x5f,
+ 0xef, 0x90, 0xd7, 0x87, 0xf6, 0x08, 0xf4, 0xfc, 0x7f, 0xed, 0xa1, 0xad,
+ 0x44, 0xb6, 0xec, 0x29, 0x6e, 0xb3, 0x67, 0xb7, 0xc8, 0x2f, 0xd1, 0x87,
+ 0xba, 0xbd, 0x98, 0xe1, 0xfb, 0x94, 0x8f, 0x07, 0xba, 0xd1, 0xb6, 0xca,
+ 0xb9, 0xed, 0x7c, 0x91, 0x38, 0x88, 0x8b, 0x7b, 0x09, 0xe3, 0xe7, 0x54,
+ 0xa8, 0x43, 0xb6, 0xcd, 0xab, 0x18, 0x13, 0x78, 0x57, 0x88, 0x43, 0xcd,
+ 0xf9, 0x95, 0x73, 0x26, 0xbe, 0xc7, 0xf1, 0xb4, 0x24, 0x5f, 0xa7, 0x3f,
+ 0x71, 0x3f, 0xf3, 0xed, 0x4d, 0x2f, 0x7e, 0x76, 0x4c, 0x85, 0xd3, 0x51,
+ 0xc4, 0x4f, 0x99, 0x2c, 0x95, 0x8f, 0xa3, 0x26, 0x92, 0xe2, 0x5d, 0x69,
+ 0xda, 0x47, 0xc7, 0x18, 0x62, 0xe4, 0x64, 0xa9, 0xce, 0xba, 0x08, 0x61,
+ 0x0c, 0xfb, 0x90, 0xa3, 0x23, 0x6a, 0x2e, 0x52, 0xfc, 0x58, 0x9a, 0x71,
+ 0x39, 0x2e, 0xf1, 0xfa, 0x3b, 0xa8, 0x3b, 0x4c, 0xc9, 0x6a, 0x5b, 0xfb,
+ 0xb3, 0x5e, 0xd2, 0x5b, 0x42, 0x0d, 0x11, 0x4e, 0x4b, 0x58, 0xa5, 0x5b,
+ 0x23, 0xd3, 0xa9, 0x0e, 0xd4, 0x5a, 0x13, 0xbd, 0x6a, 0xf5, 0x60, 0x6f,
+ 0x68, 0x75, 0xcf, 0x54, 0x4b, 0xba, 0xd8, 0xab, 0xe6, 0x44, 0x16, 0xcb,
+ 0xa2, 0x50, 0xd7, 0xc4, 0x0e, 0x0b, 0xbe, 0x57, 0x3f, 0xfb, 0x59, 0x95,
+ 0x0e, 0x41, 0xb7, 0x72, 0x6c, 0x29, 0x15, 0x66, 0x0d, 0x19, 0x9f, 0x94,
+ 0x63, 0xa8, 0x1b, 0x9f, 0x91, 0xe9, 0x32, 0xe8, 0xd2, 0x7c, 0xc7, 0xc0,
+ 0x6f, 0x1f, 0x70, 0x93, 0xf6, 0x28, 0x62, 0xac, 0x4b, 0x3b, 0x68, 0xce,
+ 0xe4, 0x58, 0x27, 0xa5, 0x98, 0x57, 0xde, 0x81, 0xfd, 0xd0, 0x5f, 0xfe,
+ 0x59, 0x96, 0xad, 0x1d, 0x92, 0x77, 0xe3, 0x03, 0xed, 0x15, 0x6b, 0x37,
+ 0xbd, 0xb5, 0x6b, 0x58, 0xa3, 0xfd, 0xee, 0x6c, 0xd2, 0xe1, 0x97, 0x75,
+ 0xad, 0x73, 0xd9, 0xe6, 0x3b, 0x61, 0xff, 0x76, 0xd4, 0x85, 0x7d, 0x7d,
+ 0x74, 0xd9, 0xfa, 0xdc, 0x2e, 0x69, 0x37, 0xa9, 0x37, 0x9c, 0x13, 0x65,
+ 0x8c, 0xc5, 0xfa, 0x15, 0x0f, 0xd7, 0x5b, 0xc0, 0xd5, 0x41, 0xba, 0x31,
+ 0xc2, 0x58, 0x07, 0x7d, 0xa8, 0x79, 0xf2, 0x1b, 0xb1, 0x86, 0xb0, 0xdf,
+ 0xf1, 0x70, 0x7d, 0xab, 0x09, 0x17, 0xd7, 0xf8, 0xe4, 0x99, 0x38, 0xbb,
+ 0x9d, 0xbc, 0x91, 0x1f, 0xea, 0x80, 0xfa, 0x48, 0x1a, 0x93, 0x88, 0xed,
+ 0x93, 0x0d, 0x5d, 0xdb, 0x19, 0xb9, 0x0a, 0x6a, 0xae, 0xc6, 0x8b, 0xa0,
+ 0x11, 0xb5, 0x58, 0x63, 0xd0, 0xab, 0xb7, 0x69, 0x47, 0x6b, 0xda, 0x1e,
+ 0x19, 0x77, 0x4a, 0xda, 0xae, 0x2e, 0xb9, 0x76, 0x65, 0x51, 0x37, 0x97,
+ 0x64, 0x6f, 0xbd, 0xba, 0xcb, 0xfd, 0xbf, 0xdb, 0xa6, 0x84, 0xb4, 0x3e,
+ 0x99, 0xdf, 0x68, 0x63, 0x77, 0x22, 0xae, 0x3b, 0xef, 0x32, 0xcf, 0x4c,
+ 0x32, 0x07, 0x4d, 0x32, 0x77, 0x18, 0x5e, 0x3c, 0x8c, 0x37, 0xe1, 0x88,
+ 0x03, 0xc7, 0x8a, 0x67, 0xbf, 0x73, 0x1e, 0x2e, 0xbf, 0xfe, 0xf4, 0x63,
+ 0xea, 0x9f, 0xdf, 0xb5, 0x79, 0x5d, 0x99, 0xee, 0x77, 0xab, 0x8e, 0xc7,
+ 0xb0, 0x75, 0xd0, 0x1f, 0x9f, 0x52, 0xb0, 0xaf, 0x5c, 0xdd, 0xd5, 0x07,
+ 0x7c, 0x1f, 0xb6, 0xc7, 0x57, 0x5f, 0xb7, 0x6e, 0xfd, 0xed, 0xca, 0x80,
+ 0x3a, 0xcd, 0x90, 0xef, 0x4c, 0x98, 0xb4, 0x34, 0x26, 0xb0, 0x5f, 0x8e,
+ 0x30, 0x37, 0xe6, 0xc1, 0xc7, 0x61, 0x73, 0xd8, 0x9c, 0x26, 0xee, 0xa8,
+ 0x00, 0x27, 0x6a, 0xc9, 0x74, 0x9b, 0xa7, 0xe7, 0x6f, 0xf3, 0x7c, 0xe0,
+ 0xde, 0xc9, 0x6f, 0x3c, 0xbf, 0xed, 0xd1, 0x73, 0xa3, 0xcb, 0xa5, 0xc7,
+ 0x5f, 0x1f, 0x34, 0x37, 0x7f, 0xaf, 0xf4, 0x7a, 0xf2, 0xc4, 0xfb, 0x33,
+ 0x1e, 0x5d, 0xd4, 0x4d, 0x33, 0x4d, 0xd4, 0xcb, 0xbb, 0xc0, 0xa3, 0x6b,
+ 0x8d, 0xa2, 0x4a, 0xa3, 0x76, 0x49, 0x31, 0x67, 0x25, 0xc6, 0x32, 0x62,
+ 0x41, 0x27, 0x09, 0x7b, 0x0a, 0xbb, 0x6e, 0x96, 0xa9, 0xe7, 0x5b, 0x88,
+ 0xd5, 0xd4, 0xfb, 0x7b, 0x32, 0x53, 0xee, 0xb7, 0x5b, 0x0d, 0xfa, 0x6b,
+ 0x22, 0xb9, 0x22, 0xc3, 0xf6, 0x8a, 0xae, 0xa1, 0x12, 0xf1, 0x13, 0x42,
+ 0xd9, 0xde, 0x92, 0x01, 0x5d, 0xdb, 0xbc, 0x27, 0x16, 0xe4, 0x32, 0x59,
+ 0x81, 0x8f, 0xed, 0xfb, 0x57, 0x47, 0xd7, 0xa4, 0x08, 0x6f, 0xd7, 0xb7,
+ 0xc1, 0xf5, 0xba, 0xc6, 0x43, 0x7c, 0xcd, 0xb8, 0x0c, 0x69, 0xdb, 0xe7,
+ 0xe3, 0xb3, 0x64, 0xb6, 0xe1, 0xe3, 0x0c, 0x23, 0x2e, 0x23, 0x06, 0xec,
+ 0xfb, 0xbc, 0x67, 0x2f, 0x7c, 0xff, 0xbe, 0xc3, 0x5a, 0x48, 0xa5, 0xbf,
+ 0xea, 0xcd, 0x7d, 0x8f, 0x32, 0xc0, 0xb7, 0x2f, 0xf7, 0x17, 0xbd, 0x78,
+ 0x53, 0x34, 0x32, 0x0d, 0xca, 0x80, 0xb6, 0x02, 0xfd, 0x6b, 0xfb, 0x84,
+ 0xcf, 0x54, 0x3e, 0x89, 0x98, 0xd5, 0xed, 0xd6, 0x0f, 0xe8, 0xaf, 0x32,
+ 0x0d, 0xce, 0xad, 0xb5, 0x65, 0xed, 0x16, 0xcf, 0x97, 0x0e, 0x62, 0x6e,
+ 0x12, 0x7f, 0x94, 0x1d, 0x61, 0x0e, 0xe1, 0x3d, 0xe3, 0xc1, 0xc9, 0x58,
+ 0x16, 0xb9, 0x2b, 0x73, 0x68, 0x1c, 0xdf, 0x86, 0xd7, 0x67, 0x69, 0xb9,
+ 0x57, 0x51, 0xab, 0x40, 0x9e, 0x03, 0xe0, 0x27, 0x2e, 0xe3, 0x0d, 0xe8,
+ 0x7c, 0x23, 0x9e, 0x6d, 0xc0, 0x14, 0x6f, 0xc3, 0xb8, 0xb1, 0x6f, 0xbc,
+ 0xf1, 0xa6, 0xc3, 0x78, 0xf0, 0x57, 0xda, 0x5f, 0xe2, 0xa0, 0xdd, 0xef,
+ 0xd5, 0x32, 0xc6, 0x63, 0x95, 0x09, 0xe3, 0xf1, 0x0a, 0xf7, 0xa8, 0xaf,
+ 0xf5, 0x88, 0x15, 0xcf, 0x2a, 0xd4, 0xa9, 0xfb, 0xba, 0x70, 0xe6, 0x09,
+ 0xd8, 0x46, 0xd1, 0x98, 0x1c, 0xda, 0x25, 0xf9, 0x64, 0x0f, 0x68, 0x7e,
+ 0x08, 0xcf, 0x56, 0xcc, 0xff, 0x3c, 0xe6, 0x61, 0x47, 0x49, 0xfa, 0xc7,
+ 0x0e, 0xdd, 0x5b, 0x4e, 0x99, 0xa4, 0x71, 0xc0, 0xb3, 0xad, 0x37, 0x4d,
+ 0xd7, 0x96, 0x9e, 0xc6, 0xf7, 0x4e, 0xcc, 0x7f, 0x01, 0x4f, 0xe4, 0xb2,
+ 0x7d, 0xfe, 0x3c, 0x7d, 0x70, 0x0c, 0xf3, 0x0f, 0x00, 0xc7, 0x1f, 0xe0,
+ 0xfd, 0x5e, 0xbc, 0xff, 0xde, 0x96, 0xbd, 0xbf, 0xcb, 0xb3, 0x31, 0x9f,
+ 0xdd, 0x32, 0xef, 0xc7, 0x6f, 0x9e, 0x27, 0xd2, 0xbd, 0x0a, 0xc6, 0x57,
+ 0x23, 0xb2, 0x7b, 0xa5, 0x5d, 0x54, 0xcd, 0x8d, 0xe1, 0xaa, 0x66, 0x4a,
+ 0xcf, 0x0a, 0xe3, 0xf7, 0x0f, 0xb0, 0xc7, 0x12, 0xb5, 0x0a, 0xa5, 0x51,
+ 0xb7, 0xda, 0x47, 0x9f, 0x39, 0xba, 0x77, 0x81, 0xcf, 0xe2, 0xd1, 0xd1,
+ 0x3a, 0x61, 0xf8, 0x7e, 0xec, 0xe8, 0xde, 0xfa, 0x3f, 0x00, 0x16, 0x72,
+ 0xa9, 0xf8, 0xf8, 0x09, 0x7f, 0x7e, 0xcb, 0x99, 0x5a, 0xb6, 0x38, 0x93,
+ 0x7e, 0xff, 0xcc, 0xd1, 0x6c, 0x95, 0x75, 0x42, 0x22, 0x26, 0xba, 0x16,
+ 0x2f, 0x1e, 0x2d, 0x20, 0x3f, 0x86, 0x34, 0x2d, 0xfe, 0x3a, 0xd7, 0xa8,
+ 0x87, 0xed, 0x68, 0x23, 0x5d, 0xcd, 0x78, 0x98, 0x67, 0x88, 0xe7, 0x18,
+ 0xf0, 0x24, 0x81, 0x87, 0xf9, 0xc6, 0xa5, 0x37, 0xbe, 0xb0, 0x1d, 0x6d,
+ 0xc4, 0xc5, 0xb3, 0x7c, 0x7c, 0x3d, 0xa2, 0x56, 0x7e, 0x48, 0x7a, 0x4d,
+ 0xd6, 0xb6, 0x6e, 0xac, 0x69, 0x91, 0xfc, 0x69, 0xe6, 0xec, 0x7d, 0xde,
+ 0x37, 0xca, 0x18, 0xf4, 0xdc, 0x71, 0xc5, 0x79, 0x3e, 0xb1, 0x96, 0x62,
+ 0xb9, 0x82, 0xef, 0x45, 0x1f, 0x56, 0x79, 0xb0, 0x9d, 0x4d, 0x7c, 0xb7,
+ 0x78, 0xb2, 0xe6, 0x99, 0x7e, 0xef, 0xd9, 0x4c, 0x0b, 0x40, 0xa1, 0x87,
+ 0xee, 0x0d, 0x3d, 0xf8, 0x7c, 0x62, 0x61, 0x95, 0xb4, 0x25, 0xc1, 0xab,
+ 0x4f, 0xdb, 0x47, 0xd5, 0x1f, 0xf7, 0x26, 0xf1, 0xe7, 0x9f, 0xe7, 0xcb,
+ 0x80, 0x74, 0xf1, 0x09, 0x5b, 0xfe, 0x50, 0xef, 0x9c, 0x84, 0xdf, 0xf1,
+ 0x1e, 0xc4, 0x71, 0x96, 0x6d, 0xca, 0xbe, 0x0d, 0x7a, 0x27, 0x2f, 0x06,
+ 0x7a, 0x09, 0xc5, 0x9a, 0x2e, 0xce, 0x9e, 0xf5, 0x49, 0xb9, 0x0a, 0x5c,
+ 0x19, 0xf4, 0x95, 0x6e, 0x6f, 0x34, 0x85, 0xf8, 0xb8, 0x06, 0xfb, 0xbc,
+ 0x6c, 0xf1, 0x3e, 0x26, 0xcc, 0x7c, 0x27, 0xa5, 0xfa, 0xbf, 0x00, 0x86,
+ 0xf5, 0xd5, 0xed, 0xbb, 0x96, 0x05, 0xc0, 0x2c, 0x62, 0xed, 0x84, 0x1b,
+ 0x97, 0x19, 0xdb, 0x1d, 0x85, 0xda, 0xa3, 0x60, 0xfd, 0xb7, 0xc3, 0x3a,
+ 0xeb, 0x36, 0xec, 0x76, 0x77, 0x21, 0xc8, 0x39, 0xf3, 0x89, 0xd9, 0x05,
+ 0xc4, 0xf0, 0xaa, 0xa5, 0x76, 0x2b, 0x6d, 0x91, 0x89, 0x2a, 0x62, 0x12,
+ 0xba, 0xde, 0x44, 0x7c, 0x41, 0xfe, 0x53, 0xeb, 0xa1, 0xc5, 0x1a, 0x36,
+ 0x7b, 0xd4, 0xe7, 0x68, 0x57, 0x9a, 0xf2, 0xd0, 0x29, 0xe4, 0xe5, 0x91,
+ 0xc7, 0x90, 0x73, 0x20, 0xaf, 0x53, 0x45, 0x74, 0xf2, 0xb4, 0x91, 0x37,
+ 0x7e, 0xab, 0x60, 0xb9, 0x7d, 0x80, 0xce, 0x67, 0xe2, 0xf2, 0x18, 0x3a,
+ 0xd5, 0xa1, 0xe3, 0x4c, 0x5e, 0xc7, 0x9b, 0x7e, 0x73, 0x52, 0xb5, 0xa3,
+ 0xc6, 0x40, 0x01, 0x8a, 0x0a, 0xc7, 0x1c, 0x14, 0xd9, 0x3b, 0x87, 0xb8,
+ 0x82, 0x38, 0xbc, 0x77, 0x15, 0xd1, 0xed, 0x14, 0xe1, 0x95, 0x84, 0x4f,
+ 0x85, 0xa4, 0xe5, 0x14, 0xef, 0x43, 0x64, 0x0f, 0xfa, 0x31, 0xe2, 0xdc,
+ 0x1b, 0xc6, 0x73, 0x1c, 0x7f, 0xfb, 0x51, 0x5b, 0x99, 0xa8, 0x91, 0xb7,
+ 0x81, 0x07, 0x2c, 0xf7, 0x6c, 0x07, 0x6f, 0x76, 0x4b, 0x7b, 0x04, 0x7b,
+ 0x08, 0x1f, 0x06, 0x1d, 0x7b, 0x40, 0x8f, 0x7b, 0x3e, 0x71, 0x84, 0x4f,
+ 0x89, 0xf4, 0xcf, 0x49, 0x8f, 0xd2, 0x7b, 0xc2, 0x52, 0x48, 0x71, 0xad,
+ 0x03, 0xf0, 0xdc, 0x87, 0x35, 0xbd, 0xcf, 0xbd, 0x57, 0xca, 0xdf, 0xa6,
+ 0x1b, 0x73, 0x06, 0xde, 0x51, 0x4f, 0xa5, 0x4c, 0xe9, 0xaf, 0xb9, 0xb0,
+ 0x7b, 0x57, 0xbf, 0xd4, 0xcd, 0xbb, 0x29, 0x65, 0xb9, 0xb4, 0x29, 0xd4,
+ 0xc4, 0x79, 0x48, 0x35, 0x3c, 0xc8, 0xfb, 0x19, 0xc2, 0xb0, 0xaf, 0x35,
+ 0x35, 0x8c, 0x39, 0x48, 0xf9, 0xb9, 0x73, 0x4a, 0xfd, 0x6f, 0xf7, 0x2e,
+ 0xcd, 0x35, 0x85, 0xf6, 0x15, 0xec, 0xff, 0x43, 0xed, 0x2b, 0xa2, 0xe2,
+ 0x9e, 0xaf, 0xe0, 0x7b, 0x91, 0xdf, 0x7e, 0x2e, 0xfe, 0xed, 0xbb, 0xdc,
+ 0x78, 0xef, 0xc8, 0xb4, 0xcd, 0x3b, 0x0c, 0x47, 0x2e, 0xdb, 0x45, 0xe3,
+ 0x91, 0x4d, 0x75, 0x66, 0x52, 0xe7, 0xe7, 0x02, 0x64, 0xbf, 0x5e, 0xd7,
+ 0x3d, 0x9b, 0x5c, 0xa9, 0x47, 0xe4, 0xea, 0x52, 0xbb, 0xac, 0x2f, 0xb8,
+ 0x36, 0xbf, 0xbe, 0x40, 0x3b, 0x37, 0xe5, 0xed, 0x25, 0x0b, 0x6b, 0x49,
+ 0xfc, 0xf5, 0xc8, 0xf5, 0xa5, 0xcd, 0x75, 0xe7, 0x85, 0xc6, 0xc3, 0xa0,
+ 0xa5, 0x47, 0x42, 0x96, 0xa3, 0xfb, 0xaf, 0x1c, 0x72, 0x5f, 0x51, 0xc6,
+ 0x25, 0x5f, 0xe9, 0x47, 0x0f, 0x88, 0xe4, 0x1c, 0x66, 0x0e, 0x82, 0xfe,
+ 0x2b, 0x9f, 0x40, 0x6d, 0x92, 0x80, 0xf3, 0xf4, 0xeb, 0x7b, 0xc5, 0x4f,
+ 0x85, 0x7b, 0xa4, 0xd5, 0xfa, 0xa3, 0x6e, 0x37, 0x57, 0x99, 0x6e, 0x9f,
+ 0x6a, 0xf9, 0xf9, 0xfa, 0x75, 0xe0, 0x1e, 0x81, 0x9d, 0xd2, 0x36, 0x6d,
+ 0xd8, 0xac, 0x29, 0xcb, 0x43, 0x89, 0x6a, 0x51, 0x18, 0x1f, 0x52, 0x38,
+ 0xd3, 0xc0, 0xbe, 0x24, 0xe4, 0xb1, 0x43, 0xd7, 0x42, 0x19, 0x05, 0xdd,
+ 0xce, 0xcd, 0x48, 0xbe, 0xf1, 0x9b, 0x98, 0xcf, 0xc8, 0x54, 0x63, 0x0c,
+ 0x67, 0x9d, 0xa4, 0xdd, 0xf6, 0x48, 0x3b, 0xcf, 0x49, 0x81, 0xc6, 0x87,
+ 0xa4, 0x70, 0x7a, 0x46, 0x0e, 0x57, 0x48, 0x27, 0xef, 0x19, 0x13, 0xc9,
+ 0x9c, 0x0c, 0xc7, 0x97, 0x50, 0x3b, 0xb9, 0xfe, 0x98, 0x96, 0xc2, 0x19,
+ 0xe0, 0xa8, 0xf0, 0x1e, 0xa0, 0x1f, 0x76, 0x33, 0xac, 0xfb, 0x9a, 0x29,
+ 0x1d, 0x77, 0x38, 0xff, 0x43, 0xe8, 0xa9, 0xbf, 0xb8, 0x1f, 0x70, 0x79,
+ 0xf4, 0x40, 0x93, 0xa8, 0x97, 0x17, 0x2b, 0xe8, 0xf7, 0xec, 0x10, 0x6b,
+ 0x2f, 0xa5, 0xee, 0xef, 0x93, 0x5a, 0x65, 0xd8, 0x54, 0x8a, 0x35, 0x15,
+ 0x75, 0xc1, 0x35, 0xfa, 0x77, 0x4c, 0x85, 0xad, 0x3e, 0x59, 0xaa, 0x14,
+ 0xd1, 0x37, 0x2b, 0xef, 0x5e, 0x03, 0x16, 0x60, 0xb9, 0x71, 0x2f, 0xa3,
+ 0xc8, 0x37, 0xea, 0xcf, 0xc6, 0x27, 0x41, 0x63, 0x26, 0x6e, 0xca, 0x71,
+ 0xd0, 0x87, 0xf7, 0x45, 0xd8, 0xf8, 0x1c, 0x6b, 0xb8, 0x0c, 0xd6, 0xd2,
+ 0x72, 0xe4, 0xec, 0x24, 0x68, 0xe8, 0x92, 0xfe, 0x3f, 0xa1, 0x8f, 0x3d,
+ 0x81, 0x39, 0x7e, 0x27, 0x60, 0xaf, 0x5f, 0xc4, 0x3b, 0x61, 0x63, 0x78,
+ 0x52, 0x0e, 0x7d, 0x78, 0x9a, 0xa0, 0x25, 0xe2, 0xf6, 0x26, 0x87, 0xe2,
+ 0x52, 0x3b, 0xfd, 0xa0, 0x4c, 0x2d, 0x3e, 0x08, 0xfc, 0x3f, 0x42, 0x5f,
+ 0x80, 0xfc, 0xb6, 0xc8, 0xb3, 0x58, 0xff, 0xf1, 0x9c, 0x9d, 0x3d, 0xda,
+ 0x37, 0xe6, 0x38, 0xcf, 0xe7, 0x41, 0xec, 0x47, 0x8f, 0x51, 0xc9, 0x48,
+ 0xa1, 0xc2, 0xb3, 0xa0, 0x3b, 0xd4, 0x53, 0xf9, 0xd3, 0x93, 0x9e, 0x8e,
+ 0x7b, 0x24, 0x17, 0x2d, 0xb2, 0xbf, 0x40, 0x9e, 0x58, 0x18, 0xcd, 0x96,
+ 0x13, 0x66, 0x56, 0x11, 0x57, 0x52, 0x98, 0x1b, 0xdc, 0xb9, 0x88, 0x58,
+ 0x73, 0xe8, 0x6d, 0xd3, 0x5c, 0x3b, 0xee, 0xdd, 0x1d, 0x10, 0xd7, 0x9b,
+ 0x32, 0x0e, 0x1b, 0xeb, 0x9f, 0x1b, 0x41, 0x2d, 0xfc, 0x16, 0x6a, 0xc9,
+ 0x84, 0x27, 0x83, 0x31, 0xcf, 0x36, 0xda, 0x9b, 0x6c, 0x02, 0x7a, 0xae,
+ 0x40, 0xf7, 0x15, 0xd8, 0x01, 0x62, 0xf5, 0x2b, 0x1b, 0xf6, 0x31, 0xd6,
+ 0x54, 0x63, 0x76, 0xca, 0xdf, 0x54, 0x13, 0xc9, 0x35, 0xd8, 0xcf, 0x75,
+ 0xf4, 0x02, 0x6b, 0xe8, 0x55, 0xd7, 0xd1, 0xd7, 0x2d, 0x96, 0x0f, 0x81,
+ 0x7e, 0xd6, 0x94, 0xfc, 0x8e, 0xe9, 0x5a, 0xa7, 0xcd, 0x7a, 0xe1, 0x2e,
+ 0x7d, 0xb7, 0x2b, 0x4f, 0xf4, 0xb0, 0xd7, 0x64, 0x5f, 0xce, 0x7b, 0xe9,
+ 0xab, 0xd0, 0xe3, 0x9a, 0xc9, 0x75, 0x7f, 0x1f, 0x7b, 0x01, 0xdf, 0x7e,
+ 0x48, 0x0b, 0xed, 0x87, 0x7b, 0x08, 0xd3, 0xa3, 0xfd, 0x24, 0xaf, 0xf1,
+ 0xd1, 0x66, 0xeb, 0xdd, 0xae, 0x9f, 0xe9, 0x3a, 0xcb, 0xbc, 0x22, 0xbe,
+ 0xfd, 0xbe, 0xe7, 0xb0, 0xaf, 0xcb, 0x0e, 0x21, 0x76, 0x37, 0x1c, 0x79,
+ 0xc1, 0xde, 0xec, 0x77, 0x07, 0x2a, 0xbe, 0x9c, 0x28, 0xc7, 0x43, 0x72,
+ 0xa2, 0x91, 0x80, 0x4f, 0x50, 0x86, 0x56, 0x93, 0x0c, 0x45, 0xbe, 0x5e,
+ 0x11, 0x79, 0xb9, 0xc2, 0x35, 0x2d, 0xc3, 0x58, 0x36, 0xd4, 0xce, 0xbb,
+ 0x75, 0xd8, 0xe5, 0xdf, 0xcb, 0xe1, 0x79, 0x91, 0xb3, 0x58, 0x5f, 0xae,
+ 0xd0, 0x57, 0x47, 0x50, 0xbf, 0xee, 0x94, 0xda, 0x02, 0x7a, 0xb2, 0x8a,
+ 0x4c, 0x65, 0x1f, 0x60, 0xbe, 0x89, 0xc8, 0xba, 0xbe, 0x93, 0x15, 0x19,
+ 0x3c, 0x17, 0x96, 0xf0, 0x39, 0x34, 0x7f, 0x90, 0xfd, 0xf9, 0x21, 0xff,
+ 0x8e, 0xd6, 0xf5, 0xf9, 0x52, 0x19, 0x7b, 0x2b, 0xfd, 0x3a, 0x4e, 0x96,
+ 0xea, 0x05, 0xc9, 0x57, 0x79, 0x16, 0x9e, 0x0b, 0x71, 0xac, 0xa5, 0x64,
+ 0xfa, 0xf4, 0x88, 0x3c, 0x8b, 0x33, 0xd0, 0xff, 0xe1, 0x8c, 0x71, 0x29,
+ 0x9e, 0xc5, 0x7c, 0xfd, 0x9a, 0x2c, 0x2c, 0x15, 0xa4, 0x56, 0xbd, 0xd0,
+ 0x74, 0xf7, 0x8e, 0xef, 0x85, 0xe6, 0x5e, 0xf6, 0x10, 0xfb, 0x19, 0xf4,
+ 0xaa, 0x16, 0xbe, 0x21, 0xb3, 0xfa, 0xf4, 0xd4, 0xe6, 0x3b, 0xe3, 0xe6,
+ 0x1e, 0x76, 0x42, 0x66, 0x2b, 0x29, 0x29, 0x9d, 0x1e, 0xd1, 0x77, 0x0d,
+ 0x6d, 0xe9, 0xea, 0xd3, 0x37, 0x90, 0x2b, 0x26, 0xf4, 0x9d, 0xf1, 0x2d,
+ 0x79, 0xd4, 0x9e, 0x95, 0x27, 0xad, 0x83, 0x72, 0x02, 0xf5, 0xf5, 0xa7,
+ 0xd1, 0xeb, 0xc7, 0xbb, 0xa9, 0x47, 0xd0, 0x6b, 0xb1, 0x07, 0x75, 0x64,
+ 0xdc, 0xfe, 0xb8, 0xf9, 0x3c, 0x24, 0x7b, 0xb5, 0xce, 0x3c, 0xf9, 0x5f,
+ 0x4e, 0x06, 0x79, 0xef, 0x06, 0x7a, 0xc7, 0x8c, 0x86, 0x33, 0x5c, 0xb8,
+ 0x2a, 0xe1, 0x86, 0xcd, 0x17, 0x08, 0xb7, 0x60, 0x78, 0x70, 0x06, 0xe0,
+ 0x42, 0x72, 0xd1, 0x0e, 0xc3, 0x46, 0x26, 0xc0, 0x27, 0x62, 0xfc, 0x68,
+ 0xa7, 0x57, 0x07, 0xef, 0x40, 0x6e, 0xbd, 0xbd, 0xff, 0x35, 0x6f, 0xff,
+ 0xb3, 0xde, 0xfe, 0xcb, 0x1b, 0xfb, 0xfd, 0xfc, 0xfa, 0x13, 0x47, 0x9a,
+ 0xe8, 0x7a, 0xad, 0xec, 0xc2, 0xcf, 0x7a, 0x74, 0x5d, 0xde, 0xa0, 0xcb,
+ 0x87, 0x87, 0x3c, 0x35, 0xcf, 0x8c, 0xcd, 0x8c, 0xd1, 0xfd, 0x90, 0xa3,
+ 0x23, 0x39, 0x1b, 0xbe, 0x51, 0x49, 0x8c, 0x15, 0xf5, 0x9d, 0x9a, 0x92,
+ 0xb5, 0xe8, 0xac, 0x4c, 0x58, 0x89, 0xb1, 0x69, 0x09, 0xc1, 0x96, 0x19,
+ 0x5b, 0x42, 0x52, 0x63, 0xcc, 0xc1, 0x33, 0x6f, 0x6f, 0x4f, 0xeb, 0xd5,
+ 0x26, 0x5a, 0x43, 0x2f, 0x91, 0x46, 0x97, 0xd6, 0xc8, 0xc0, 0x6d, 0x5a,
+ 0x5d, 0x78, 0x97, 0xd6, 0xab, 0xe5, 0x26, 0xf8, 0x73, 0x61, 0x0f, 0x3e,
+ 0xdc, 0x04, 0x4f, 0x7b, 0x66, 0x5d, 0x41, 0x7b, 0x26, 0x6d, 0x3f, 0x0b,
+ 0xdf, 0x90, 0xc8, 0x8e, 0x74, 0xf5, 0xe8, 0x7d, 0x03, 0x8e, 0x44, 0x50,
+ 0x6f, 0xb4, 0x62, 0x6d, 0xbd, 0xca, 0x5a, 0x44, 0xed, 0x6d, 0x95, 0x41,
+ 0xd8, 0x2c, 0x75, 0xe7, 0xde, 0x0d, 0x3e, 0xaa, 0x6b, 0x02, 0x47, 0x9e,
+ 0xb4, 0x49, 0xcb, 0x8f, 0x9d, 0x97, 0xa3, 0x83, 0x76, 0x49, 0x86, 0xcc,
+ 0x56, 0x9c, 0x5f, 0x6b, 0x68, 0x9c, 0x49, 0xd2, 0xb2, 0x32, 0xd4, 0x6f,
+ 0x7e, 0x0f, 0x7c, 0x8e, 0x57, 0x0d, 0xa9, 0x59, 0x89, 0xd8, 0x79, 0xe0,
+ 0xd8, 0x0f, 0xdd, 0xd4, 0x46, 0x48, 0x8f, 0xc8, 0x61, 0xd8, 0x77, 0x4d,
+ 0xe7, 0x45, 0xda, 0x71, 0x62, 0xa2, 0x88, 0x5a, 0xe7, 0x2f, 0x75, 0x6e,
+ 0x73, 0x9c, 0x1b, 0xc8, 0x6f, 0x13, 0x5b, 0x6c, 0x4f, 0x9d, 0x73, 0x6d,
+ 0x4f, 0x9d, 0x43, 0x0f, 0x7c, 0x32, 0x22, 0x6d, 0xcb, 0xf0, 0x9f, 0x97,
+ 0xf6, 0xb8, 0xf5, 0xdc, 0x4b, 0xfc, 0xdd, 0x09, 0xf1, 0xee, 0x64, 0x58,
+ 0xac, 0x93, 0x3a, 0x1f, 0x40, 0xde, 0xe3, 0x32, 0x7d, 0x86, 0x31, 0xd5,
+ 0x92, 0x81, 0x93, 0xd4, 0x07, 0xeb, 0x9a, 0x85, 0xd1, 0x02, 0x7c, 0x64,
+ 0x06, 0x71, 0x41, 0x2d, 0xdf, 0x94, 0x82, 0x45, 0x39, 0x74, 0x49, 0xfb,
+ 0x32, 0xfa, 0xf1, 0x65, 0xc4, 0x86, 0xe5, 0x98, 0xb4, 0xc0, 0xb7, 0xd4,
+ 0xb9, 0xa8, 0x51, 0x9a, 0x7f, 0x17, 0xfe, 0xc0, 0xdf, 0x70, 0x50, 0x5b,
+ 0x9e, 0x8b, 0x19, 0xf4, 0x2d, 0x75, 0x8e, 0x76, 0x8e, 0x72, 0xea, 0x1c,
+ 0xed, 0x9c, 0x74, 0xf8, 0xfe, 0x82, 0xf7, 0x73, 0x23, 0xfa, 0x9e, 0xfa,
+ 0x86, 0x4d, 0x5e, 0x7e, 0x20, 0xd9, 0x2a, 0x6b, 0x44, 0xf2, 0x23, 0xdd,
+ 0xa8, 0x65, 0x76, 0x65, 0xed, 0x81, 0xb1, 0x75, 0xf9, 0xa8, 0x7c, 0xdd,
+ 0xf9, 0x11, 0xf8, 0x22, 0x1f, 0xcd, 0x7c, 0x91, 0xa7, 0x2e, 0x69, 0xd1,
+ 0x7c, 0xf9, 0xfc, 0x40, 0xd0, 0xe0, 0x67, 0xef, 0xc9, 0x18, 0xf0, 0x7f,
+ 0x11, 0x31, 0xa0, 0x0f, 0xcf, 0x27, 0xf0, 0x44, 0x4a, 0x3b, 0x47, 0xde,
+ 0xc9, 0xeb, 0x75, 0xd4, 0x8d, 0x3e, 0x9f, 0x53, 0x78, 0x7f, 0x55, 0xa6,
+ 0xe7, 0x9d, 0xe3, 0xc8, 0xab, 0xbc, 0x43, 0xef, 0x71, 0xef, 0x83, 0xb7,
+ 0xf2, 0xfe, 0xaa, 0xb8, 0xf2, 0x49, 0x98, 0x35, 0xc1, 0xfb, 0xd2, 0x56,
+ 0x59, 0x34, 0xc7, 0x8e, 0x98, 0xae, 0xc3, 0x0f, 0xd7, 0x19, 0x27, 0x28,
+ 0xa3, 0xeb, 0x92, 0x9d, 0xe7, 0xfd, 0x97, 0x8b, 0x6f, 0xaa, 0xee, 0xc7,
+ 0x8d, 0xe6, 0x3d, 0x36, 0xe0, 0xfa, 0x00, 0x47, 0xba, 0xd6, 0x28, 0x3f,
+ 0xc4, 0x9c, 0xde, 0xa6, 0x58, 0xd3, 0xbc, 0x6f, 0x4c, 0x9e, 0x43, 0x1d,
+ 0xf0, 0x9a, 0xbd, 0x49, 0xae, 0x53, 0xac, 0x85, 0x6a, 0xf5, 0x49, 0xf8,
+ 0x64, 0x0b, 0x62, 0x99, 0x29, 0xeb, 0xe5, 0x56, 0xa9, 0xa1, 0xde, 0x59,
+ 0x5c, 0x62, 0x2c, 0x24, 0xed, 0xed, 0x98, 0x77, 0xe3, 0x17, 0x63, 0xed,
+ 0x7a, 0x19, 0x79, 0x16, 0xbe, 0xbd, 0x5e, 0x8e, 0xe2, 0xd9, 0x87, 0xa7,
+ 0x85, 0x67, 0x1c, 0xcf, 0x24, 0x9e, 0x23, 0x78, 0x8e, 0xe0, 0x69, 0x61,
+ 0x6f, 0x0c, 0x4f, 0xbf, 0x67, 0x20, 0xae, 0xdb, 0x7c, 0x97, 0xf4, 0x79,
+ 0xa8, 0x15, 0x2d, 0xe6, 0xb4, 0xb0, 0x9d, 0x43, 0x1f, 0x91, 0x1d, 0x61,
+ 0xad, 0xc7, 0x9a, 0xef, 0x03, 0xc7, 0xb4, 0xd8, 0x97, 0x17, 0x8d, 0xfd,
+ 0x43, 0xcc, 0x0b, 0x55, 0xe4, 0x85, 0xf7, 0x76, 0xa3, 0x7f, 0x34, 0x0f,
+ 0xe8, 0xbb, 0xa3, 0x79, 0x7c, 0xf3, 0x1d, 0x3d, 0x6f, 0x74, 0x06, 0x79,
+ 0x8a, 0xf1, 0xd3, 0xc1, 0x9e, 0x3c, 0xe2, 0xf8, 0x2e, 0xf8, 0x5f, 0x06,
+ 0x71, 0x1b, 0xef, 0x0b, 0x97, 0x76, 0xbb, 0x39, 0x15, 0xf9, 0x56, 0x6d,
+ 0xbd, 0xaf, 0xb1, 0xb1, 0x67, 0xbb, 0xde, 0xa0, 0x13, 0x38, 0x12, 0xd5,
+ 0x05, 0xf8, 0xe0, 0xf7, 0xed, 0xe3, 0xba, 0xb6, 0xa3, 0x2e, 0x9e, 0x45,
+ 0x8d, 0x9a, 0x9b, 0x63, 0x0d, 0x73, 0x0c, 0x7d, 0x09, 0xfa, 0xb3, 0x28,
+ 0x7b, 0x72, 0xe6, 0x02, 0x5d, 0x8b, 0x46, 0xa5, 0x9d, 0x79, 0xe0, 0x06,
+ 0xce, 0x03, 0x5f, 0x8b, 0x0e, 0x64, 0xf6, 0x08, 0x6a, 0x42, 0xc7, 0x09,
+ 0x5b, 0xfb, 0x25, 0xfe, 0x38, 0x63, 0x8e, 0x60, 0xbf, 0x29, 0xee, 0xbd,
+ 0x3a, 0xe2, 0xee, 0xa4, 0xfe, 0xbd, 0x18, 0xc6, 0x65, 0x63, 0xef, 0x1d,
+ 0xc0, 0xc5, 0x79, 0xde, 0x69, 0x8b, 0xec, 0x9f, 0x73, 0x6b, 0x5a, 0x65,
+ 0x35, 0xe3, 0xfb, 0x39, 0x0f, 0x1f, 0xd7, 0x95, 0xf7, 0xdb, 0xc6, 0x1e,
+ 0xc8, 0x08, 0xfe, 0x00, 0x1d, 0x9f, 0x40, 0xfd, 0x7c, 0x11, 0x7a, 0x79,
+ 0x0d, 0x3a, 0xb9, 0x54, 0xa6, 0xad, 0x0f, 0xc3, 0xee, 0x21, 0xc3, 0x49,
+ 0xe2, 0x1a, 0xd1, 0x67, 0x5f, 0x2c, 0x23, 0x76, 0x32, 0xfe, 0xa9, 0x5f,
+ 0x8d, 0xb2, 0x3e, 0x64, 0x1e, 0x74, 0xf1, 0xf4, 0xb9, 0x70, 0xe2, 0xaf,
+ 0xed, 0xd6, 0xf4, 0xd4, 0xf4, 0x3d, 0x18, 0xe5, 0x04, 0x1b, 0xe4, 0x6f,
+ 0x04, 0x1a, 0xe6, 0x0b, 0x51, 0x7d, 0x0f, 0xaf, 0x38, 0x47, 0x3e, 0x46,
+ 0x24, 0x3b, 0xe7, 0xef, 0xeb, 0xc6, 0xbe, 0x1d, 0x4d, 0xb8, 0xee, 0xdc,
+ 0xc2, 0x83, 0xf2, 0x78, 0xe0, 0xfa, 0xd6, 0xba, 0x3f, 0x61, 0x16, 0x37,
+ 0xee, 0x86, 0x99, 0x7f, 0xa9, 0x9b, 0x14, 0xf6, 0xfb, 0xfa, 0xe9, 0xf3,
+ 0x7a, 0x81, 0xc4, 0x6c, 0x51, 0x58, 0xab, 0x50, 0x47, 0x63, 0xf0, 0x6b,
+ 0x13, 0xf8, 0x6d, 0xa9, 0x96, 0xdb, 0x44, 0xf5, 0xb0, 0x37, 0x66, 0xad,
+ 0xdc, 0x7c, 0xe6, 0xaf, 0x78, 0x67, 0xa2, 0x9f, 0x3e, 0xc5, 0xba, 0x59,
+ 0xe7, 0x19, 0xc0, 0x74, 0x6c, 0xa1, 0xed, 0x17, 0x3d, 0x38, 0xae, 0x27,
+ 0xa5, 0x88, 0x3a, 0x34, 0x37, 0x87, 0x8a, 0x1e, 0xf1, 0x5b, 0xa5, 0xf9,
+ 0xbb, 0x16, 0xef, 0xf0, 0x86, 0xe3, 0xd3, 0xa0, 0xb1, 0x68, 0x66, 0x78,
+ 0x6f, 0x06, 0x1c, 0xbd, 0x5b, 0x70, 0x8c, 0x7b, 0x38, 0xc6, 0xa5, 0x74,
+ 0x66, 0x02, 0xbe, 0x96, 0x41, 0x7e, 0xef, 0x37, 0x1f, 0x91, 0x4f, 0xa0,
+ 0xb9, 0xc6, 0xdc, 0xd9, 0x11, 0xe8, 0xc9, 0x71, 0xf6, 0xdb, 0x87, 0x40,
+ 0xf7, 0x77, 0x90, 0x5b, 0xfd, 0x9a, 0xa7, 0x14, 0x0b, 0x21, 0x87, 0x1d,
+ 0xd1, 0xbf, 0xc3, 0x16, 0x4d, 0x13, 0xf6, 0xaa, 0x8c, 0xe1, 0x24, 0xda,
+ 0x7b, 0xe4, 0xb7, 0x59, 0xe4, 0x2a, 0xf2, 0xd9, 0x29, 0x25, 0xd3, 0x78,
+ 0x38, 0x84, 0xba, 0x26, 0x3b, 0x47, 0x3f, 0x92, 0x81, 0x50, 0xba, 0x15,
+ 0x35, 0xa9, 0x23, 0x6f, 0xdb, 0xfc, 0x77, 0x0a, 0xb3, 0x72, 0xb1, 0x6e,
+ 0xe2, 0xf9, 0x5d, 0xe8, 0xe1, 0x4f, 0xf1, 0xfe, 0x76, 0x0f, 0xea, 0x3e,
+ 0xac, 0x64, 0x60, 0xbb, 0x49, 0x5d, 0xcf, 0xb0, 0x8e, 0xa8, 0x21, 0xdf,
+ 0x2a, 0xe4, 0x1a, 0xd4, 0x55, 0x63, 0xac, 0x5d, 0x9f, 0x5b, 0xbc, 0x26,
+ 0x97, 0xe6, 0xf9, 0x3b, 0x28, 0xf3, 0xf2, 0x41, 0xc6, 0x03, 0x73, 0x26,
+ 0x85, 0xb9, 0x25, 0xc6, 0x32, 0x7c, 0x37, 0xe0, 0x40, 0x3d, 0xa8, 0x11,
+ 0x50, 0x6b, 0xaf, 0x5b, 0x49, 0xf0, 0x79, 0x4d, 0x2e, 0xce, 0x87, 0x65,
+ 0xd1, 0x62, 0x5d, 0x24, 0xf1, 0x2c, 0x60, 0x2f, 0x2e, 0xfd, 0x93, 0x6b,
+ 0x13, 0x84, 0x47, 0xcf, 0x53, 0x44, 0x5d, 0xf7, 0x88, 0xde, 0xfb, 0xd3,
+ 0xf4, 0x4c, 0x9a, 0x9a, 0xfb, 0xbc, 0x82, 0x5c, 0xa4, 0x3f, 0xe9, 0xdf,
+ 0x28, 0x58, 0x1b, 0x1c, 0x83, 0xcd, 0xb2, 0x76, 0x67, 0x3f, 0x80, 0xf7,
+ 0x3a, 0xd7, 0xc9, 0x3b, 0x9e, 0x0b, 0xfd, 0x90, 0x0d, 0xfd, 0x9e, 0x77,
+ 0x62, 0xc8, 0xa3, 0x8a, 0xbe, 0x5e, 0xd2, 0xb1, 0xa0, 0x54, 0x29, 0x20,
+ 0xa7, 0x20, 0x06, 0xd8, 0xbd, 0xb0, 0xc5, 0x49, 0xe8, 0x72, 0x0c, 0x70,
+ 0x5b, 0x72, 0xc9, 0x6a, 0x49, 0xd7, 0x65, 0x6a, 0xe5, 0xf6, 0xfd, 0x4d,
+ 0x1e, 0xfe, 0xa3, 0x56, 0x61, 0x5b, 0xf0, 0x21, 0xb5, 0x1a, 0xc5, 0x13,
+ 0xf1, 0x78, 0x15, 0xfd, 0x45, 0x99, 0xf7, 0x43, 0xe8, 0x0d, 0xca, 0xbc,
+ 0x3b, 0x49, 0xe2, 0x39, 0xc2, 0xfb, 0x22, 0x2f, 0xae, 0x11, 0x3f, 0xe9,
+ 0xf0, 0xe3, 0x0b, 0x6b, 0x49, 0xc6, 0x17, 0xbf, 0x9e, 0x74, 0x6d, 0xe1,
+ 0x44, 0x85, 0x31, 0x84, 0x76, 0xdd, 0x8f, 0xb8, 0x45, 0x5b, 0x70, 0x6b,
+ 0xc9, 0xa5, 0xaa, 0x2b, 0xb3, 0xe9, 0xc6, 0x05, 0x9d, 0x23, 0x0e, 0x88,
+ 0x05, 0x1b, 0xa3, 0xec, 0xb0, 0xa6, 0x73, 0xc0, 0x79, 0xc9, 0xe8, 0x27,
+ 0x65, 0xf6, 0xaa, 0x64, 0x96, 0x46, 0xe4, 0x05, 0x1d, 0xb7, 0xfc, 0x98,
+ 0xc5, 0x1a, 0x92, 0xbf, 0x1f, 0x27, 0xe5, 0xf9, 0xd3, 0xd7, 0x24, 0xfb,
+ 0x22, 0xe3, 0xd6, 0x70, 0x6c, 0x87, 0xc1, 0x58, 0xe5, 0x48, 0x1d, 0xb9,
+ 0xe9, 0x11, 0x9b, 0xff, 0x16, 0x20, 0x84, 0x9e, 0xce, 0x91, 0xd6, 0xd1,
+ 0x84, 0x1d, 0x37, 0xfa, 0x9f, 0xd8, 0x61, 0x30, 0x37, 0x0e, 0x9b, 0x4f,
+ 0x89, 0x7f, 0x1f, 0xd5, 0x26, 0x4f, 0xe9, 0xbb, 0x0a, 0xb8, 0xed, 0xdc,
+ 0xfb, 0xfa, 0x77, 0x94, 0x1b, 0x29, 0xca, 0x1a, 0xdf, 0xab, 0x9c, 0x2f,
+ 0x46, 0x6e, 0xa4, 0x5a, 0xa4, 0x74, 0x87, 0xe3, 0x3c, 0x39, 0xfa, 0xc0,
+ 0x6e, 0xf7, 0xdf, 0x8b, 0x3c, 0x7d, 0x87, 0x1b, 0x0b, 0x7e, 0xcd, 0xfb,
+ 0xfe, 0x3a, 0x9e, 0xb4, 0x6d, 0xe6, 0x5b, 0xe6, 0x47, 0xea, 0x0d, 0xcf,
+ 0x25, 0xbe, 0x33, 0xf7, 0xce, 0x22, 0xf7, 0x32, 0x5f, 0xee, 0x92, 0x1c,
+ 0x7f, 0xe7, 0x53, 0x7a, 0xbe, 0xe8, 0xd6, 0xd2, 0x1e, 0x5c, 0x75, 0x4a,
+ 0xa6, 0xab, 0xac, 0xa1, 0x2e, 0x22, 0x97, 0x0d, 0xc1, 0x56, 0x99, 0xd3,
+ 0x8e, 0x23, 0x9f, 0xf3, 0xf7, 0x69, 0xac, 0x2d, 0x70, 0x5f, 0x22, 0x19,
+ 0x57, 0xcd, 0xbf, 0x2b, 0xdd, 0x8c, 0xf2, 0x3e, 0xea, 0xfc, 0x10, 0xf4,
+ 0xfe, 0x15, 0xf6, 0x16, 0x03, 0xda, 0x46, 0xb2, 0x2f, 0x51, 0xf6, 0xee,
+ 0xef, 0xd7, 0xd2, 0xed, 0xfa, 0x00, 0xeb, 0x80, 0xcf, 0x40, 0x2e, 0x07,
+ 0xec, 0x6b, 0xcc, 0xdd, 0xff, 0xa6, 0xac, 0xe1, 0xe4, 0x53, 0x06, 0x7d,
+ 0x1b, 0xdf, 0x4b, 0x21, 0x59, 0x88, 0x92, 0x7f, 0xc8, 0xcb, 0xa0, 0xef,
+ 0x6c, 0x27, 0x87, 0xad, 0x32, 0xf8, 0x0b, 0xc8, 0x80, 0xb2, 0xf4, 0x65,
+ 0xc0, 0xf7, 0x09, 0xe8, 0x8b, 0x3d, 0x43, 0xbf, 0xee, 0x23, 0x4b, 0x0d,
+ 0xf7, 0xec, 0x52, 0xa5, 0x99, 0x66, 0xd2, 0x4b, 0x9d, 0x9e, 0x97, 0x9c,
+ 0xd6, 0xef, 0xac, 0xe4, 0xaa, 0xe7, 0x65, 0x7f, 0x75, 0x56, 0x1e, 0xb5,
+ 0x1e, 0x06, 0xbf, 0x57, 0x9c, 0x82, 0xa5, 0x7b, 0x95, 0xb1, 0x3c, 0xce,
+ 0x2e, 0x8c, 0xf4, 0xca, 0x4d, 0xd4, 0x1d, 0xcf, 0x2e, 0x9a, 0xf2, 0x3f,
+ 0x9d, 0x5b, 0x5f, 0x6c, 0x5b, 0xd5, 0x19, 0xff, 0x7c, 0x6d, 0x27, 0x69,
+ 0x68, 0xc2, 0xad, 0xeb, 0x24, 0x6e, 0x9a, 0x51, 0x3b, 0xbe, 0x6d, 0x23,
+ 0x92, 0xa2, 0xdb, 0x10, 0x68, 0xd4, 0x65, 0x8a, 0x71, 0x42, 0x17, 0xb6,
+ 0x22, 0xd2, 0xae, 0xab, 0x2a, 0x8d, 0x81, 0xe5, 0xa6, 0x7f, 0xd8, 0xc3,
+ 0x0a, 0x85, 0x75, 0x08, 0x21, 0xd5, 0xb8, 0xe9, 0xd6, 0x69, 0x21, 0x4e,
+ 0xff, 0x2d, 0x8c, 0x87, 0xcd, 0x4a, 0xd2, 0x96, 0x4d, 0x11, 0x2e, 0x88,
+ 0xb2, 0x3d, 0x6c, 0xa3, 0x4a, 0x01, 0xed, 0x79, 0x7b, 0x99, 0x34, 0x36,
+ 0x65, 0x05, 0x36, 0x5e, 0x36, 0xf5, 0x81, 0x07, 0xa6, 0xd1, 0x79, 0xbf,
+ 0xdf, 0x77, 0xee, 0x75, 0x6c, 0x13, 0x84, 0xb4, 0x48, 0x91, 0xef, 0x39,
+ 0xf7, 0xdc, 0x73, 0xce, 0x3d, 0xdf, 0xff, 0xef, 0xfb, 0xdd, 0x8c, 0x3d,
+ 0x28, 0x3f, 0xd2, 0x5c, 0x3e, 0xe3, 0x93, 0x00, 0x7c, 0x52, 0x83, 0x2d,
+ 0x90, 0x36, 0x27, 0x76, 0x53, 0xe8, 0x53, 0x86, 0x41, 0xeb, 0xb8, 0xf1,
+ 0x9b, 0x6d, 0x73, 0x7f, 0xcb, 0x59, 0xf8, 0xee, 0xee, 0x7d, 0x6d, 0x7e,
+ 0xce, 0xd7, 0xf8, 0xb7, 0x7f, 0xf2, 0x6a, 0x68, 0x83, 0x32, 0x83, 0xfd,
+ 0xbc, 0xa1, 0x7a, 0xd6, 0x01, 0x2f, 0x31, 0x37, 0x1d, 0xd3, 0xfc, 0x43,
+ 0x78, 0x9a, 0x3a, 0xea, 0x2a, 0x74, 0xd4, 0x10, 0x75, 0xd7, 0xf0, 0xbc,
+ 0xcb, 0xfc, 0x40, 0x54, 0xfe, 0x38, 0x45, 0x3d, 0x1c, 0x97, 0x3f, 0x4c,
+ 0x3d, 0x8b, 0xfd, 0x24, 0x8a, 0xcc, 0x51, 0xde, 0x98, 0xc9, 0xd1, 0x4f,
+ 0x52, 0x7f, 0x3e, 0xed, 0x3e, 0xad, 0x76, 0x20, 0x6e, 0xe5, 0xd7, 0x87,
+ 0x55, 0xdf, 0x1c, 0xd3, 0xda, 0x6e, 0xdc, 0xea, 0x92, 0x1b, 0x17, 0x8c,
+ 0x8e, 0x0d, 0x4f, 0x47, 0x03, 0x23, 0x0b, 0xb4, 0x4b, 0xc9, 0x58, 0xd6,
+ 0x6a, 0x94, 0x43, 0x51, 0xe6, 0x9e, 0x53, 0xd4, 0xcf, 0xb0, 0x85, 0xbd,
+ 0x76, 0xd6, 0x6a, 0xf2, 0xec, 0x4f, 0xac, 0x4e, 0xcf, 0x1e, 0xf3, 0xf4,
+ 0x2c, 0xef, 0xa5, 0x68, 0x03, 0x20, 0x93, 0x89, 0x99, 0x51, 0x2b, 0x09,
+ 0x9b, 0x87, 0xeb, 0x45, 0xce, 0x1f, 0x97, 0xe3, 0x8b, 0x47, 0xe1, 0x7f,
+ 0xf7, 0xda, 0x7b, 0x69, 0x57, 0xed, 0x21, 0xe2, 0x71, 0xb0, 0xfe, 0x97,
+ 0xea, 0xe6, 0x7a, 0xd4, 0x9b, 0x8b, 0xf7, 0x21, 0xe7, 0xd3, 0xac, 0xd7,
+ 0x36, 0x32, 0x9f, 0xa3, 0x7b, 0xad, 0x1d, 0xbb, 0xa7, 0xb2, 0xee, 0x64,
+ 0xc1, 0xf1, 0xb0, 0x61, 0xf8, 0x85, 0x2f, 0xf4, 0x8d, 0x08, 0xd7, 0xe4,
+ 0x7a, 0xad, 0x92, 0xde, 0x0f, 0xfd, 0x32, 0xcd, 0xff, 0x9c, 0x57, 0xbb,
+ 0x42, 0xbc, 0x12, 0xed, 0x5c, 0xc5, 0x36, 0x7d, 0xc5, 0x9b, 0xaf, 0xbf,
+ 0x5d, 0x9a, 0xa3, 0x55, 0xe3, 0x99, 0x5b, 0x61, 0x3b, 0x2e, 0xb9, 0x45,
+ 0xfe, 0x96, 0xcb, 0x11, 0xa7, 0x41, 0xf6, 0xda, 0x1b, 0xeb, 0xe6, 0xd8,
+ 0x86, 0x3e, 0xe3, 0x13, 0x04, 0xa7, 0x03, 0x9e, 0x6f, 0xb1, 0x89, 0x7e,
+ 0x93, 0x77, 0xdd, 0xa4, 0x39, 0x99, 0xb8, 0xd5, 0x59, 0xf7, 0x1e, 0x9b,
+ 0x2a, 0x76, 0x38, 0x6e, 0x51, 0x77, 0x36, 0x46, 0xa5, 0x95, 0x3c, 0x54,
+ 0x56, 0x3f, 0x3e, 0xe4, 0x18, 0xcc, 0x45, 0xd4, 0x39, 0xd2, 0xce, 0x9c,
+ 0xfd, 0x5b, 0x7a, 0x6e, 0x2d, 0xf4, 0x09, 0x70, 0x0d, 0x3e, 0xf9, 0x4c,
+ 0xbe, 0x97, 0xb9, 0x5e, 0xcc, 0xdf, 0xcc, 0xf9, 0x5d, 0xef, 0x9c, 0x13,
+ 0x6e, 0xce, 0xba, 0x5f, 0xb2, 0x17, 0x0c, 0xff, 0xa5, 0x1d, 0xf0, 0x5e,
+ 0x2b, 0xda, 0x0b, 0xb4, 0x09, 0x9f, 0x37, 0x8f, 0x6f, 0x1b, 0x7a, 0xd4,
+ 0x36, 0x9c, 0x2a, 0x90, 0x3f, 0xc9, 0x97, 0x3e, 0x3f, 0xfa, 0x3a, 0x8f,
+ 0x3c, 0x4a, 0x3d, 0x3b, 0x28, 0x67, 0x0b, 0x3c, 0x9b, 0x94, 0xd6, 0xb4,
+ 0x36, 0x9f, 0x3b, 0xa8, 0x98, 0xac, 0xee, 0xe9, 0xc4, 0x4b, 0x39, 0x19,
+ 0x96, 0xab, 0x2e, 0xcf, 0x2c, 0x51, 0xcc, 0x04, 0x5b, 0xaa, 0xde, 0x7f,
+ 0xbf, 0x9e, 0x59, 0x58, 0x7d, 0xc6, 0x18, 0xc6, 0x3e, 0xef, 0xd1, 0xbb,
+ 0x55, 0xcf, 0x36, 0x53, 0x43, 0x9f, 0xaf, 0xeb, 0x39, 0x85, 0xa1, 0x13,
+ 0x59, 0xdf, 0x0f, 0x47, 0xf8, 0x0c, 0xd7, 0xa5, 0xcf, 0xc7, 0xb5, 0xc8,
+ 0x7b, 0xdd, 0xb0, 0xd8, 0xfd, 0x12, 0xdc, 0x09, 0xd1, 0xdf, 0xc9, 0x3a,
+ 0x72, 0x00, 0xb2, 0xba, 0xd9, 0x60, 0x60, 0xc6, 0x8d, 0xaf, 0x91, 0xb1,
+ 0xae, 0xe1, 0x1c, 0x11, 0xab, 0xc0, 0x8f, 0x3e, 0xf5, 0x93, 0xdb, 0x98,
+ 0x2f, 0xe3, 0xf9, 0xeb, 0x03, 0x98, 0xdf, 0xf1, 0xea, 0xea, 0x53, 0xdb,
+ 0xc9, 0xab, 0xa3, 0x5a, 0x1f, 0xe4, 0x33, 0x94, 0x63, 0x9e, 0x19, 0xe9,
+ 0xf2, 0x1e, 0x9e, 0x67, 0x7b, 0x5b, 0x1d, 0x1d, 0x93, 0xde, 0xfe, 0xfc,
+ 0xfb, 0x61, 0x09, 0xb7, 0x53, 0xc7, 0x45, 0x25, 0x39, 0xcd, 0x98, 0x05,
+ 0xb6, 0x6b, 0x9c, 0x73, 0x7d, 0xb1, 0x2e, 0xce, 0xfc, 0x9f, 0xba, 0x38,
+ 0x63, 0x7d, 0xa4, 0xbc, 0x13, 0xd6, 0x3c, 0xd6, 0xe7, 0xd3, 0xb5, 0x58,
+ 0x43, 0x57, 0xbf, 0x76, 0x1f, 0xad, 0xd0, 0xf1, 0x87, 0x05, 0xda, 0xab,
+ 0x94, 0xe6, 0x94, 0xff, 0x3e, 0xc5, 0xb3, 0xe5, 0x1e, 0xaf, 0x72, 0x8f,
+ 0xc3, 0x4b, 0x8a, 0x83, 0x7c, 0x58, 0x65, 0xf8, 0x74, 0x81, 0x3a, 0xa6,
+ 0x45, 0xe6, 0x67, 0x7c, 0x3d, 0x33, 0xe6, 0xf9, 0xb8, 0xf9, 0xf5, 0x0d,
+ 0xaa, 0x67, 0xe0, 0xdd, 0x38, 0x23, 0x9e, 0x7d, 0xe9, 0x92, 0xb9, 0x0b,
+ 0xb4, 0xbb, 0x49, 0xf4, 0x45, 0x03, 0x73, 0x0b, 0xac, 0x4d, 0x12, 0x8b,
+ 0x32, 0x2c, 0xac, 0xfb, 0x8f, 0xd8, 0xa7, 0x20, 0x6f, 0x31, 0x79, 0x7f,
+ 0x8a, 0x3e, 0x7d, 0x03, 0x7c, 0xe3, 0xd6, 0xba, 0xf3, 0xdd, 0x51, 0xf1,
+ 0x09, 0x6b, 0xe9, 0x1e, 0xef, 0x90, 0x66, 0xf2, 0xb9, 0x63, 0xdf, 0x10,
+ 0xfa, 0x60, 0xbc, 0xce, 0x22, 0x16, 0x60, 0xec, 0x11, 0xd7, 0xd8, 0x63,
+ 0xae, 0xc8, 0xbe, 0x16, 0x2f, 0xaf, 0xd4, 0xa2, 0xbc, 0x42, 0x7e, 0xcb,
+ 0xa8, 0xff, 0x3d, 0xa4, 0x3a, 0x2b, 0x3f, 0xd5, 0x6b, 0x70, 0x2c, 0x76,
+ 0x4c, 0x79, 0x4f, 0x6a, 0x78, 0x2f, 0xe6, 0xad, 0x3d, 0xd6, 0x61, 0x7c,
+ 0x2b, 0x5b, 0xf5, 0x4d, 0x58, 0xc7, 0xd1, 0xae, 0x70, 0x7e, 0xf2, 0x06,
+ 0x79, 0x84, 0x3a, 0xcf, 0x1f, 0xe7, 0xd3, 0xc3, 0x6f, 0x73, 0x3c, 0xf9,
+ 0xbf, 0x1a, 0x8b, 0xe0, 0xcb, 0xaa, 0xdf, 0xe7, 0xcb, 0x1d, 0xef, 0x55,
+ 0xdb, 0x04, 0xca, 0x5d, 0x75, 0x7d, 0xd2, 0x96, 0xc8, 0xf4, 0x0a, 0x5d,
+ 0xd2, 0xfd, 0xdc, 0xff, 0xf3, 0xcc, 0xed, 0x42, 0xde, 0x56, 0xa3, 0xcd,
+ 0x09, 0xa5, 0x4d, 0x06, 0xb4, 0x89, 0x28, 0x6d, 0x18, 0xef, 0x3d, 0xe5,
+ 0xf1, 0x5b, 0x0b, 0xce, 0x8b, 0xb9, 0x5a, 0xe8, 0xba, 0x7d, 0xd4, 0xf9,
+ 0xcf, 0x76, 0x68, 0x7d, 0xd0, 0xa1, 0xee, 0x5b, 0x0b, 0x7d, 0xc6, 0xf6,
+ 0x56, 0xf5, 0x47, 0x4c, 0xbc, 0x15, 0xd7, 0x3c, 0x68, 0x10, 0xfa, 0x79,
+ 0x6e, 0x0a, 0xbe, 0x1a, 0x71, 0x6f, 0x35, 0xb4, 0xfa, 0x8e, 0x77, 0x5e,
+ 0xf3, 0x4a, 0x1b, 0xca, 0x00, 0xf5, 0xe6, 0x3a, 0xcc, 0xb7, 0x27, 0xda,
+ 0x07, 0xfe, 0xfa, 0x19, 0xfa, 0x37, 0x6b, 0x3c, 0x11, 0x84, 0xcc, 0xdf,
+ 0x9c, 0x6a, 0xf7, 0x62, 0x38, 0x07, 0x6d, 0xc4, 0xad, 0x53, 0x11, 0xc6,
+ 0x14, 0x68, 0xf7, 0x48, 0xc3, 0x34, 0xe2, 0x57, 0xe8, 0xf1, 0x25, 0xb5,
+ 0x47, 0x7d, 0xb8, 0x7f, 0x07, 0x71, 0x7e, 0xb8, 0x3e, 0x8a, 0xe7, 0x7a,
+ 0x0d, 0x16, 0x21, 0xba, 0x45, 0xcf, 0x74, 0x6e, 0x2a, 0x11, 0x3b, 0x2c,
+ 0x5e, 0xdf, 0xb8, 0xab, 0xfa, 0x60, 0x65, 0x5f, 0x0f, 0xca, 0x9e, 0x8a,
+ 0xbd, 0x60, 0x1c, 0x0d, 0x1f, 0x7e, 0xc6, 0xd8, 0x83, 0x7c, 0xb1, 0x4f,
+ 0xf1, 0x51, 0xc1, 0xa1, 0x45, 0x9c, 0x25, 0x7d, 0xd2, 0x65, 0xf8, 0xe1,
+ 0x2e, 0xce, 0x90, 0x7e, 0x77, 0xf9, 0xe4, 0xa4, 0x9b, 0x62, 0x7d, 0x0c,
+ 0xfa, 0xe0, 0xa4, 0x8c, 0x20, 0x2e, 0x18, 0x09, 0xb6, 0x32, 0xaf, 0x0c,
+ 0xdf, 0x30, 0xe7, 0xe5, 0x1e, 0xfb, 0x98, 0x33, 0x95, 0x73, 0x0b, 0xdc,
+ 0x3b, 0x65, 0xdb, 0xc4, 0xde, 0x73, 0x53, 0xdc, 0xaf, 0xc9, 0x43, 0xb0,
+ 0x6d, 0x4d, 0xbb, 0xf8, 0xe5, 0x59, 0x0c, 0xe0, 0x77, 0x10, 0xf2, 0xc0,
+ 0xb1, 0xf8, 0x5d, 0x58, 0x96, 0x77, 0x2f, 0xf8, 0xb6, 0x3d, 0x20, 0x6f,
+ 0x3b, 0xe5, 0x93, 0xa7, 0xdc, 0xf5, 0x3c, 0x03, 0x37, 0xc7, 0x9a, 0xb5,
+ 0xe3, 0xb8, 0x79, 0x29, 0x97, 0x97, 0xdc, 0xa5, 0xf5, 0x96, 0xd2, 0x92,
+ 0xf2, 0xbf, 0x8c, 0x33, 0xbc, 0x7e, 0xaf, 0x25, 0x86, 0x7e, 0xa4, 0xcd,
+ 0x67, 0x6b, 0x7f, 0xd5, 0xb6, 0xc0, 0xd7, 0x7f, 0xe4, 0x47, 0xf2, 0xe5,
+ 0xb2, 0xec, 0x52, 0xfd, 0xbf, 0xda, 0x73, 0xd5, 0xba, 0xdf, 0xf7, 0x6f,
+ 0xa9, 0xdf, 0xb5, 0xfe, 0xa3, 0xf1, 0xc1, 0x96, 0xe9, 0x7a, 0x9d, 0xf0,
+ 0x98, 0x57, 0x57, 0x58, 0x8d, 0xf7, 0x0e, 0x78, 0x7a, 0x21, 0xa5, 0xbe,
+ 0x73, 0xca, 0xa6, 0x7e, 0xe0, 0x7e, 0x9a, 0xe5, 0xe0, 0xec, 0x6d, 0xd0,
+ 0xc4, 0xd7, 0xc1, 0x8c, 0xfb, 0x7c, 0xdd, 0xd1, 0xea, 0xf9, 0xc2, 0x96,
+ 0x74, 0x9f, 0xa3, 0xef, 0xe4, 0x40, 0x8f, 0xb6, 0x49, 0x66, 0x3c, 0x28,
+ 0xc9, 0x73, 0x1b, 0x62, 0xc6, 0xd7, 0x25, 0xff, 0x41, 0xde, 0xb4, 0x4f,
+ 0x7d, 0x51, 0xf4, 0xdf, 0x29, 0x5c, 0xdb, 0xf0, 0x33, 0xe4, 0x79, 0x9f,
+ 0x7f, 0xcf, 0xae, 0xe3, 0xd1, 0x9d, 0x1e, 0x8f, 0xf2, 0xbe, 0x65, 0xea,
+ 0x1f, 0x18, 0xdb, 0x7d, 0x8e, 0x7b, 0x34, 0xcf, 0x75, 0x9f, 0x33, 0xf1,
+ 0x7a, 0xed, 0x73, 0x7d, 0x95, 0xe7, 0x70, 0xbf, 0x47, 0xb1, 0x61, 0x98,
+ 0x7b, 0xd7, 0x20, 0x7c, 0xba, 0x3e, 0xda, 0x1c, 0xda, 0xef, 0xcd, 0xee,
+ 0x2e, 0x21, 0xbf, 0x27, 0x3c, 0x9e, 0xa3, 0xbe, 0x89, 0x78, 0xfa, 0x66,
+ 0xc5, 0xbe, 0x8c, 0x18, 0xfc, 0x09, 0x73, 0x22, 0x55, 0xf6, 0xe5, 0x71,
+ 0xf3, 0x6e, 0x35, 0xf6, 0xe5, 0x4e, 0x6f, 0x1e, 0xff, 0x9e, 0xaf, 0x57,
+ 0xfc, 0xb6, 0xaf, 0x57, 0xea, 0x7d, 0x5a, 0x9f, 0xf6, 0xb5, 0xb8, 0xaf,
+ 0xea, 0x98, 0x2f, 0xbf, 0x6a, 0xde, 0x25, 0x8b, 0x98, 0x8d, 0x3e, 0x65,
+ 0x22, 0x67, 0x30, 0xd3, 0xd6, 0x59, 0x8b, 0xb8, 0x0f, 0xe7, 0xc7, 0x92,
+ 0x8e, 0xdc, 0xd6, 0xd8, 0xfa, 0xf4, 0xec, 0x98, 0xe6, 0x79, 0xe6, 0x5c,
+ 0x4f, 0xef, 0x44, 0x77, 0x43, 0xae, 0x5e, 0x89, 0xac, 0x60, 0x8a, 0x66,
+ 0x4e, 0xa4, 0x61, 0x87, 0x52, 0x5a, 0x2f, 0xfb, 0x2e, 0xf6, 0x3b, 0xa8,
+ 0x78, 0xae, 0x35, 0xce, 0x73, 0xf2, 0x90, 0x5d, 0xd6, 0xda, 0x4d, 0xd3,
+ 0x50, 0xf1, 0x44, 0xd3, 0x8b, 0x3e, 0xdf, 0x93, 0x9f, 0x66, 0x4e, 0x1c,
+ 0x9c, 0x29, 0x0f, 0x87, 0xb6, 0xf7, 0xda, 0x79, 0x21, 0x66, 0x7f, 0x58,
+ 0x8e, 0x28, 0x76, 0xf8, 0x15, 0xdc, 0xdf, 0xc7, 0xf8, 0x32, 0x11, 0x52,
+ 0x4c, 0x70, 0x22, 0x36, 0x01, 0x59, 0xcc, 0xba, 0xc4, 0xf8, 0xaf, 0x55,
+ 0xac, 0xff, 0x9c, 0xd0, 0xcf, 0x22, 0xa6, 0xe0, 0x59, 0x39, 0xec, 0x6e,
+ 0x76, 0x97, 0xc4, 0xf8, 0xbf, 0x59, 0xad, 0x09, 0x35, 0xca, 0x84, 0x1b,
+ 0x6a, 0x4a, 0x97, 0x8c, 0x0c, 0x8c, 0x06, 0x53, 0x6b, 0x26, 0x9d, 0x68,
+ 0xd3, 0xae, 0x12, 0x64, 0xbc, 0x04, 0xfd, 0x5f, 0x8a, 0x05, 0x46, 0x14,
+ 0x9b, 0xf6, 0x65, 0x49, 0xb7, 0xd3, 0xcf, 0xa7, 0x3e, 0xf9, 0x8a, 0xdc,
+ 0xb4, 0xb7, 0xca, 0xcd, 0x1e, 0xe2, 0x31, 0xfb, 0xd1, 0xa6, 0x2e, 0x19,
+ 0x44, 0x5f, 0x12, 0x7d, 0x4d, 0xca, 0x8f, 0x1a, 0x9f, 0x41, 0x67, 0xdd,
+ 0xb4, 0xa9, 0xab, 0xee, 0xe2, 0x2f, 0xde, 0xf5, 0x6f, 0xa0, 0x09, 0xb1,
+ 0x1d, 0xdb, 0xd0, 0xa6, 0x8e, 0xb3, 0xeb, 0xfa, 0x3b, 0xd1, 0xbe, 0x17,
+ 0x73, 0x34, 0xe8, 0xfb, 0x59, 0xce, 0x76, 0x53, 0xe7, 0xac, 0x19, 0xb3,
+ 0xae, 0xae, 0xfd, 0xfb, 0x36, 0x83, 0x4f, 0xf8, 0x94, 0xf4, 0xce, 0xa5,
+ 0xe4, 0xe1, 0x8e, 0xda, 0xf6, 0xbf, 0xea, 0xda, 0xad, 0xb2, 0xa6, 0x8d,
+ 0x64, 0x38, 0xd6, 0x5e, 0xdb, 0xef, 0xf3, 0x93, 0xdf, 0xee, 0xc0, 0xfb,
+ 0x42, 0x66, 0xac, 0xa4, 0xc6, 0x52, 0x37, 0xa3, 0x5c, 0xeb, 0xc3, 0xba,
+ 0x67, 0x78, 0xcd, 0x67, 0xf8, 0x2c, 0xf3, 0x7a, 0xb7, 0xd9, 0x8f, 0x67,
+ 0x98, 0x13, 0x60, 0x5e, 0x83, 0x3c, 0xbb, 0x5a, 0x9c, 0xc5, 0x31, 0x9f,
+ 0xcd, 0x37, 0x64, 0x2a, 0xbc, 0xe7, 0xeb, 0x95, 0x58, 0x05, 0xab, 0xb6,
+ 0xab, 0xe0, 0xe7, 0x84, 0x49, 0x3b, 0xad, 0x49, 0xc5, 0x6e, 0x80, 0xce,
+ 0x87, 0x40, 0xe7, 0x07, 0x83, 0x8c, 0x0b, 0x9b, 0x3d, 0x5a, 0x3b, 0x32,
+ 0x52, 0xfa, 0x0d, 0x64, 0x9c, 0x3c, 0x0a, 0x9f, 0xa2, 0x64, 0x79, 0xf8,
+ 0x8c, 0x01, 0xd8, 0x34, 0x57, 0x82, 0x9a, 0x77, 0x40, 0x7c, 0x3f, 0x7f,
+ 0x5d, 0x46, 0xa6, 0x98, 0x13, 0x20, 0x3f, 0x33, 0xae, 0x4f, 0xe1, 0xde,
+ 0x2d, 0x8c, 0x75, 0x21, 0xc3, 0x63, 0xe0, 0xd7, 0x90, 0x38, 0xd3, 0xdb,
+ 0x24, 0x37, 0x3e, 0xa6, 0x3e, 0x40, 0x37, 0x6c, 0xd4, 0x29, 0x77, 0x54,
+ 0x26, 0xaf, 0x6c, 0x82, 0xac, 0x32, 0xee, 0xd7, 0x9c, 0x46, 0x39, 0xac,
+ 0xbe, 0x39, 0x7d, 0x0e, 0xe6, 0xe1, 0x4c, 0x8d, 0xd9, 0xc8, 0xed, 0xa1,
+ 0x98, 0xb4, 0x8e, 0xca, 0xcc, 0xac, 0xad, 0x78, 0x97, 0x94, 0xdc, 0x2e,
+ 0x93, 0x76, 0xd9, 0x7d, 0x71, 0xe8, 0x2a, 0xfa, 0xf2, 0x3f, 0x88, 0x98,
+ 0xb3, 0xdc, 0xbd, 0x81, 0x31, 0x71, 0x72, 0xba, 0x7a, 0x0e, 0xc5, 0xc8,
+ 0xe0, 0xde, 0x2f, 0xdb, 0x8c, 0xcc, 0x30, 0x3e, 0xfe, 0xa0, 0x9c, 0x8a,
+ 0x72, 0x4d, 0x8e, 0x65, 0xed, 0x96, 0x3c, 0xc2, 0xbd, 0xfd, 0xc7, 0xe3,
+ 0xe5, 0x97, 0x31, 0x5f, 0x5c, 0xba, 0x5f, 0x1d, 0xd3, 0xb8, 0xfe, 0x54,
+ 0x4d, 0x0c, 0x6b, 0xf2, 0x05, 0x26, 0x8e, 0xbd, 0x2e, 0x13, 0x8b, 0xa4,
+ 0x0f, 0x6d, 0x7c, 0x40, 0x7e, 0xe1, 0xf4, 0xda, 0x4f, 0x68, 0xad, 0x31,
+ 0x91, 0x62, 0x7d, 0xa6, 0xd9, 0x49, 0xda, 0xf3, 0x12, 0x1a, 0xfc, 0x1a,
+ 0xae, 0x19, 0xd7, 0xe6, 0xdd, 0x5e, 0xf7, 0x09, 0xf1, 0x71, 0x20, 0x9b,
+ 0x53, 0x8d, 0x81, 0x4f, 0xca, 0xd7, 0xf7, 0x71, 0x8c, 0xc1, 0x81, 0x48,
+ 0x80, 0xb4, 0x7a, 0xef, 0x2e, 0xe2, 0x67, 0x6a, 0xf3, 0x7f, 0x0f, 0x1c,
+ 0xdb, 0x3b, 0x90, 0x38, 0xc3, 0x18, 0x36, 0xec, 0x3c, 0xba, 0xc1, 0xbc,
+ 0x6b, 0x2e, 0xb7, 0x4e, 0xb4, 0x7e, 0x76, 0xfc, 0x1f, 0x0e, 0xf1, 0x10,
+ 0x89, 0x58, 0xa3, 0xc5, 0x3c, 0x38, 0x75, 0x1c, 0x6b, 0x2a, 0xcc, 0xb9,
+ 0x11, 0xcb, 0xdf, 0x24, 0x97, 0xfb, 0x2c, 0x79, 0x20, 0x94, 0x8a, 0x5b,
+ 0xb2, 0x25, 0x7e, 0x4e, 0xb0, 0x26, 0xeb, 0x2b, 0x8b, 0x89, 0x1c, 0xc7,
+ 0x87, 0xa6, 0x39, 0x5f, 0x5c, 0xe3, 0x95, 0xe4, 0x96, 0x72, 0xf9, 0x29,
+ 0x57, 0x02, 0xc9, 0x7b, 0x3e, 0x2c, 0xb3, 0x16, 0x6e, 0xbd, 0xfa, 0x79,
+ 0x38, 0x05, 0xea, 0x0a, 0x7b, 0xc2, 0x60, 0x0e, 0x27, 0x8f, 0x77, 0x2f,
+ 0xb2, 0xfd, 0xe4, 0x43, 0xa6, 0x7d, 0x06, 0xed, 0x06, 0x0f, 0xeb, 0x34,
+ 0x75, 0xbc, 0xbb, 0x78, 0x6c, 0x83, 0x89, 0xbf, 0x97, 0x15, 0xff, 0xf5,
+ 0x56, 0x4d, 0x4c, 0x93, 0x0a, 0x8c, 0x17, 0xc6, 0x02, 0x63, 0x05, 0xab,
+ 0xaf, 0x09, 0xb4, 0x5a, 0x70, 0x99, 0xab, 0xf1, 0x73, 0x56, 0xcc, 0xf7,
+ 0x8b, 0x3c, 0xa9, 0x18, 0x29, 0xd6, 0x14, 0x2d, 0xf5, 0x85, 0x0e, 0x2d,
+ 0x30, 0xc7, 0x1f, 0x51, 0x7d, 0x70, 0x78, 0xb1, 0x55, 0xf2, 0xf6, 0x7a,
+ 0xc9, 0xab, 0x8c, 0x47, 0x55, 0x07, 0x58, 0xce, 0x3d, 0xe8, 0xe3, 0xbe,
+ 0x1f, 0x57, 0x5c, 0xc4, 0xeb, 0x85, 0x4e, 0xb4, 0x99, 0x6b, 0xde, 0x51,
+ 0xd7, 0x5f, 0x5d, 0x97, 0x4d, 0xd8, 0x96, 0x55, 0x5f, 0x93, 0x65, 0x5f,
+ 0x7d, 0x2d, 0xf6, 0xb4, 0x5c, 0x27, 0xdf, 0x94, 0xfc, 0x9c, 0xbb, 0xeb,
+ 0xe5, 0xdc, 0x1f, 0xc3, 0x9c, 0x9c, 0x5b, 0x32, 0xa1, 0xa1, 0xa6, 0xbe,
+ 0x53, 0x53, 0xc1, 0x5b, 0x2b, 0xf9, 0x53, 0xb4, 0x17, 0x2b, 0xb5, 0x72,
+ 0xdc, 0x7b, 0x06, 0xbe, 0x48, 0x1e, 0x7e, 0x45, 0xce, 0xfb, 0xfe, 0x80,
+ 0xf7, 0x2b, 0xcf, 0x7f, 0xc1, 0x9e, 0x9a, 0xb5, 0xce, 0x6e, 0xd5, 0xd4,
+ 0xd9, 0xbf, 0x8d, 0x67, 0x59, 0x63, 0xcf, 0x95, 0x1b, 0xc0, 0xbb, 0x0d,
+ 0xc4, 0x89, 0x54, 0xc6, 0x53, 0xc7, 0xab, 0x2e, 0xd7, 0xb9, 0x76, 0x79,
+ 0x73, 0x05, 0xa1, 0xe7, 0x0f, 0x4e, 0xf9, 0x63, 0x4e, 0x4a, 0x63, 0x7f,
+ 0x22, 0x16, 0xb4, 0x38, 0xc6, 0xe8, 0xfb, 0xb4, 0x7b, 0x12, 0x7a, 0x9c,
+ 0x3a, 0x9f, 0xef, 0xed, 0xc0, 0xd7, 0xa3, 0x2e, 0xa0, 0x3e, 0x57, 0x1b,
+ 0x10, 0xcf, 0x43, 0xd7, 0x8f, 0x94, 0x34, 0x97, 0x1f, 0xfb, 0x6a, 0x30,
+ 0x31, 0x93, 0x55, 0xdd, 0x00, 0x7f, 0xaf, 0xf4, 0x26, 0xf3, 0x41, 0x67,
+ 0x24, 0x50, 0x5d, 0xa7, 0x61, 0x6c, 0xc6, 0x9a, 0x46, 0x0b, 0x74, 0x83,
+ 0xc8, 0x55, 0xf0, 0xc6, 0x6b, 0x0b, 0xe4, 0xd7, 0x60, 0xbb, 0x89, 0xaf,
+ 0x96, 0x76, 0x58, 0xd2, 0xae, 0xb5, 0xcf, 0xbc, 0x13, 0xa1, 0x7f, 0x32,
+ 0x9c, 0xec, 0x87, 0x9f, 0xad, 0xd8, 0x03, 0xe6, 0x2b, 0x0f, 0x22, 0x1e,
+ 0xab, 0xce, 0xb1, 0x40, 0xbe, 0xc6, 0xd9, 0x9f, 0x85, 0x5f, 0xb9, 0x52,
+ 0xf7, 0xc8, 0x17, 0x27, 0x35, 0xb7, 0x39, 0xb7, 0xd0, 0xa2, 0x3a, 0x76,
+ 0xae, 0x38, 0x86, 0x73, 0x91, 0xad, 0xd6, 0x50, 0xde, 0xeb, 0x0f, 0x4b,
+ 0xb1, 0xc8, 0xb6, 0x74, 0x35, 0xe8, 0xb9, 0xfb, 0xb5, 0x1d, 0x5b, 0xe6,
+ 0xe1, 0x2b, 0x16, 0x17, 0x1d, 0xfc, 0xf7, 0xe0, 0xbf, 0x0f, 0xff, 0xbb,
+ 0x25, 0x3d, 0x4d, 0xff, 0x95, 0xb5, 0x9c, 0x96, 0xba, 0xf5, 0xe9, 0x23,
+ 0x75, 0x29, 0x0e, 0x2c, 0xef, 0xc5, 0x39, 0xf9, 0x62, 0xbd, 0x9c, 0x30,
+ 0x4f, 0xea, 0xeb, 0x08, 0xe6, 0x4b, 0xfd, 0x5a, 0x5f, 0x75, 0x0d, 0xcb,
+ 0xf2, 0xea, 0x5e, 0xe4, 0xe9, 0x66, 0x39, 0x5c, 0xf4, 0x6b, 0x57, 0x31,
+ 0x39, 0x52, 0xa9, 0x5d, 0x49, 0x26, 0x38, 0xf4, 0xc9, 0x23, 0xd9, 0x29,
+ 0xc5, 0x13, 0x58, 0xd6, 0xd0, 0xf5, 0x47, 0x26, 0x16, 0xdf, 0x7e, 0x64,
+ 0x05, 0x13, 0x8e, 0x7b, 0x8b, 0xab, 0x61, 0x86, 0x88, 0xa5, 0xe3, 0xb7,
+ 0x72, 0xea, 0xbb, 0x61, 0xdf, 0x7e, 0xcc, 0x43, 0x9c, 0x1d, 0xf4, 0x4c,
+ 0xf3, 0x0a, 0x76, 0xd7, 0xc4, 0xa3, 0xc4, 0x91, 0xf2, 0xb9, 0x6a, 0xec,
+ 0x47, 0x08, 0xe7, 0x2f, 0x01, 0xcb, 0xc9, 0x61, 0x1f, 0x3f, 0xed, 0x34,
+ 0x7e, 0x20, 0x71, 0xa6, 0x89, 0x2a, 0xec, 0x91, 0x8f, 0x35, 0x7d, 0x09,
+ 0x73, 0x65, 0xe4, 0x77, 0xa5, 0x47, 0xe5, 0x57, 0xa5, 0x31, 0xc8, 0xf7,
+ 0x04, 0xe6, 0x3c, 0x20, 0x6f, 0x96, 0xf6, 0xc9, 0xb5, 0xd2, 0xb8, 0xbc,
+ 0x51, 0xda, 0x8d, 0x98, 0x6a, 0x94, 0x58, 0x4f, 0x0f, 0x2b, 0x3d, 0x2c,
+ 0x07, 0xcf, 0x2b, 0x06, 0xf0, 0x16, 0xfd, 0x9e, 0xe3, 0xea, 0x67, 0x13,
+ 0x5f, 0x9f, 0xf8, 0x35, 0xe3, 0x79, 0x62, 0x33, 0x8b, 0x25, 0x1f, 0xc3,
+ 0x71, 0xb4, 0x0b, 0x6b, 0xdb, 0xfc, 0x36, 0x65, 0xe4, 0x7c, 0x24, 0x30,
+ 0x7a, 0x3e, 0x14, 0x78, 0x50, 0xbf, 0x73, 0x61, 0xbd, 0xb3, 0x2c, 0x93,
+ 0xae, 0x43, 0xde, 0x1c, 0x1c, 0x81, 0x2c, 0x8c, 0x42, 0xd5, 0x3f, 0xe4,
+ 0xac, 0x17, 0x90, 0x34, 0xf5, 0x11, 0xfc, 0xcc, 0xe4, 0x8b, 0xae, 0x64,
+ 0x0b, 0xf3, 0x01, 0x83, 0x47, 0xb3, 0xd1, 0xee, 0x43, 0xfb, 0xe7, 0x5e,
+ 0x7b, 0xa7, 0x64, 0x67, 0x25, 0xf5, 0xbe, 0xfa, 0xc3, 0x2f, 0x7b, 0x7d,
+ 0x83, 0xe8, 0x03, 0x67, 0x5e, 0x64, 0xdf, 0x45, 0xaf, 0x8f, 0x67, 0xc2,
+ 0x5a, 0x7d, 0x5c, 0xf9, 0x2a, 0x6b, 0x8f, 0x8b, 0x7e, 0xd7, 0xa0, 0xb5,
+ 0xf8, 0x0f, 0x3a, 0x8d, 0x6e, 0x23, 0x26, 0xf0, 0x9f, 0x9d, 0x8c, 0xc1,
+ 0x8a, 0x90, 0xaf, 0xbb, 0xa0, 0x13, 0xff, 0xba, 0x75, 0xa5, 0x6d, 0x0d,
+ 0x7d, 0x5c, 0x85, 0xd1, 0xfe, 0x58, 0xba, 0x17, 0xff, 0xed, 0xe1, 0x79,
+ 0x9f, 0xc0, 0xbb, 0xe1, 0xac, 0x0a, 0xc4, 0x8d, 0xc7, 0x21, 0xdb, 0x2d,
+ 0xb2, 0xfe, 0x2c, 0xe9, 0xd5, 0x0b, 0x5d, 0x9d, 0x82, 0xdc, 0xba, 0xb2,
+ 0x50, 0x0a, 0x05, 0x46, 0x0a, 0x29, 0x31, 0x78, 0x6a, 0x4b, 0x32, 0xd1,
+ 0x94, 0x9c, 0x1e, 0x48, 0xf4, 0x30, 0x0f, 0x99, 0xed, 0x77, 0xe5, 0x52,
+ 0x89, 0xf6, 0x38, 0x27, 0x97, 0x07, 0x12, 0x6e, 0x51, 0x88, 0x8b, 0x71,
+ 0xe5, 0x32, 0x64, 0xf3, 0x9d, 0xf3, 0xbb, 0xe5, 0x48, 0x41, 0xfd, 0xe0,
+ 0xde, 0xb0, 0xbc, 0x20, 0x97, 0x06, 0x5e, 0xb8, 0x75, 0xc9, 0x3d, 0x84,
+ 0x33, 0x25, 0x1f, 0x1e, 0xee, 0x32, 0xfb, 0x56, 0x1c, 0x92, 0x30, 0x1f,
+ 0xa2, 0x35, 0x35, 0xa7, 0x51, 0xd2, 0xfb, 0x23, 0x5e, 0x5c, 0x0e, 0x9f,
+ 0x3b, 0x30, 0x60, 0xea, 0x29, 0x01, 0x7f, 0x9f, 0x61, 0xf8, 0x31, 0x7c,
+ 0xce, 0xa7, 0x8d, 0x3f, 0x4f, 0x67, 0x20, 0x3d, 0xdb, 0x2a, 0xa1, 0x8b,
+ 0xf7, 0x81, 0xae, 0x21, 0x39, 0xd4, 0x5f, 0x2e, 0x7f, 0xd3, 0x0d, 0xc5,
+ 0x27, 0x10, 0xa3, 0x60, 0xff, 0xb2, 0xee, 0xc5, 0x36, 0xd0, 0xa4, 0x49,
+ 0xa2, 0x2f, 0xfa, 0xeb, 0x35, 0x7a, 0x58, 0x86, 0x8b, 0xeb, 0x8c, 0x2d,
+ 0xf3, 0xb1, 0x0d, 0xfe, 0x7c, 0x06, 0x53, 0xd6, 0x6d, 0xf5, 0x07, 0xbc,
+ 0xef, 0x24, 0xbc, 0xf6, 0x3d, 0x81, 0x07, 0x42, 0xed, 0x12, 0x72, 0x9e,
+ 0xdf, 0x48, 0x6c, 0xe4, 0x52, 0xc1, 0xef, 0x87, 0x9f, 0x18, 0xf2, 0xfd,
+ 0x61, 0xd9, 0xbe, 0x72, 0xd6, 0xb2, 0xbd, 0x7b, 0xf1, 0x5b, 0xde, 0x9c,
+ 0x29, 0x6f, 0x2c, 0x62, 0x8e, 0xd8, 0x5a, 0xb5, 0x4f, 0x66, 0xec, 0xa7,
+ 0xf2, 0x74, 0x7f, 0xe2, 0x15, 0xc5, 0xc9, 0x56, 0x9e, 0xe1, 0x7d, 0xc4,
+ 0x90, 0x25, 0x7d, 0x26, 0xb6, 0x07, 0xf4, 0xcd, 0xc4, 0xee, 0xb6, 0xe7,
+ 0xad, 0x60, 0xc0, 0xf8, 0x23, 0x0d, 0xf2, 0xbd, 0x28, 0xec, 0x36, 0xbf,
+ 0x61, 0x61, 0xfe, 0xcb, 0xbd, 0xed, 0xf9, 0x29, 0xec, 0x4b, 0x9c, 0x49,
+ 0x5a, 0x13, 0xd8, 0x1f, 0xcf, 0x80, 0x18, 0x50, 0x0b, 0x74, 0xea, 0xc4,
+ 0xfb, 0x21, 0x7e, 0xea, 0xf7, 0xdf, 0x7f, 0x1d, 0x74, 0x18, 0xf7, 0x6f,
+ 0x70, 0x61, 0x62, 0x31, 0x17, 0x32, 0xec, 0x61, 0x60, 0xab, 0xe5, 0xd6,
+ 0xc7, 0xc6, 0xfa, 0x78, 0x3a, 0x62, 0x94, 0x62, 0xf0, 0x03, 0x29, 0x13,
+ 0xe4, 0xcd, 0x0e, 0xf4, 0xaf, 0xf9, 0x24, 0xa5, 0xaf, 0xee, 0xf7, 0x7d,
+ 0x58, 0xc1, 0x76, 0x4f, 0x14, 0xf6, 0x19, 0x6c, 0x9e, 0xb5, 0x2c, 0xa9,
+ 0xae, 0xa4, 0x3d, 0x89, 0xfd, 0xa6, 0x43, 0x89, 0x62, 0x4e, 0x62, 0x32,
+ 0x0f, 0x7d, 0xf1, 0x1a, 0x64, 0xff, 0x5a, 0x29, 0x1e, 0x48, 0x63, 0x4f,
+ 0x87, 0x0b, 0x43, 0x32, 0x31, 0xab, 0xdf, 0x7e, 0x41, 0xef, 0x0f, 0xc9,
+ 0x5c, 0x21, 0xd1, 0x33, 0x0f, 0xfe, 0x9b, 0x2f, 0x10, 0x5f, 0xd4, 0x1b,
+ 0x1f, 0xc5, 0x8c, 0x4b, 0x85, 0xcd, 0xb0, 0x0f, 0x92, 0xba, 0x04, 0xff,
+ 0xe7, 0x52, 0xa9, 0x07, 0x7c, 0x86, 0xfb, 0x25, 0x07, 0xbf, 0xd0, 0x99,
+ 0xa5, 0x01, 0xc8, 0x39, 0xf7, 0x62, 0xcb, 0xc2, 0x56, 0x9c, 0x1d, 0x71,
+ 0x44, 0x8a, 0x1f, 0xff, 0x2f, 0xce, 0xd7, 0x7f, 0xef, 0x1d, 0x6a, 0xa7,
+ 0xe7, 0x75, 0x5f, 0xb0, 0xcb, 0x88, 0x01, 0xb2, 0xfd, 0xc6, 0x6e, 0xa7,
+ 0x23, 0x6d, 0x92, 0xbe, 0x9b, 0x76, 0xbc, 0x5d, 0x63, 0x44, 0xe5, 0xc5,
+ 0x08, 0xef, 0xbf, 0xb3, 0xd1, 0xd0, 0x2f, 0x5c, 0xd7, 0xbe, 0x8e, 0xdf,
+ 0x56, 0xe9, 0x70, 0xf8, 0x6b, 0xe3, 0xf7, 0xed, 0x8d, 0xac, 0xef, 0x76,
+ 0x38, 0x49, 0xac, 0xf5, 0x5b, 0x2f, 0x5f, 0x80, 0xeb, 0x79, 0x3e, 0xb3,
+ 0xc1, 0x5b, 0x97, 0xf3, 0xb6, 0x62, 0x9e, 0x16, 0x6f, 0xad, 0x56, 0xcd,
+ 0x4f, 0x9a, 0xb5, 0x10, 0xe3, 0x16, 0xfe, 0xb2, 0x51, 0xbf, 0x35, 0x86,
+ 0xbd, 0xa8, 0x6d, 0xff, 0x79, 0x23, 0x71, 0x73, 0x1d, 0x4e, 0xab, 0x62,
+ 0x3c, 0x6f, 0xb6, 0xb7, 0xe3, 0x9a, 0x6b, 0x72, 0x8c, 0xc9, 0x87, 0xcf,
+ 0x95, 0x38, 0x3f, 0xdb, 0x29, 0x39, 0xa1, 0xf9, 0x0c, 0x83, 0xe5, 0x9b,
+ 0x2b, 0xdc, 0x2f, 0x13, 0xe7, 0x15, 0x5f, 0x37, 0x93, 0xb7, 0xf8, 0xdd,
+ 0x0b, 0xbf, 0x97, 0xa3, 0x2f, 0x31, 0x26, 0x07, 0x71, 0x7e, 0x97, 0xe1,
+ 0x53, 0x2d, 0x99, 0xef, 0x62, 0xf1, 0x77, 0x00, 0xe7, 0x12, 0x82, 0x8c,
+ 0x51, 0x46, 0x29, 0x53, 0x38, 0xbf, 0x71, 0x5b, 0xde, 0x1d, 0xa0, 0x3c,
+ 0x0f, 0xc8, 0x95, 0x8a, 0x3c, 0xe7, 0x20, 0xcf, 0x94, 0xe5, 0x1c, 0x64,
+ 0xda, 0xf0, 0xf5, 0x7e, 0x7e, 0x67, 0x1d, 0x83, 0xbd, 0x52, 0x1f, 0xe2,
+ 0x25, 0xf0, 0xb5, 0xed, 0x7d, 0x2b, 0x15, 0xd0, 0x1c, 0x4e, 0x76, 0xb6,
+ 0xc1, 0xfb, 0x0e, 0x00, 0xd7, 0x57, 0x9e, 0x93, 0xf4, 0x6c, 0x33, 0xbf,
+ 0xe7, 0xea, 0xe2, 0x99, 0x65, 0xaf, 0xf0, 0xdf, 0xe7, 0x45, 0xe2, 0x4d,
+ 0xe9, 0xcf, 0xf2, 0x9a, 0x71, 0xde, 0x26, 0x8c, 0x19, 0x04, 0x9d, 0x9b,
+ 0x31, 0x3f, 0xf7, 0xb8, 0xda, 0x38, 0xde, 0x0f, 0x55, 0xe1, 0x53, 0x7d,
+ 0x7a, 0xaf, 0xd5, 0x35, 0xb3, 0xfd, 0xcd, 0xde, 0xfb, 0xf1, 0x1c, 0x94,
+ 0xef, 0xc1, 0xb7, 0xf4, 0x89, 0xc9, 0x2f, 0x29, 0x3d, 0x87, 0xb9, 0x02,
+ 0xf9, 0x37, 0xa4, 0x39, 0x8c, 0x2c, 0x6c, 0xcb, 0x5e, 0x1d, 0x1f, 0x5b,
+ 0x91, 0xef, 0xae, 0x80, 0xc6, 0xdd, 0xd9, 0xc2, 0x1a, 0xe9, 0x56, 0x1d,
+ 0xd4, 0xe5, 0xf1, 0x36, 0xec, 0x85, 0x62, 0xb9, 0x0f, 0xc8, 0xf1, 0xd2,
+ 0x20, 0xe8, 0x10, 0x93, 0xa7, 0xe0, 0x37, 0x3f, 0x53, 0xba, 0x43, 0x96,
+ 0x23, 0xd8, 0x57, 0x45, 0xc6, 0x86, 0xe5, 0xfb, 0xf3, 0x09, 0xef, 0x3a,
+ 0xe1, 0x2e, 0x5b, 0x3b, 0xb0, 0x07, 0xca, 0x13, 0xe5, 0x8a, 0xe3, 0x82,
+ 0x88, 0x45, 0x38, 0xef, 0xd3, 0x46, 0xb7, 0x61, 0xde, 0x62, 0x84, 0xf2,
+ 0xcb, 0xbd, 0x85, 0x3c, 0x99, 0x65, 0x5c, 0xc5, 0x77, 0x36, 0x36, 0x29,
+ 0x53, 0x73, 0x16, 0x09, 0xc5, 0x81, 0xae, 0x9c, 0x81, 0x3f, 0x8f, 0x2f,
+ 0x97, 0xfe, 0x77, 0x14, 0xd4, 0xa3, 0xb0, 0x95, 0x05, 0xd8, 0xca, 0x02,
+ 0x6c, 0x24, 0x64, 0xe1, 0x5a, 0x01, 0x36, 0xb2, 0x00, 0x1b, 0x09, 0x7d,
+ 0xf6, 0x3a, 0x62, 0xbb, 0xd7, 0xc0, 0x43, 0xc6, 0xd7, 0x3e, 0x4a, 0x5f,
+ 0x1b, 0x7f, 0xff, 0x03, 0x4c, 0x03, 0x3a, 0xe1, 0xd4, 0x71, 0x00, 0x00,
+ 0x00 };
static const u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_RXP_b06FwRodata[(0x24/4) + 1] = {
- 0x08004580, 0x08004580, 0x080044f8, 0x08004530, 0x08004564, 0x08004588,
- 0x08004588, 0x08004588, 0x08004468, 0x00000000 };
+ 0x08004590, 0x08004590, 0x08004508, 0x08004540, 0x08004574, 0x08004598,
+ 0x08004598, 0x08004598, 0x08004478, 0x00000000 };
static struct fw_info bnx2_rxp_fw_06 = {
- /* Firmware version: 4.0.5 */
+ /* Firmware version: 4.1.1 */
.ver_major = 0x4,
- .ver_minor = 0x0,
- .ver_fix = 0x5,
+ .ver_minor = 0x1,
+ .ver_fix = 0x1,
.start_addr = 0x080031d0,
.text_addr = 0x08000000,
- .text_len = 0x71c0,
+ .text_len = 0x71d0,
.text_index = 0x0,
.gz_text = bnx2_RXP_b06FwText,
.gz_text_len = sizeof(bnx2_RXP_b06FwText),
@@ -2931,22 +2932,22 @@ static struct fw_info bnx2_rxp_fw_06 = {
.data_index = 0x0,
.data = bnx2_RXP_b06FwData,
- .sbss_addr = 0x08007200,
+ .sbss_addr = 0x08007220,
.sbss_len = 0x58,
.sbss_index = 0x0,
- .bss_addr = 0x08007258,
+ .bss_addr = 0x08007278,
.bss_len = 0x44c,
.bss_index = 0x0,
- .rodata_addr = 0x080071c0,
+ .rodata_addr = 0x080071d0,
.rodata_len = 0x24,
.rodata_index = 0x0,
.rodata = bnx2_RXP_b06FwRodata,
};
static u8 bnx2_rv2p_proc1[] = {
- /* Date: 12/07/2007 14:57 */
+ /* Date: 12/07/2007 15:02 */
0xd5, 0x56, 0x41, 0x6b, 0x13, 0x51, 0x10, 0x9e, 0xdd, 0x6c, 0xbb, 0xdb,
0x64, 0xb3, 0x59, 0xaa, 0xd6, 0x50, 0x53, 0x93, 0x06, 0x2f, 0xad, 0x29,
0x6d, 0xaa, 0x82, 0x42, 0xa1, 0x92, 0x4b, 0xc1, 0xf6, 0x20, 0xf5, 0x22,
@@ -3032,7 +3033,7 @@ static u8 bnx2_rv2p_proc1[] = {
0xa7, 0xd8, 0x0d, 0x00, 0x00, 0x00 };
static u8 bnx2_rv2p_proc2[] = {
- /* Date: 12/07/2007 14:57 */
+ /* Date: 12/07/2007 15:02 */
0xed, 0x59, 0x5d, 0x6c, 0x54, 0xc7, 0x15, 0x9e, 0xbd, 0xbb, 0x7b, 0xf7,
0x7a, 0x7d, 0xf7, 0xae, 0x71, 0xa8, 0xff, 0xf9, 0xb3, 0x09, 0xd8, 0xa9,
0x21, 0xce, 0x9a, 0x98, 0x02, 0x55, 0x63, 0x39, 0x95, 0x81, 0xa6, 0x55,
diff --git a/drivers/net/bnx2_fw2.h b/drivers/net/bnx2_fw2.h
index 13b222eb2f6..e6ffa2769f3 100644
--- a/drivers/net/bnx2_fw2.h
+++ b/drivers/net/bnx2_fw2.h
@@ -3173,250 +3173,250 @@ static struct fw_info bnx2_rxp_fw_09 = {
};
static u8 bnx2_xi_rv2p_proc1[] = {
- /* Date: 12/07/2007 16:21 */
- 0xc5, 0x56, 0xcd, 0x6b, 0x13, 0x51, 0x10, 0x9f, 0xdd, 0xa4, 0xd9, 0x34,
- 0xd9, 0x64, 0x97, 0xaa, 0x25, 0xb4, 0x91, 0xa6, 0x55, 0x0f, 0x69, 0x23,
- 0xb6, 0xea, 0xc1, 0x43, 0xc1, 0xda, 0x8b, 0xa0, 0x9e, 0x7a, 0x10, 0xf1,
- 0xdb, 0x20, 0x05, 0xf1, 0x8f, 0x70, 0x51, 0xab, 0x20, 0x78, 0x28, 0x6a,
- 0xb0, 0x0a, 0xea, 0x49, 0x45, 0x3c, 0x34, 0x07, 0x41, 0x50, 0x14, 0x14,
- 0x3c, 0xe9, 0x4d, 0xf0, 0xe3, 0x50, 0x15, 0x3f, 0x0e, 0x7a, 0x13, 0x8f,
- 0xda, 0xf8, 0xde, 0xcc, 0xef, 0xd9, 0xdd, 0x4d, 0xd3, 0x14, 0x0f, 0xba,
- 0xd0, 0xfc, 0xfa, 0xde, 0x9b, 0x37, 0x6f, 0xe6, 0x37, 0xf3, 0x66, 0x9e,
- 0x4f, 0x44, 0x36, 0x05, 0xf5, 0x3e, 0x85, 0x94, 0xb5, 0x12, 0x69, 0x05,
- 0x16, 0xd1, 0x5d, 0x97, 0x31, 0xd8, 0x40, 0xf2, 0x0d, 0x09, 0x04, 0x43,
- 0xbe, 0xfa, 0xfd, 0x4e, 0x5b, 0x4b, 0x1a, 0x13, 0xb4, 0xb5, 0x5f, 0xe3,
- 0x36, 0x7a, 0x5c, 0x2a, 0x28, 0xfc, 0xd5, 0xa0, 0x40, 0x8f, 0xd7, 0xcc,
- 0xde, 0xaf, 0x67, 0x59, 0xef, 0x3b, 0xec, 0x7f, 0x9d, 0x10, 0xdc, 0x52,
- 0x49, 0x8b, 0x1e, 0x20, 0xad, 0xf7, 0x19, 0x5e, 0x4e, 0xeb, 0x71, 0xd1,
- 0x0a, 0xd6, 0xe3, 0x7c, 0x5b, 0xe6, 0xe7, 0xa6, 0x3d, 0x3d, 0x4f, 0xef,
- 0xc7, 0xf5, 0xd8, 0xcb, 0x9c, 0xae, 0xa7, 0x59, 0xaf, 0xac, 0x77, 0x65,
- 0x4e, 0xf3, 0x3e, 0xd7, 0x12, 0x7d, 0xea, 0x8f, 0xf7, 0x6f, 0x56, 0x7a,
- 0x60, 0x37, 0x89, 0x9e, 0x43, 0x25, 0x3d, 0x3f, 0x06, 0xb9, 0x51, 0xc8,
- 0x15, 0x9b, 0xe4, 0xe6, 0xa6, 0x35, 0x3a, 0x54, 0xad, 0x68, 0x7f, 0xfa,
- 0x95, 0xa1, 0xae, 0xf0, 0xd3, 0x27, 0xfe, 0x4e, 0xc2, 0xec, 0x77, 0x83,
- 0xfa, 0x1f, 0x65, 0xdb, 0xa0, 0x96, 0x9b, 0x53, 0x7e, 0x1b, 0x7f, 0x8d,
- 0xbc, 0xc8, 0x39, 0xac, 0xe7, 0xad, 0x5a, 0x37, 0x7e, 0x85, 0xfd, 0xc9,
- 0x86, 0xfc, 0x89, 0xf9, 0xd9, 0xe4, 0x57, 0x98, 0xa7, 0xf4, 0x22, 0x76,
- 0xeb, 0x73, 0x94, 0x0d, 0x7c, 0x4e, 0x0a, 0xfc, 0xa6, 0x62, 0xfb, 0x52,
- 0x2d, 0xf6, 0x7d, 0x6a, 0x2c, 0xf8, 0x69, 0xd6, 0xf5, 0xfc, 0xd3, 0x85,
- 0xf9, 0x72, 0x74, 0x5d, 0xfc, 0xef, 0x80, 0xff, 0x8f, 0xe0, 0xdf, 0x0e,
- 0x5a, 0x6b, 0x17, 0x78, 0x3d, 0xc9, 0xfb, 0x7b, 0x95, 0x3d, 0x1a, 0x57,
- 0x03, 0xfb, 0x81, 0x07, 0x81, 0x07, 0x80, 0xab, 0x80, 0x2b, 0x81, 0x2b,
- 0x80, 0x5d, 0xc0, 0xcb, 0x40, 0x1f, 0xe8, 0x01, 0xf3, 0xc0, 0x8b, 0x40,
- 0x17, 0x98, 0x05, 0xd6, 0x80, 0x57, 0x81, 0x69, 0xe0, 0x31, 0xe0, 0x23,
- 0xe0, 0x13, 0xe0, 0x37, 0xe0, 0x39, 0xa3, 0xcf, 0xc2, 0xb9, 0x40, 0x42,
- 0x3e, 0x58, 0x31, 0x9e, 0xae, 0x21, 0xef, 0x35, 0xcf, 0x58, 0x2f, 0x1b,
- 0x39, 0xc4, 0x97, 0x79, 0x9a, 0x81, 0x5c, 0xd7, 0xec, 0x8d, 0xd8, 0xfd,
- 0x28, 0xb5, 0xbd, 0x17, 0xf1, 0xb8, 0x79, 0xec, 0xcf, 0xe1, 0xed, 0x1e,
- 0x9f, 0x93, 0x4f, 0xc9, 0xbc, 0x31, 0x6b, 0x8f, 0x27, 0x78, 0x34, 0x23,
- 0xf8, 0x39, 0xd3, 0xa9, 0x7e, 0x1b, 0x8d, 0xc9, 0xac, 0x8c, 0x8f, 0xe4,
- 0x0c, 0xcf, 0x46, 0x8f, 0xb1, 0xa7, 0x9d, 0x1d, 0xad, 0xce, 0x33, 0x76,
- 0xb5, 0x3b, 0x57, 0xb0, 0x6a, 0x47, 0xfd, 0xbf, 0x32, 0x2c, 0x98, 0x1c,
- 0x61, 0xa8, 0xb8, 0xa9, 0xa4, 0xc6, 0xcd, 0xee, 0x33, 0x73, 0x8e, 0x46,
- 0xb7, 0x50, 0xe3, 0xfb, 0x92, 0xa4, 0x5a, 0x4a, 0xeb, 0xfd, 0xd9, 0x38,
- 0x2f, 0x72, 0x3d, 0x47, 0x5e, 0x30, 0x16, 0xae, 0x3c, 0x17, 0xf9, 0x57,
- 0x25, 0x97, 0x71, 0xf7, 0x10, 0xc5, 0x3e, 0xb3, 0x2e, 0xf7, 0x31, 0x60,
- 0xbb, 0x7f, 0x58, 0x41, 0xdd, 0x9c, 0x83, 0x7d, 0xc7, 0x4d, 0x1c, 0x7d,
- 0xb6, 0x73, 0x80, 0x64, 0x3c, 0x51, 0x96, 0xf5, 0x89, 0x32, 0xee, 0xf3,
- 0x40, 0x34, 0x1f, 0xe4, 0x5e, 0x24, 0x10, 0xef, 0x7d, 0xb8, 0x17, 0xf1,
- 0x7b, 0x9c, 0x9e, 0xbd, 0x31, 0x1d, 0xce, 0x97, 0x02, 0x55, 0x47, 0x60,
- 0x4f, 0x53, 0x9c, 0x4d, 0x3d, 0x36, 0xf9, 0xce, 0xd3, 0xb3, 0x41, 0x22,
- 0xc2, 0xdf, 0x18, 0x55, 0xc2, 0x71, 0xb2, 0x16, 0xc9, 0x97, 0x76, 0xe7,
- 0x44, 0xf4, 0xe5, 0x55, 0x04, 0xa8, 0x39, 0x8f, 0x1d, 0xf8, 0x35, 0x86,
- 0x3c, 0xee, 0x6d, 0xca, 0x63, 0x53, 0xe7, 0x25, 0x9f, 0x5b, 0xd5, 0xaf,
- 0xbf, 0xaf, 0xcf, 0x22, 0x17, 0x84, 0xf2, 0xd3, 0xd4, 0x43, 0xf0, 0xe4,
- 0xb0, 0x5c, 0x71, 0xee, 0x9e, 0xc4, 0x4d, 0xea, 0xb8, 0x4a, 0xc6, 0x20,
- 0x6a, 0xa7, 0x63, 0xfc, 0xeb, 0x0b, 0xd7, 0xc1, 0x75, 0x2d, 0xe2, 0x15,
- 0xae, 0xbb, 0x71, 0x5e, 0xa2, 0x79, 0x2f, 0xf1, 0xcf, 0x80, 0xa7, 0xde,
- 0x36, 0x75, 0xa1, 0x13, 0x72, 0xdd, 0x4b, 0xc8, 0x89, 0xde, 0xf1, 0x72,
- 0xb8, 0x8e, 0xf8, 0x0d, 0xd4, 0xc1, 0x3f, 0x71, 0x78, 0xd8, 0x22, 0x0e,
- 0xa3, 0xff, 0x37, 0x0e, 0xe8, 0xa7, 0xed, 0xe2, 0x40, 0xb1, 0x38, 0xfc,
- 0x98, 0x5f, 0x5e, 0x1c, 0x08, 0x3c, 0x51, 0x8b, 0x38, 0xa4, 0xc0, 0xd7,
- 0xd7, 0xf9, 0xa5, 0xe3, 0x90, 0x85, 0xdc, 0xe7, 0x90, 0x1c, 0xdb, 0x3d,
- 0x2a, 0xf7, 0xd4, 0xa9, 0x7e, 0x89, 0xf1, 0x3b, 0x52, 0xd1, 0xf5, 0xe7,
- 0x04, 0xd5, 0xe1, 0xff, 0x9b, 0x08, 0x0f, 0x39, 0x65, 0x9f, 0xbc, 0x23,
- 0x6e, 0xd7, 0x0d, 0x5f, 0xb2, 0x5c, 0xaa, 0x08, 0xde, 0x62, 0x79, 0x3f,
- 0xc4, 0x5b, 0x94, 0x5f, 0xe1, 0xcd, 0xa7, 0x9b, 0x7f, 0xea, 0x92, 0xc7,
- 0xfa, 0x86, 0x51, 0xd7, 0x0f, 0xa3, 0xbe, 0x7e, 0xc8, 0x48, 0xfd, 0xae,
- 0xee, 0xe4, 0x3a, 0x4b, 0xdd, 0xa8, 0xb3, 0xd5, 0x9c, 0x8c, 0x7b, 0x72,
- 0xf2, 0x6e, 0x19, 0x76, 0x5c, 0x96, 0xeb, 0xc9, 0x09, 0x76, 0x67, 0xf5,
- 0xbe, 0x02, 0x7d, 0xdc, 0xc5, 0xe2, 0x95, 0x19, 0x57, 0xea, 0xed, 0xcc,
- 0x73, 0xd4, 0x7f, 0xcf, 0xf0, 0x04, 0x7f, 0x37, 0xe9, 0xf9, 0x6e, 0x55,
- 0xef, 0xc2, 0xfc, 0x2a, 0x99, 0x41, 0xb1, 0xef, 0x3a, 0xac, 0x2f, 0x99,
- 0x7d, 0x7d, 0x9a, 0xcf, 0x07, 0xf3, 0xa6, 0xbf, 0x0c, 0x6c, 0xd7, 0xf6,
- 0x78, 0x94, 0x77, 0x24, 0x9e, 0x82, 0x4a, 0xce, 0x76, 0xf4, 0xb6, 0xe2,
- 0x94, 0x2d, 0xe3, 0xa9, 0x93, 0xac, 0x66, 0xd7, 0x94, 0x99, 0x1f, 0xe7,
- 0x44, 0x9e, 0xb8, 0xf3, 0x94, 0xe7, 0xf3, 0xf5, 0x84, 0xcc, 0x3b, 0x3b,
- 0x0d, 0x1f, 0x1e, 0xfb, 0x57, 0x13, 0x3e, 0xf6, 0x5f, 0x12, 0xdc, 0xab,
- 0x9e, 0x22, 0xfa, 0xcb, 0xd4, 0x5c, 0xe9, 0x3f, 0x33, 0x6e, 0x9a, 0x91,
- 0x98, 0x0f, 0x7b, 0xa3, 0xf4, 0x91, 0x0e, 0xd4, 0xff, 0xce, 0x50, 0x9c,
- 0xe2, 0x7d, 0x79, 0xb9, 0xf1, 0x0a, 0xf7, 0x0b, 0xd3, 0x47, 0xe2, 0x7d,
- 0x21, 0x87, 0x3c, 0xbb, 0xdc, 0x26, 0x1f, 0x4d, 0x9d, 0xbd, 0x80, 0x7b,
- 0xb0, 0x58, 0x3f, 0xd6, 0x98, 0x6f, 0xf1, 0x8e, 0x28, 0x22, 0xff, 0x4c,
- 0xdf, 0x5c, 0xec, 0xbd, 0x20, 0xf2, 0xcb, 0x7b, 0x27, 0xf8, 0x2d, 0xde,
- 0x09, 0xff, 0xec, 0x3d, 0x50, 0x58, 0x88, 0xa3, 0xc9, 0xd3, 0x70, 0x1c,
- 0xc3, 0xf9, 0x1a, 0xef, 0xd7, 0x4b, 0xf5, 0xe9, 0x3c, 0x78, 0x9e, 0x04,
- 0xcf, 0x49, 0xea, 0x48, 0x30, 0x31, 0x6e, 0xf2, 0x14, 0xeb, 0xb5, 0xa7,
- 0x6c, 0x16, 0x77, 0x3b, 0xce, 0x58, 0x1a, 0xf3, 0xee, 0x19, 0x91, 0x4b,
- 0xca, 0x7c, 0xc1, 0xe0, 0xd9, 0x53, 0xf2, 0x3e, 0xb4, 0xe9, 0x37, 0xf9,
- 0x0f, 0x65, 0x7b, 0x50, 0x0d, 0x00, 0x00, 0x00 };
+ /* Date: 01/14/2008 15:44 */
+ 0xc5, 0x56, 0xcd, 0x6b, 0x13, 0x51, 0x10, 0x9f, 0xdd, 0x7c, 0x6c, 0x9a,
+ 0x6c, 0xb2, 0xa1, 0x6a, 0x09, 0x35, 0xd2, 0x58, 0x7a, 0x30, 0x6d, 0xc4,
+ 0x56, 0x3d, 0x78, 0x28, 0x54, 0x7a, 0x11, 0xac, 0xa7, 0x1e, 0x44, 0xc4,
+ 0xcf, 0x20, 0x05, 0xf5, 0x8f, 0x70, 0x51, 0xab, 0x20, 0x78, 0x28, 0x68,
+ 0xb4, 0x7e, 0xa0, 0x27, 0x15, 0xf1, 0x90, 0x1c, 0x04, 0x05, 0x45, 0x50,
+ 0xf0, 0xa4, 0x37, 0x41, 0xbd, 0x54, 0xc5, 0x0f, 0xf0, 0xe2, 0x45, 0x8f,
+ 0xda, 0xf8, 0xde, 0xcc, 0xef, 0xd9, 0xdd, 0x4d, 0xd2, 0x14, 0x0f, 0x1a,
+ 0x68, 0x7f, 0xec, 0xdb, 0xdf, 0x9b, 0x37, 0xf3, 0x9b, 0x79, 0x33, 0x9b,
+ 0x27, 0x22, 0x9b, 0xfc, 0xc6, 0x80, 0x42, 0x72, 0xad, 0x58, 0x4a, 0x81,
+ 0x45, 0x74, 0xcf, 0x65, 0xf4, 0x37, 0x91, 0xfc, 0x46, 0x04, 0xfc, 0x91,
+ 0xbc, 0xfa, 0xff, 0x9d, 0x26, 0x4a, 0x1a, 0x63, 0x34, 0xb1, 0x5e, 0xe3,
+ 0x24, 0x3d, 0x29, 0x15, 0x14, 0xfe, 0x6a, 0x92, 0xaf, 0x9f, 0x87, 0xea,
+ 0x0f, 0x1a, 0x19, 0xb6, 0xfb, 0x0e, 0xfb, 0xdf, 0xc4, 0x04, 0xb7, 0x55,
+ 0x52, 0x62, 0x07, 0x48, 0x1b, 0xf3, 0x0c, 0xaf, 0xe6, 0xf4, 0x73, 0xd1,
+ 0xf2, 0x37, 0xe2, 0x7c, 0x5b, 0xd6, 0x17, 0xe6, 0x3c, 0xbd, 0x4e, 0xef,
+ 0x27, 0xf5, 0xb3, 0x97, 0x3e, 0xdd, 0x48, 0xb1, 0x5d, 0x79, 0xdf, 0x9b,
+ 0x3e, 0xcd, 0xfb, 0x5c, 0x4b, 0xec, 0xa9, 0x3f, 0xde, 0xbf, 0x55, 0xd9,
+ 0x81, 0xdf, 0x24, 0x76, 0x0e, 0x96, 0xf4, 0xfa, 0x76, 0xf0, 0xc6, 0xc1,
+ 0x2b, 0xb6, 0xf0, 0x16, 0xe6, 0x34, 0x3a, 0x54, 0xad, 0xe8, 0x78, 0x06,
+ 0x49, 0xe2, 0x49, 0xd0, 0x4c, 0xca, 0x15, 0x9d, 0x06, 0x84, 0xfd, 0x6e,
+ 0x58, 0xef, 0x57, 0xbe, 0x0d, 0x6b, 0xde, 0x82, 0x8a, 0xdb, 0xc4, 0x1b,
+ 0xe6, 0x39, 0x15, 0x63, 0x57, 0xf3, 0xde, 0x2a, 0x9e, 0x89, 0x2f, 0x18,
+ 0x57, 0x26, 0x10, 0x57, 0x24, 0xde, 0x96, 0xf8, 0x82, 0x7a, 0xa5, 0xda,
+ 0xf8, 0xaf, 0xcf, 0x51, 0xbe, 0xf0, 0x39, 0x49, 0xe8, 0x9c, 0x8c, 0xec,
+ 0x4b, 0x76, 0x88, 0xfb, 0x93, 0x35, 0xb3, 0x21, 0xec, 0x3f, 0x91, 0xb6,
+ 0xf7, 0x54, 0xf9, 0x8d, 0xf5, 0x72, 0x3b, 0x1d, 0x12, 0xd0, 0xe1, 0x31,
+ 0xe2, 0x9b, 0xa2, 0x21, 0xbb, 0xc0, 0xef, 0xe3, 0xbc, 0x7f, 0xad, 0xf2,
+ 0x47, 0xe3, 0x3a, 0xe0, 0x7a, 0xe0, 0x01, 0xe0, 0x7e, 0xe0, 0x1a, 0xe0,
+ 0x6a, 0xe0, 0x2a, 0x60, 0x2f, 0xf0, 0x32, 0x30, 0x0f, 0xf4, 0x80, 0x39,
+ 0xe0, 0x05, 0xa0, 0x0b, 0xcc, 0x00, 0x6b, 0xc0, 0xab, 0xc0, 0x14, 0xf0,
+ 0x28, 0xf0, 0x21, 0xf0, 0x31, 0xf0, 0x0b, 0xf0, 0x1c, 0xd0, 0xb1, 0x60,
+ 0x0f, 0xa8, 0x7e, 0x3e, 0xee, 0x47, 0x48, 0xa7, 0xeb, 0xa8, 0x7f, 0xad,
+ 0x33, 0xde, 0x97, 0x0d, 0x0f, 0xf9, 0x65, 0x9d, 0x2e, 0x83, 0xd7, 0x5b,
+ 0xbf, 0x19, 0xb9, 0x27, 0xa5, 0xae, 0xf7, 0x23, 0x9a, 0x37, 0x8f, 0xe3,
+ 0x39, 0xb4, 0xc3, 0xe3, 0x73, 0x72, 0x49, 0x59, 0x37, 0x6e, 0xed, 0xf1,
+ 0x04, 0x8f, 0xa4, 0x05, 0x3f, 0xa7, 0x7b, 0xd4, 0xff, 0x66, 0x73, 0x26,
+ 0x23, 0xcf, 0x87, 0xb3, 0x46, 0x67, 0x63, 0xc7, 0xf8, 0xd3, 0xcd, 0x8f,
+ 0x4e, 0xe7, 0x19, 0xbf, 0xba, 0x9d, 0x2b, 0x58, 0xb5, 0xc3, 0xf1, 0x5f,
+ 0x19, 0x15, 0x8c, 0x8f, 0x31, 0x54, 0xdc, 0x64, 0x5c, 0xe3, 0x56, 0xf7,
+ 0xb9, 0x39, 0x47, 0xa3, 0x5b, 0xa8, 0xf1, 0x7d, 0x89, 0x53, 0x2d, 0xa9,
+ 0xed, 0xfe, 0x6c, 0x9e, 0x17, 0x5e, 0xff, 0xe1, 0x97, 0x8c, 0x85, 0x2b,
+ 0x2f, 0x84, 0xff, 0xba, 0xe4, 0x32, 0xee, 0x1e, 0xa1, 0xc8, 0xcf, 0xbc,
+ 0x97, 0xfb, 0xe8, 0xb3, 0xdf, 0x3f, 0x2c, 0xbf, 0x61, 0xce, 0xc1, 0xbe,
+ 0xe3, 0x26, 0x8f, 0x79, 0xf6, 0x73, 0x90, 0xe4, 0x79, 0xba, 0x2c, 0xef,
+ 0xa7, 0xcb, 0xb8, 0xcf, 0x83, 0xe1, 0x7a, 0x90, 0x7b, 0x11, 0x43, 0xbe,
+ 0xf7, 0xe2, 0x5e, 0x44, 0xef, 0x71, 0xaa, 0x7e, 0x73, 0x2e, 0x58, 0x2f,
+ 0x05, 0xaa, 0x8e, 0xc1, 0x9f, 0x96, 0x3c, 0x9b, 0xbe, 0x6c, 0xea, 0x9d,
+ 0x97, 0xeb, 0x7e, 0x2c, 0xa4, 0xdf, 0x76, 0xaa, 0x04, 0xf3, 0x64, 0xb5,
+ 0xa9, 0x97, 0x6e, 0xe7, 0x84, 0xec, 0xe5, 0x54, 0x06, 0xa8, 0xb5, 0x8e,
+ 0x1d, 0xc4, 0x35, 0x81, 0x3a, 0x5e, 0xdb, 0x52, 0xc7, 0xa6, 0xdf, 0x4b,
+ 0x3d, 0x77, 0xea, 0x5f, 0x7f, 0xdf, 0xa7, 0x85, 0xe7, 0x07, 0xea, 0xd3,
+ 0xf4, 0x43, 0xe8, 0xe4, 0x30, 0xaf, 0xb8, 0x70, 0x5f, 0xf2, 0x26, 0xfd,
+ 0x5c, 0x15, 0xa3, 0x1f, 0xf6, 0xd3, 0x31, 0xf1, 0x0d, 0x04, 0xfb, 0xe7,
+ 0x50, 0x87, 0x7c, 0x05, 0xfb, 0x6e, 0x54, 0x97, 0x70, 0xdd, 0x4b, 0xfe,
+ 0xd3, 0xd0, 0xa9, 0xbf, 0x4b, 0x5f, 0xe8, 0x01, 0x6f, 0xcd, 0x32, 0x3c,
+ 0xb1, 0x3b, 0x59, 0x0e, 0xf6, 0x11, 0xaf, 0x89, 0xfe, 0x87, 0x7d, 0x7d,
+ 0xf5, 0x47, 0x1d, 0xf2, 0x30, 0xfe, 0x7f, 0xf3, 0x80, 0xf9, 0x52, 0xb4,
+ 0x24, 0x0f, 0x09, 0x5a, 0x99, 0xbe, 0x84, 0xf8, 0xa9, 0x83, 0xbe, 0x49,
+ 0xe8, 0xf0, 0x6d, 0x71, 0x79, 0x7d, 0x33, 0xe0, 0x7d, 0x0d, 0xf0, 0xb8,
+ 0x2e, 0xc6, 0xe5, 0xfe, 0x39, 0xd5, 0x2f, 0x11, 0xdd, 0xc6, 0x2a, 0xba,
+ 0xaf, 0x9c, 0xa0, 0x06, 0xe2, 0x7a, 0x1b, 0x8a, 0x2f, 0xab, 0xfc, 0x93,
+ 0xef, 0x84, 0x3b, 0x0d, 0xa3, 0x83, 0xbc, 0x2e, 0x55, 0x04, 0x6f, 0x33,
+ 0x3f, 0x1f, 0xd0, 0x23, 0xac, 0x9b, 0xe8, 0x91, 0xa7, 0x5b, 0x7f, 0xfa,
+ 0x8d, 0xc7, 0xf6, 0x46, 0xd1, 0xaf, 0x0f, 0xa1, 0x6f, 0x7e, 0x48, 0x4b,
+ 0x5f, 0xae, 0x4e, 0x71, 0xff, 0xa4, 0x3e, 0xf4, 0xcf, 0x6a, 0x56, 0x9e,
+ 0xfb, 0xb3, 0xf2, 0x1d, 0x36, 0xea, 0xb8, 0xcc, 0xeb, 0xcf, 0x0a, 0xf6,
+ 0x65, 0xf4, 0xbe, 0x02, 0x7d, 0xdc, 0xc5, 0xf4, 0xca, 0xbc, 0x2b, 0x7d,
+ 0x74, 0xfe, 0x05, 0xfa, 0xba, 0x67, 0x74, 0x42, 0xbc, 0x5b, 0xf4, 0x7a,
+ 0x1f, 0x7f, 0xf2, 0x2c, 0xe9, 0xab, 0x38, 0xc3, 0xe2, 0xdf, 0x0d, 0x78,
+ 0x5f, 0x32, 0xfb, 0x06, 0xb4, 0x9e, 0x4f, 0x16, 0xcd, 0xdc, 0x18, 0xdc,
+ 0xa1, 0xfd, 0xf1, 0x28, 0xe7, 0x48, 0x3e, 0x05, 0x15, 0xcf, 0x76, 0xf4,
+ 0xb6, 0xe2, 0xac, 0x2d, 0xcf, 0xb3, 0x27, 0xd9, 0xcc, 0xae, 0x59, 0xb3,
+ 0x3e, 0xc9, 0x05, 0x3a, 0x7d, 0xf7, 0x19, 0xaf, 0xe7, 0x1a, 0x31, 0x59,
+ 0x77, 0xa6, 0x8c, 0x1e, 0x1e, 0xc7, 0x57, 0x13, 0x3d, 0xf6, 0x5d, 0x14,
+ 0xdc, 0x4b, 0x3b, 0x19, 0xd3, 0x35, 0x57, 0xe6, 0xca, 0xbc, 0x9b, 0x62,
+ 0x24, 0xd6, 0xc3, 0xde, 0x2c, 0xf3, 0x21, 0x81, 0xbe, 0xde, 0x13, 0xc8,
+ 0x53, 0x74, 0xde, 0xae, 0x34, 0x5f, 0xc1, 0x39, 0x60, 0xe6, 0x43, 0xb4,
+ 0xdf, 0x67, 0x51, 0x67, 0xd7, 0xba, 0xd4, 0xa3, 0xe9, 0x9f, 0x97, 0x16,
+ 0xe5, 0x1e, 0xb4, 0x9b, 0xb3, 0x1a, 0x73, 0x1d, 0xbe, 0x0f, 0x8a, 0xa8,
+ 0x3f, 0x33, 0x0f, 0xdb, 0x7d, 0x07, 0x08, 0x7f, 0x65, 0xf3, 0x3f, 0xdf,
+ 0x61, 0xfe, 0xff, 0xb3, 0x39, 0x5f, 0x58, 0xca, 0xa3, 0xa9, 0xd3, 0x60,
+ 0x1e, 0x83, 0xf5, 0x1a, 0x9d, 0xc3, 0xcb, 0xcd, 0xdf, 0x1c, 0x74, 0x3e,
+ 0x06, 0x9d, 0xe3, 0x94, 0x88, 0xb1, 0x30, 0x6e, 0xfc, 0x14, 0xdb, 0xb5,
+ 0x67, 0x6d, 0xa6, 0xbb, 0x89, 0x33, 0x96, 0xc6, 0x9c, 0x7b, 0x46, 0x78,
+ 0x71, 0x59, 0x2f, 0x18, 0x3c, 0x7b, 0x4a, 0xbe, 0xfb, 0x6c, 0xfa, 0x0d,
+ 0x6d, 0x29, 0x98, 0xe1, 0x30, 0x0d, 0x00, 0x00, 0x00 };
static u8 bnx2_xi_rv2p_proc2[] = {
- /* Date: 12/07/2007 16:21 */
- 0xad, 0x58, 0x5d, 0x6c, 0xd3, 0x55, 0x14, 0xbf, 0xfd, 0x58, 0xdb, 0xb5,
+ /* Date: 01/14/2008 15:44 */
+ 0xad, 0x58, 0x5d, 0x6c, 0xd3, 0x55, 0x14, 0xbf, 0xfd, 0x58, 0xdb, 0x75,
0xff, 0xb6, 0x63, 0x9b, 0xdd, 0xa7, 0x6e, 0x6e, 0x61, 0x6c, 0xd8, 0xcd,
0xd1, 0x8d, 0x4f, 0x4d, 0x5c, 0x86, 0x19, 0x20, 0x26, 0x8c, 0x61, 0xd4,
- 0x37, 0xd8, 0x90, 0xb2, 0xb1, 0x8d, 0x2c, 0x8c, 0xf0, 0xc0, 0x8b, 0x0d,
+ 0x37, 0xd8, 0x90, 0xb2, 0xb2, 0x8d, 0x2c, 0x8c, 0xf0, 0xc0, 0x8b, 0x0d,
0xd3, 0xf1, 0xd2, 0x07, 0x47, 0xb2, 0x0d, 0x8d, 0xc1, 0x45, 0x7d, 0x40,
- 0x9f, 0xec, 0x83, 0x32, 0x30, 0xc6, 0xc4, 0xe8, 0x42, 0xf0, 0x01, 0x48,
+ 0x9f, 0xec, 0x83, 0x52, 0x30, 0xc6, 0xc4, 0xe8, 0x42, 0xf0, 0x01, 0x48,
0x30, 0xc6, 0x68, 0x48, 0x08, 0xea, 0x32, 0x10, 0x75, 0x0c, 0xfb, 0x64,
- 0x98, 0xf7, 0x9e, 0xdf, 0xb9, 0xff, 0xfe, 0xff, 0x6d, 0x27, 0x18, 0xec,
+ 0x98, 0xf7, 0x9e, 0xdf, 0xb9, 0xff, 0xfe, 0xff, 0x5d, 0x27, 0x18, 0xec,
0x43, 0x4f, 0xef, 0xbd, 0xe7, 0x9e, 0x7b, 0x3e, 0x7e, 0xe7, 0x9c, 0x7b,
- 0x5b, 0x24, 0x84, 0x70, 0x8a, 0x44, 0xaa, 0x46, 0x52, 0x11, 0x70, 0xb8,
- 0x04, 0x3e, 0x6b, 0x8b, 0x88, 0x5c, 0x4b, 0xf9, 0xe4, 0x77, 0x81, 0x78,
- 0xc9, 0x59, 0x4e, 0x63, 0xb7, 0x50, 0x34, 0x2c, 0x44, 0xc2, 0x4a, 0x4b,
- 0x98, 0x5e, 0x65, 0xfa, 0x3b, 0xd3, 0xc7, 0x1d, 0xa0, 0x57, 0x78, 0xbc,
- 0x85, 0xc7, 0xd7, 0x78, 0xfc, 0x23, 0xd3, 0x8d, 0x3c, 0xbf, 0x99, 0x69,
- 0x92, 0xe9, 0x76, 0x5e, 0x9f, 0x65, 0x2a, 0x3f, 0x09, 0x43, 0x7e, 0xc9,
- 0xe5, 0x26, 0xad, 0xa7, 0x81, 0xe9, 0x26, 0xe8, 0xbb, 0xa7, 0x56, 0xf1,
- 0x2d, 0x2c, 0x67, 0xf8, 0x30, 0x7f, 0x7d, 0x02, 0xb4, 0x06, 0xbb, 0x3e,
- 0x4e, 0x3c, 0xad, 0xf7, 0x83, 0xf4, 0x06, 0x41, 0xfb, 0xd8, 0xfe, 0x8e,
- 0x28, 0x91, 0xe4, 0x7e, 0x27, 0xc6, 0x5d, 0x0d, 0xca, 0x0f, 0xc5, 0xc2,
- 0xed, 0x54, 0x72, 0x5a, 0x7c, 0x9e, 0xf3, 0x98, 0x7f, 0x35, 0x0c, 0xfa,
- 0x9a, 0x1f, 0xf4, 0x17, 0x7f, 0xa1, 0xfc, 0x5e, 0x5e, 0x8e, 0x07, 0x58,
- 0xbe, 0xc1, 0x6a, 0x07, 0xb0, 0x7f, 0xce, 0x80, 0x1e, 0x2f, 0xd7, 0x42,
+ 0x5b, 0x2c, 0x84, 0x70, 0x8a, 0x44, 0xaa, 0x56, 0x52, 0x61, 0x38, 0x5c,
+ 0x02, 0x9f, 0xb5, 0xc5, 0x44, 0xae, 0xa5, 0x7c, 0xf2, 0xbb, 0x40, 0xbc,
+ 0xe4, 0xac, 0xa0, 0xb1, 0x5b, 0x28, 0x1a, 0x12, 0x22, 0x61, 0xa5, 0xa5,
+ 0x4c, 0xaf, 0x32, 0xfd, 0x9d, 0xe9, 0xe3, 0x0e, 0xd0, 0x2b, 0x3c, 0xde,
+ 0xc2, 0xe3, 0x6b, 0x3c, 0xfe, 0x91, 0xe9, 0x46, 0x9e, 0xdf, 0xcc, 0x34,
+ 0xc9, 0x74, 0x3b, 0xaf, 0xa7, 0x99, 0xca, 0x4f, 0xc2, 0x90, 0x5f, 0x72,
+ 0xb9, 0x59, 0xeb, 0x69, 0x60, 0xba, 0x19, 0xfa, 0xee, 0xa9, 0x53, 0x7c,
+ 0xf3, 0x4b, 0x59, 0x3e, 0xcc, 0x5f, 0x9f, 0x00, 0xad, 0xc5, 0xae, 0x8f,
+ 0x13, 0x4f, 0xeb, 0xfd, 0x20, 0x7d, 0x01, 0xd0, 0x7e, 0xb6, 0xbf, 0x33,
+ 0x42, 0x24, 0xb9, 0xdf, 0x89, 0x71, 0x77, 0xa3, 0xf2, 0x43, 0x89, 0x70,
+ 0x3b, 0x95, 0x9c, 0x56, 0x9f, 0xe7, 0x3c, 0xe6, 0x5f, 0x0d, 0x81, 0xbe,
+ 0xe6, 0x07, 0xfd, 0xc5, 0x5f, 0x28, 0xbf, 0x97, 0x96, 0x62, 0x45, 0x2c,
+ 0xdf, 0x60, 0xb5, 0x8b, 0xb0, 0x7f, 0xd6, 0x80, 0x1e, 0x2f, 0xd7, 0x41,
0xbf, 0xef, 0x9f, 0x52, 0xf3, 0x2e, 0x91, 0x60, 0x39, 0x42, 0x68, 0x3d,
- 0x79, 0x7d, 0x10, 0xfb, 0x56, 0xad, 0xc1, 0xea, 0x5b, 0x71, 0x8c, 0xab,
- 0x3e, 0x28, 0xa2, 0xb8, 0x9c, 0x4e, 0x69, 0xfe, 0x7c, 0x72, 0xdd, 0x52,
- 0x2e, 0xe4, 0x8b, 0x3a, 0x1f, 0x29, 0x93, 0x88, 0x82, 0x8a, 0xe6, 0xec,
- 0x73, 0x20, 0x7f, 0x6a, 0xb5, 0x9a, 0x77, 0x8a, 0x1e, 0x97, 0x9a, 0xf7,
- 0x88, 0x9e, 0x01, 0xed, 0x5f, 0xac, 0xc7, 0x3d, 0x44, 0xca, 0x7b, 0xc7,
- 0x95, 0x9d, 0x61, 0xb1, 0xcf, 0x19, 0x26, 0x7e, 0xf8, 0xc5, 0xe5, 0x33,
- 0x3e, 0x03, 0xff, 0x97, 0x35, 0x06, 0xd9, 0x12, 0x6f, 0xc3, 0xbe, 0xd2,
- 0x18, 0xe8, 0x64, 0xac, 0x40, 0x91, 0x68, 0x7c, 0x94, 0x86, 0x2d, 0x37,
- 0xd7, 0xf9, 0x88, 0x2f, 0xd1, 0xac, 0xe3, 0xa7, 0xe3, 0xa5, 0xe2, 0xf8,
- 0x89, 0x8c, 0x23, 0xbb, 0xa5, 0x1e, 0x7e, 0xfd, 0x75, 0xb5, 0xe2, 0x97,
- 0xce, 0xad, 0xc3, 0x39, 0x19, 0xfd, 0xac, 0xf1, 0xff, 0xe8, 0x3f, 0xc4,
- 0x5f, 0xc9, 0xeb, 0x60, 0xbf, 0xd4, 0x4a, 0xbf, 0x28, 0x5a, 0xed, 0x48,
- 0x34, 0xdb, 0xe3, 0x71, 0x7d, 0x22, 0x4c, 0xbf, 0x6f, 0x75, 0x16, 0x91,
- 0x5f, 0x77, 0x61, 0xfe, 0x54, 0xd7, 0x39, 0xc4, 0x63, 0x07, 0xd9, 0x2f,
- 0xfc, 0x6f, 0x7c, 0x8a, 0x5d, 0xbd, 0x41, 0x35, 0x7e, 0xa5, 0x3d, 0x7e,
- 0x01, 0xeb, 0x05, 0x63, 0xf0, 0xeb, 0x2e, 0x96, 0xba, 0xc3, 0xe5, 0x50,
- 0x24, 0xe9, 0x19, 0xa3, 0xa1, 0x31, 0x47, 0xeb, 0x86, 0x38, 0x99, 0xc2,
- 0xfa, 0xe1, 0x80, 0x1a, 0xef, 0x8a, 0x2e, 0x60, 0x1c, 0x1d, 0x18, 0xe7,
- 0x8d, 0x4e, 0xf8, 0xe1, 0x96, 0x13, 0xf2, 0x18, 0x5e, 0x7e, 0x37, 0xc5,
- 0xc1, 0x21, 0x8c, 0x2e, 0xd0, 0x37, 0x69, 0xfd, 0x6f, 0x47, 0x92, 0xec,
- 0xee, 0x0a, 0xb9, 0xcf, 0x81, 0x91, 0x71, 0x6d, 0xe2, 0x56, 0xe3, 0xfe,
- 0x61, 0xf1, 0x3b, 0x6e, 0x68, 0xbc, 0xb2, 0xff, 0xd9, 0xbf, 0xef, 0x89,
- 0x6c, 0x9c, 0x82, 0x76, 0x35, 0x80, 0x7a, 0xea, 0xb3, 0xf1, 0xaa, 0xf1,
- 0x69, 0xf7, 0x33, 0xc7, 0xc7, 0x82, 0x17, 0x22, 0x12, 0x27, 0x36, 0xdc,
- 0x30, 0x4e, 0x2b, 0xa4, 0xbf, 0x74, 0xfc, 0x95, 0x20, 0xaf, 0x18, 0x64,
- 0x79, 0x03, 0x6c, 0xd7, 0x10, 0xdb, 0x75, 0xc7, 0xaf, 0xfd, 0xaa, 0xed,
- 0x01, 0x3d, 0x69, 0xb3, 0xc7, 0x21, 0xf1, 0x64, 0xc7, 0x21, 0xeb, 0x93,
- 0xfc, 0xa6, 0x0e, 0x3f, 0xaa, 0xea, 0x41, 0x4d, 0x3b, 0x1b, 0x14, 0x9f,
- 0x27, 0x36, 0x9d, 0xb2, 0xe3, 0x50, 0xe7, 0xe3, 0x9e, 0x5a, 0x2d, 0x5f,
- 0xe1, 0x32, 0x2d, 0x71, 0x89, 0xb8, 0x9d, 0x4e, 0x59, 0xf3, 0xb3, 0x32,
- 0x4f, 0x7e, 0xda, 0xf3, 0x42, 0xfb, 0xe5, 0x70, 0x90, 0x0a, 0x54, 0xfb,
- 0xe5, 0x79, 0xfb, 0x79, 0xc0, 0xb7, 0xd7, 0xc4, 0x4f, 0xe9, 0x06, 0xf6,
- 0x1f, 0xd3, 0xc8, 0x46, 0x25, 0xaf, 0x9b, 0xe5, 0xb7, 0xb2, 0x7c, 0xc3,
- 0x92, 0x77, 0x4a, 0xbf, 0x4e, 0x33, 0xdf, 0x74, 0xdc, 0x32, 0x79, 0xa7,
- 0xfd, 0x47, 0xe7, 0x47, 0x2f, 0xcf, 0xab, 0xfd, 0x55, 0x0f, 0xc8, 0xc3,
- 0x4d, 0xa6, 0xbc, 0xef, 0xcc, 0x7c, 0x53, 0xeb, 0x01, 0xf1, 0x1c, 0x0f,
- 0xed, 0xf5, 0xe4, 0x4f, 0x59, 0x4f, 0xc8, 0x0e, 0x9f, 0x71, 0x8e, 0xeb,
- 0xc7, 0xa8, 0x3a, 0xa7, 0x9c, 0xf5, 0x2e, 0x67, 0xbd, 0x65, 0xbf, 0x6a,
- 0xe6, 0x3a, 0xb3, 0xd7, 0x5a, 0x2f, 0xd6, 0x5a, 0xf2, 0x5e, 0x8d, 0x1b,
- 0x97, 0x73, 0xfb, 0x85, 0xcd, 0x9f, 0x09, 0x41, 0xfe, 0xf7, 0x72, 0x7c,
+ 0x79, 0x7d, 0x10, 0xfb, 0x56, 0xad, 0xc1, 0xea, 0x5b, 0x31, 0x8c, 0xab,
+ 0x3f, 0x28, 0xa6, 0xb8, 0x9c, 0x4e, 0x69, 0xfe, 0x7c, 0x72, 0xdd, 0x52,
+ 0x2e, 0xe4, 0x8b, 0x7a, 0x1f, 0x29, 0x93, 0x88, 0x80, 0x8a, 0x96, 0xdc,
+ 0x73, 0x20, 0x7f, 0x6a, 0xb5, 0x9a, 0x77, 0x8a, 0x5e, 0x97, 0x9a, 0xf7,
+ 0x88, 0xde, 0xb8, 0xf6, 0x2f, 0xd6, 0x63, 0x1e, 0x22, 0x15, 0x7d, 0xe3,
+ 0xca, 0xce, 0x90, 0xd8, 0xe7, 0x0c, 0x11, 0x3f, 0xfc, 0xe2, 0xf2, 0x19,
+ 0x9f, 0x81, 0xff, 0xcb, 0x5a, 0x83, 0x6c, 0x89, 0xb5, 0x63, 0x5f, 0x59,
+ 0x14, 0x74, 0x32, 0x5a, 0xa0, 0x48, 0x24, 0x36, 0x4a, 0xc3, 0xd6, 0x9b,
+ 0xeb, 0x7c, 0xc4, 0x97, 0x68, 0xd1, 0xf1, 0xd3, 0xf1, 0x52, 0x71, 0xfc,
+ 0x44, 0xc6, 0x91, 0xdd, 0xd2, 0x00, 0xbf, 0xfe, 0xba, 0x5a, 0xf1, 0x4b,
+ 0xe7, 0xd6, 0xe3, 0x9c, 0xac, 0x7e, 0xd6, 0xf8, 0x7f, 0xf4, 0x1f, 0xe2,
+ 0xaf, 0xe4, 0x75, 0xb2, 0x5f, 0xea, 0xa4, 0x5f, 0x14, 0xad, 0x71, 0x24,
+ 0x5a, 0xec, 0xf1, 0xb8, 0x3e, 0x11, 0xa2, 0xdf, 0xb7, 0xba, 0x8a, 0xc9,
+ 0xaf, 0xbb, 0x30, 0x7f, 0xaa, 0xfb, 0x1c, 0xe2, 0xb1, 0x83, 0xec, 0x17,
+ 0xfe, 0x37, 0x3e, 0xc5, 0xae, 0xbe, 0x80, 0x1a, 0xbf, 0xd2, 0x11, 0xbb,
+ 0x80, 0xf5, 0x82, 0x31, 0xf8, 0x75, 0x17, 0x4b, 0xdd, 0xe1, 0x72, 0x28,
+ 0x92, 0xf4, 0x8c, 0xd1, 0xd0, 0x98, 0xa5, 0x75, 0x43, 0x9c, 0x4c, 0x61,
+ 0xfd, 0x70, 0x91, 0x1a, 0xef, 0x8a, 0xcc, 0x63, 0x1c, 0x89, 0x8f, 0xf3,
+ 0x46, 0x27, 0xfc, 0x70, 0xcb, 0x09, 0x79, 0x0c, 0x2f, 0xbf, 0x9b, 0xe2,
+ 0xe0, 0x10, 0x46, 0x37, 0xe8, 0x9b, 0xb4, 0xfe, 0xb7, 0x23, 0x49, 0x76,
+ 0x77, 0x07, 0xdd, 0xe7, 0xc0, 0xc8, 0xb8, 0x36, 0x71, 0xab, 0x71, 0xff,
+ 0xb0, 0xf8, 0x1d, 0x37, 0x34, 0x5e, 0xd9, 0xff, 0xec, 0xdf, 0xf7, 0x44,
+ 0x2e, 0x4e, 0x41, 0xbb, 0x1b, 0x41, 0x3d, 0x0d, 0xb9, 0x78, 0xd5, 0xf8,
+ 0xb4, 0xfb, 0x99, 0xe3, 0x63, 0xc1, 0x0b, 0x11, 0x89, 0x13, 0x1b, 0x6e,
+ 0x18, 0xa7, 0x95, 0xd2, 0x5f, 0x3a, 0xfe, 0x4a, 0x90, 0x57, 0x0c, 0xb2,
+ 0xbc, 0x38, 0xdb, 0x35, 0xc4, 0x76, 0xdd, 0xf1, 0x6b, 0xbf, 0x6a, 0x7b,
+ 0x40, 0x4f, 0xda, 0xec, 0x71, 0x48, 0x3c, 0xd9, 0x71, 0xc8, 0xfa, 0x24,
+ 0xbf, 0xa9, 0xc7, 0x8f, 0xea, 0x06, 0x50, 0xd3, 0xce, 0x46, 0xc5, 0xe7,
+ 0x89, 0x4e, 0xa7, 0xec, 0x38, 0xd4, 0xf9, 0xb8, 0xa7, 0x4e, 0xcb, 0x57,
+ 0xb8, 0xcc, 0x48, 0x5c, 0x22, 0x6e, 0xa7, 0x53, 0xd6, 0xfc, 0xac, 0xca,
+ 0x93, 0x9f, 0xf6, 0xbc, 0xd0, 0x7e, 0x39, 0x1c, 0xa0, 0x02, 0xd5, 0x71,
+ 0x79, 0xce, 0x7e, 0x1e, 0xf0, 0xed, 0x35, 0xf1, 0x53, 0xb6, 0x81, 0xfd,
+ 0xc7, 0x34, 0xbc, 0x51, 0xc9, 0xeb, 0x61, 0xf9, 0x6d, 0x2c, 0xdf, 0xb0,
+ 0xe4, 0x9d, 0xd2, 0xaf, 0xcb, 0xcc, 0x37, 0x1d, 0xb7, 0x6c, 0xde, 0x69,
+ 0xff, 0xd1, 0xf9, 0x91, 0xcb, 0x73, 0x6a, 0x7f, 0xf5, 0x03, 0xf2, 0x70,
+ 0x93, 0x29, 0xef, 0x3b, 0x33, 0xdf, 0xd4, 0x7a, 0x91, 0x78, 0x8e, 0x87,
+ 0xf6, 0x7a, 0xf2, 0xa7, 0xac, 0x27, 0x64, 0x87, 0xcf, 0x38, 0xc7, 0xf5,
+ 0x63, 0x54, 0x9d, 0x53, 0xc1, 0x7a, 0x57, 0xb0, 0xde, 0xb2, 0x5f, 0xb5,
+ 0x70, 0x9d, 0xd9, 0x6b, 0xad, 0x17, 0x6b, 0x2d, 0x79, 0xaf, 0xc6, 0x4d,
+ 0x4b, 0xcb, 0xfb, 0x85, 0xcd, 0x9f, 0x09, 0x41, 0xfe, 0xf7, 0x72, 0x7c,
0x3c, 0x79, 0xfa, 0x8b, 0xe6, 0x07, 0xbe, 0xb6, 0x11, 0xbf, 0xcf, 0xc4,
- 0xbf, 0xdd, 0xde, 0xca, 0x3c, 0x75, 0x27, 0xdb, 0x7e, 0xf8, 0xb3, 0xd7,
- 0x19, 0x24, 0xbe, 0x1b, 0x23, 0x6a, 0xdf, 0x49, 0x87, 0xf6, 0x53, 0x07,
- 0xea, 0x90, 0x03, 0xf6, 0x56, 0xb3, 0xbd, 0x72, 0xb9, 0x99, 0xf0, 0xef,
+ 0xbf, 0xdd, 0xde, 0xaa, 0x3c, 0x75, 0x27, 0xd7, 0x7e, 0xf8, 0xb3, 0xcf,
+ 0x19, 0x20, 0xbe, 0x1b, 0x23, 0x6a, 0xdf, 0x49, 0x87, 0xf6, 0x53, 0x27,
+ 0xea, 0x90, 0x03, 0xf6, 0xd6, 0xb0, 0xbd, 0x72, 0xb9, 0x85, 0xf0, 0xef,
0xbb, 0x31, 0x62, 0xb5, 0xd7, 0xf8, 0x97, 0xf3, 0xec, 0xb8, 0x19, 0xe1,
- 0x3e, 0xd6, 0x87, 0xbc, 0xf0, 0xed, 0xff, 0x5c, 0xeb, 0xc3, 0xe7, 0x86,
- 0xf5, 0xf9, 0x4a, 0x5e, 0x95, 0x98, 0x1f, 0x55, 0xfb, 0x1f, 0x13, 0x0c,
- 0x33, 0x31, 0xdc, 0x88, 0xfa, 0x77, 0xe7, 0x00, 0xf4, 0x1f, 0x6e, 0xd0,
+ 0x3e, 0xd6, 0x8f, 0xbc, 0xf0, 0xed, 0xff, 0x5c, 0xeb, 0xc3, 0xe7, 0x86,
+ 0xf4, 0xf9, 0x4a, 0x5e, 0xb5, 0x98, 0x1b, 0x55, 0xfb, 0x1f, 0x13, 0x0c,
+ 0x33, 0x31, 0xdc, 0x84, 0xfa, 0x77, 0xe7, 0x00, 0xf4, 0x1f, 0x6e, 0xd4,
0x7d, 0x1c, 0x38, 0x16, 0x5c, 0xff, 0xbf, 0x9e, 0xc8, 0xe7, 0x97, 0x41,
- 0x07, 0xf8, 0x4a, 0xd9, 0xae, 0x22, 0xb6, 0x2b, 0x2a, 0xb2, 0xeb, 0xec,
- 0x5e, 0xca, 0x97, 0x0e, 0xe6, 0x7b, 0x56, 0xd7, 0xe3, 0x1c, 0x3e, 0xd8,
- 0x5f, 0xc0, 0xe7, 0xe7, 0xf3, 0x57, 0x3e, 0xb9, 0xb3, 0x8c, 0xa3, 0x7e,
- 0xe6, 0x73, 0xe7, 0xa9, 0xf3, 0x18, 0xa5, 0xd7, 0x50, 0x9d, 0x3f, 0x73,
- 0x7c, 0x56, 0xf1, 0x05, 0x4d, 0x9c, 0xdb, 0xed, 0xfa, 0xe9, 0xfe, 0xa3,
- 0xfb, 0x5f, 0xf1, 0x45, 0xc4, 0xc1, 0xd0, 0x4a, 0x7e, 0x76, 0xab, 0xe9,
- 0x99, 0xc5, 0x59, 0x1d, 0x27, 0x83, 0xec, 0x9c, 0x1f, 0x55, 0xe7, 0x7f,
- 0x98, 0xe5, 0x7f, 0xa7, 0xc5, 0xff, 0xe0, 0x7f, 0x22, 0xfa, 0xa8, 0x7e,
- 0xcf, 0xd7, 0x97, 0xbf, 0xb8, 0x9f, 0x9b, 0x27, 0x6a, 0xfe, 0xc2, 0x43,
- 0xfb, 0x63, 0x77, 0x9b, 0xd5, 0xfe, 0x7a, 0x31, 0x97, 0x42, 0x7e, 0x75,
- 0x33, 0x0e, 0xf7, 0x71, 0xbd, 0xbe, 0xe1, 0x57, 0x13, 0x3e, 0xd1, 0xb7,
- 0x93, 0xfc, 0x21, 0x22, 0x01, 0xf8, 0xa7, 0xef, 0x45, 0xed, 0x4f, 0xcc,
- 0x57, 0x52, 0xbf, 0x75, 0x89, 0x6e, 0xaf, 0x41, 0xfc, 0x95, 0x41, 0xd0,
- 0x08, 0xd7, 0xf9, 0x39, 0xb3, 0x8f, 0x81, 0x9e, 0xf6, 0xe8, 0xba, 0x8c,
- 0x7e, 0xfe, 0x95, 0x47, 0x31, 0xc8, 0x20, 0x35, 0xa1, 0x3e, 0x77, 0x36,
- 0x18, 0xb4, 0xde, 0xd3, 0x04, 0x3c, 0x89, 0x3a, 0xdd, 0xe7, 0xf0, 0xe1,
- 0x3e, 0x50, 0x99, 0xe9, 0x77, 0xd6, 0x7e, 0x58, 0x68, 0xe9, 0x07, 0xfa,
+ 0x07, 0xf8, 0xca, 0xd8, 0xae, 0x62, 0xb6, 0x2b, 0x22, 0x72, 0xeb, 0xec,
+ 0x5e, 0xca, 0x97, 0x4e, 0xe6, 0x7b, 0x56, 0xd7, 0xe3, 0x65, 0x7c, 0xb0,
+ 0xbf, 0x80, 0xcf, 0xcf, 0xe7, 0xaf, 0x7c, 0x72, 0xd3, 0x8c, 0xa3, 0x01,
+ 0xe6, 0x73, 0xe7, 0xa9, 0xf3, 0x18, 0x65, 0xd6, 0x50, 0x9d, 0x3f, 0x73,
+ 0x3c, 0xad, 0xf8, 0x02, 0x26, 0xce, 0xed, 0x76, 0xfd, 0x74, 0xff, 0xd1,
+ 0xfd, 0xaf, 0xf8, 0xc2, 0xe2, 0x60, 0x70, 0x25, 0x3f, 0xbb, 0xd5, 0xf4,
+ 0xcc, 0x42, 0x5a, 0xc7, 0xc9, 0x20, 0x3b, 0xe7, 0x46, 0xd5, 0xf9, 0x1f,
+ 0xe6, 0xf8, 0xdf, 0x69, 0xf1, 0x3f, 0xf8, 0x9f, 0x88, 0x3c, 0xaa, 0xdf,
+ 0xf3, 0xf5, 0xe5, 0x2f, 0xee, 0x2f, 0xcf, 0x13, 0x35, 0x7f, 0xe1, 0xa1,
+ 0xfd, 0xb1, 0xbb, 0xdd, 0x6a, 0x7f, 0x83, 0x98, 0x4d, 0x21, 0xbf, 0x7a,
+ 0x18, 0x87, 0xfb, 0xb8, 0x5e, 0xdf, 0xf0, 0xab, 0x09, 0x9f, 0xe8, 0xdf,
+ 0x49, 0xfe, 0x10, 0xe1, 0x22, 0xf8, 0xa7, 0xff, 0x45, 0xed, 0x4f, 0xcc,
+ 0x57, 0x51, 0xbf, 0x75, 0x89, 0x1e, 0xaf, 0x41, 0xfc, 0x55, 0x01, 0xd0,
+ 0x30, 0xd7, 0xf9, 0x59, 0xb3, 0x8f, 0x81, 0x9e, 0xf6, 0xe8, 0xba, 0x8c,
+ 0x7e, 0xfe, 0x95, 0x47, 0x31, 0xc8, 0x20, 0x35, 0xa3, 0x3e, 0x77, 0x35,
+ 0x1a, 0xb4, 0xde, 0xdb, 0x0c, 0x3c, 0x89, 0x7a, 0xdd, 0xe7, 0xf0, 0xe1,
+ 0x3e, 0x50, 0x95, 0xed, 0x77, 0xd6, 0x7e, 0x58, 0x68, 0xe9, 0x07, 0xfa,
0x3c, 0xed, 0x47, 0x2d, 0x97, 0x86, 0xb2, 0xaf, 0x58, 0xfb, 0xa1, 0xee,
- 0x13, 0x4b, 0xdc, 0x27, 0x4a, 0xc4, 0xc5, 0x14, 0xec, 0x9a, 0x4b, 0x65,
- 0xe3, 0x4f, 0x9f, 0xa7, 0xe5, 0x41, 0x6f, 0x6d, 0x47, 0x46, 0x3e, 0xce,
- 0x3f, 0xc0, 0x7a, 0xfe, 0x4c, 0xf7, 0xd8, 0x08, 0xdb, 0xa3, 0xe4, 0x62,
- 0x7e, 0x3b, 0xf7, 0xe7, 0x84, 0x39, 0xb6, 0xf7, 0xd5, 0x6e, 0xd2, 0xab,
- 0x98, 0xf1, 0x16, 0xb1, 0xe4, 0x03, 0xf8, 0x4b, 0x5b, 0x41, 0x27, 0x5b,
- 0x75, 0x1c, 0x74, 0xbc, 0x74, 0x7c, 0x10, 0xc7, 0xc8, 0x3a, 0x62, 0x6b,
- 0xef, 0x5b, 0x47, 0x7d, 0xa4, 0xb5, 0x6f, 0x51, 0xe3, 0x0f, 0xfb, 0x77,
- 0x47, 0x15, 0xff, 0xeb, 0xe2, 0x2a, 0xe1, 0x50, 0x88, 0x1f, 0x98, 0x66,
- 0xfa, 0x15, 0x07, 0xc0, 0xcc, 0x57, 0x8e, 0x5f, 0x01, 0x4f, 0xb7, 0xe9,
- 0x7a, 0xae, 0xe3, 0x65, 0xcd, 0xd7, 0x78, 0x0e, 0x6e, 0x33, 0x75, 0x59,
- 0xdb, 0xa9, 0xf8, 0xa3, 0x8c, 0x47, 0x9f, 0xe8, 0xdc, 0x86, 0x7b, 0x6e,
- 0xc8, 0x8b, 0xba, 0x1f, 0xf2, 0x5a, 0xe3, 0x25, 0x71, 0x51, 0xe8, 0x55,
- 0xc3, 0xea, 0xe2, 0x42, 0xb2, 0xe7, 0xd4, 0xa5, 0x6f, 0x69, 0xf9, 0xfd,
- 0xe9, 0x00, 0xe6, 0xcb, 0x76, 0x86, 0xc9, 0x1f, 0x53, 0xc0, 0xf3, 0xbb,
- 0x93, 0xa0, 0xef, 0x88, 0x17, 0xb0, 0xbf, 0xf8, 0x04, 0xdd, 0x03, 0x7d,
- 0x65, 0x8c, 0xcf, 0x72, 0xd4, 0x89, 0xe4, 0x34, 0xdd, 0x4b, 0x96, 0x97,
- 0x45, 0x50, 0x51, 0x8f, 0xd9, 0x6f, 0x80, 0x4f, 0xb7, 0x25, 0xce, 0x0f,
- 0xc2, 0x2b, 0xdd, 0x2b, 0x25, 0x1e, 0xb1, 0x9d, 0x71, 0xeb, 0xcb, 0xc6,
- 0xad, 0xf6, 0x47, 0xb9, 0x33, 0x2f, 0x4e, 0x37, 0xd8, 0x71, 0xea, 0x61,
- 0x9c, 0xde, 0x33, 0xfb, 0x7b, 0xae, 0x5c, 0xf4, 0xf9, 0x8b, 0xff, 0x1b,
- 0x6e, 0x41, 0xb7, 0xd7, 0xab, 0xf3, 0xcb, 0x72, 0xea, 0x71, 0x8d, 0x2d,
- 0xce, 0x4d, 0xf7, 0xb5, 0x5e, 0x27, 0x3c, 0xd6, 0xf5, 0x66, 0xb3, 0x9f,
- 0x1d, 0xe1, 0x77, 0x5e, 0xda, 0xa0, 0x1f, 0xb1, 0x3b, 0x49, 0x1a, 0x1a,
- 0x15, 0x67, 0x15, 0x5f, 0x63, 0xec, 0x08, 0xd7, 0xdb, 0x4b, 0x2e, 0xd4,
- 0x9b, 0xfe, 0x03, 0x18, 0x5f, 0xe6, 0xfa, 0x71, 0x77, 0x0d, 0xd5, 0xe5,
- 0xd8, 0x91, 0xf3, 0x5a, 0x1e, 0xc9, 0x31, 0xd2, 0x5c, 0xd7, 0x9f, 0x77,
- 0x71, 0xbd, 0x25, 0xbf, 0xb9, 0x63, 0x7f, 0xd0, 0x7d, 0xc6, 0x2d, 0x3a,
- 0x9f, 0x54, 0xb4, 0x42, 0xd6, 0x6f, 0x3e, 0xff, 0x19, 0xd0, 0x1e, 0x2f,
- 0xa8, 0x68, 0xb2, 0xc7, 0x43, 0x98, 0x76, 0x61, 0xe4, 0xa9, 0x63, 0x39,
- 0xbd, 0x18, 0x7b, 0xf9, 0x5e, 0x36, 0xcd, 0x7e, 0x0a, 0x91, 0x3f, 0x8a,
- 0xa4, 0x9d, 0x8a, 0x86, 0x63, 0xa3, 0xb3, 0xd0, 0x7f, 0x68, 0x2b, 0xec,
- 0x5b, 0x62, 0xbb, 0x99, 0x86, 0xde, 0x1e, 0x23, 0xfc, 0x85, 0xc6, 0xf1,
- 0x0e, 0x09, 0x79, 0xc6, 0x60, 0xc7, 0x50, 0x1a, 0xe3, 0xa5, 0xcd, 0xa0,
- 0x7f, 0x6d, 0xc1, 0xbe, 0xa3, 0xc7, 0xd9, 0x1f, 0x5b, 0xf3, 0xef, 0xeb,
- 0xbf, 0x07, 0xbe, 0xe1, 0x46, 0x75, 0xfe, 0xe0, 0x0c, 0xbf, 0x5f, 0xc4,
- 0x80, 0x4b, 0x8d, 0x07, 0x8c, 0x34, 0x8f, 0x0f, 0x71, 0x7d, 0xbf, 0xcd,
- 0xef, 0x8d, 0xa1, 0xac, 0xf7, 0xc6, 0x02, 0xee, 0x99, 0x33, 0xe9, 0x24,
- 0x70, 0x91, 0x28, 0xcc, 0x7e, 0xaf, 0xaa, 0x71, 0x75, 0xac, 0x8c, 0xe3,
- 0x54, 0xba, 0x1e, 0x74, 0x72, 0x3d, 0xde, 0x09, 0x43, 0xc7, 0xd8, 0x2f,
- 0xed, 0x14, 0xa7, 0x96, 0xc5, 0xd9, 0x95, 0xde, 0xc9, 0xe0, 0x9b, 0xe2,
- 0x73, 0x23, 0xdc, 0x4f, 0x22, 0xc8, 0x3f, 0x51, 0x9e, 0xe4, 0x77, 0xcb,
- 0x04, 0xee, 0x9d, 0x53, 0x06, 0x68, 0x24, 0xa8, 0xf5, 0x45, 0x3e, 0x26,
- 0x52, 0xc8, 0x3b, 0xac, 0x3b, 0x2c, 0xeb, 0x7c, 0x1f, 0xc9, 0x79, 0xe7,
- 0x28, 0xba, 0xe4, 0x28, 0x71, 0x68, 0x3b, 0xb1, 0xda, 0x17, 0x54, 0xf8,
- 0xbd, 0x69, 0xe6, 0xd5, 0x02, 0xf9, 0xad, 0x6a, 0x26, 0x4d, 0xfa, 0x57,
- 0x8a, 0x12, 0xea, 0xc3, 0x15, 0xa1, 0x45, 0xf8, 0x31, 0x36, 0xcd, 0xfe,
- 0x1f, 0xd9, 0x04, 0x7a, 0x8c, 0xf1, 0xa7, 0x71, 0x75, 0x65, 0xa3, 0x41,
- 0xfb, 0xe6, 0x47, 0x71, 0x8e, 0xbe, 0x47, 0x64, 0xbf, 0xc7, 0x35, 0x1e,
- 0x2b, 0xda, 0x50, 0x48, 0xfb, 0x8f, 0xaa, 0x73, 0x82, 0x12, 0x47, 0x4a,
- 0x7f, 0xe9, 0x13, 0xce, 0x47, 0x3b, 0x4e, 0x15, 0x8e, 0x75, 0x7e, 0x58,
- 0xf1, 0x9d, 0x9d, 0xef, 0x19, 0xbc, 0x86, 0xe8, 0x5e, 0x2e, 0x8b, 0x5c,
- 0x82, 0xdf, 0x4d, 0x7c, 0x3f, 0x58, 0x29, 0x7e, 0x6f, 0x23, 0x7e, 0x31,
- 0xd6, 0xdb, 0x18, 0x18, 0x43, 0x5f, 0x1c, 0x67, 0x1c, 0x2d, 0x34, 0xf2,
- 0xfd, 0x87, 0xf5, 0xfb, 0x8d, 0xdf, 0x67, 0xc0, 0x9b, 0xd7, 0x88, 0xcf,
- 0x32, 0xbe, 0x18, 0xf7, 0x87, 0xd8, 0xee, 0xdb, 0xb0, 0xdb, 0xd0, 0x76,
- 0x0f, 0x98, 0x76, 0xeb, 0xfb, 0x95, 0x55, 0x4e, 0xb1, 0xc4, 0xad, 0xa2,
- 0xab, 0x8c, 0x2b, 0x54, 0xcf, 0x0a, 0xd8, 0x4e, 0xc9, 0xd7, 0xa6, 0xec,
- 0x09, 0xb1, 0x3d, 0x41, 0x71, 0xb0, 0xc5, 0xba, 0x2f, 0xc0, 0xfb, 0xfc,
- 0x72, 0x1f, 0xe6, 0x51, 0x17, 0x8c, 0x15, 0xfc, 0xa9, 0xfc, 0xa6, 0xe5,
- 0x66, 0xe7, 0xbd, 0xd5, 0x7f, 0x74, 0x23, 0xa5, 0x0f, 0xea, 0x9b, 0x8c,
- 0x53, 0x33, 0xfe, 0x3f, 0xd0, 0xf5, 0xed, 0x2e, 0xdd, 0x5f, 0xfd, 0x67,
- 0x86, 0x51, 0x9f, 0xce, 0x0c, 0x9f, 0xe5, 0x77, 0x07, 0xfb, 0xa5, 0x9b,
- 0xfe, 0xb7, 0x90, 0xb1, 0xab, 0xb3, 0xd7, 0x37, 0xbb, 0x1e, 0x55, 0x16,
- 0x3d, 0xf4, 0xb9, 0xff, 0x00, 0x0e, 0x4b, 0x7c, 0x26, 0x30, 0x14, 0x00,
+ 0x13, 0x8b, 0xdc, 0x27, 0x4a, 0xc5, 0xc5, 0x14, 0xec, 0x9a, 0x4d, 0xe5,
+ 0xe2, 0x4f, 0x9f, 0xa7, 0xe5, 0x41, 0x6f, 0x6d, 0x47, 0x56, 0x3e, 0xce,
+ 0x3f, 0xc0, 0x7a, 0xfe, 0x4c, 0xf7, 0xd8, 0x30, 0xdb, 0xa3, 0xe4, 0x62,
+ 0x7e, 0x3b, 0xf7, 0xe7, 0x84, 0x39, 0xb6, 0xf7, 0xd5, 0x1e, 0xd2, 0xab,
+ 0x84, 0xf1, 0x16, 0xb6, 0xe4, 0x03, 0xf8, 0xcb, 0xda, 0x40, 0x27, 0xdb,
+ 0x74, 0x1c, 0x74, 0xbc, 0x74, 0x7c, 0x10, 0xc7, 0xf0, 0x3a, 0x62, 0xeb,
+ 0xe8, 0x5f, 0x47, 0x7d, 0xa4, 0xad, 0x7f, 0x41, 0xe3, 0x0f, 0xfb, 0x77,
+ 0x47, 0x14, 0xff, 0xeb, 0xe2, 0x2a, 0xe1, 0x50, 0x88, 0x1f, 0x98, 0x66,
+ 0xfb, 0x15, 0x07, 0xc0, 0xcc, 0x57, 0x8e, 0x5f, 0x01, 0x4f, 0xb7, 0xeb,
+ 0x7a, 0xae, 0xe3, 0x65, 0xcd, 0xd7, 0xd8, 0x32, 0xdc, 0x66, 0xeb, 0xb2,
+ 0xb6, 0x53, 0xf1, 0x47, 0x18, 0x8f, 0x3e, 0xd1, 0xb5, 0x0d, 0xf7, 0xdc,
+ 0xa0, 0x17, 0x75, 0x3f, 0xe8, 0xb5, 0xc6, 0x4b, 0xe2, 0xa2, 0xd0, 0xab,
+ 0x86, 0x35, 0x25, 0x85, 0x64, 0xcf, 0xa9, 0x4b, 0xdf, 0xd2, 0xf2, 0xfb,
+ 0xd3, 0x45, 0x98, 0x2f, 0xdf, 0x19, 0x22, 0x7f, 0x4c, 0x01, 0xcf, 0xef,
+ 0x4e, 0x82, 0xbe, 0x23, 0x5e, 0xc0, 0xfe, 0x92, 0x13, 0x74, 0x0f, 0xf4,
+ 0x95, 0x33, 0x3e, 0x2b, 0x50, 0x27, 0x92, 0xd3, 0x74, 0x2f, 0x59, 0x5a,
+ 0x12, 0x01, 0x45, 0x3d, 0x66, 0xbf, 0x01, 0x3e, 0xdd, 0x96, 0x38, 0x3f,
+ 0x08, 0xaf, 0x74, 0xaf, 0x94, 0x78, 0xc4, 0x76, 0xc6, 0xad, 0x2f, 0x17,
+ 0xb7, 0xda, 0x1f, 0x15, 0xce, 0xbc, 0x38, 0xdd, 0x60, 0xc7, 0xa9, 0x87,
+ 0x71, 0x7a, 0xcf, 0xec, 0xef, 0xcb, 0xe5, 0xa2, 0xcf, 0x5f, 0xfc, 0xdf,
+ 0x70, 0x0b, 0xba, 0xbd, 0x41, 0x9d, 0x5f, 0xbe, 0xac, 0x1e, 0xd7, 0xda,
+ 0xe2, 0xdc, 0x7c, 0x5f, 0xeb, 0x75, 0xc2, 0x63, 0x5d, 0x6f, 0x31, 0xfb,
+ 0xd9, 0x11, 0x7e, 0xe7, 0x65, 0x0c, 0xfa, 0x11, 0xbd, 0x93, 0xa4, 0xa1,
+ 0x51, 0x79, 0x56, 0xf1, 0x35, 0x45, 0x8f, 0x70, 0xbd, 0xbd, 0xe4, 0x42,
+ 0xbd, 0x19, 0x38, 0x80, 0xf1, 0x65, 0xae, 0x1f, 0x77, 0xd7, 0x50, 0x5d,
+ 0x8e, 0x1e, 0x39, 0xaf, 0xe5, 0x91, 0x1c, 0x23, 0xc3, 0x75, 0xfd, 0x79,
+ 0x17, 0xd7, 0x5b, 0xf2, 0x9b, 0x3b, 0xfa, 0x07, 0xdd, 0x67, 0xdc, 0xa2,
+ 0xeb, 0x49, 0x45, 0x2b, 0x65, 0xfd, 0xe6, 0xf3, 0x9f, 0x01, 0xed, 0xf5,
+ 0x82, 0x8a, 0x66, 0x7b, 0x3c, 0x84, 0x69, 0x17, 0x46, 0x9e, 0x7a, 0x96,
+ 0xd3, 0x87, 0xb1, 0x97, 0xef, 0x65, 0xd3, 0xec, 0xa7, 0x20, 0xf9, 0xa3,
+ 0x58, 0xda, 0xa9, 0x68, 0x28, 0x3a, 0x9a, 0x86, 0xfe, 0x43, 0x5b, 0x61,
+ 0xdf, 0x22, 0xdb, 0xcd, 0x34, 0xf8, 0xf6, 0x18, 0xe1, 0x2f, 0x38, 0x8e,
+ 0x77, 0x48, 0xd0, 0x33, 0x06, 0x3b, 0x86, 0x32, 0x18, 0x2f, 0x6e, 0x06,
+ 0xfd, 0x6b, 0x0b, 0xf6, 0x1d, 0x3d, 0xce, 0xfe, 0xd8, 0x9a, 0x7f, 0xdf,
+ 0xc0, 0x3d, 0xf0, 0x0d, 0x37, 0xa9, 0xf3, 0x07, 0x67, 0xf8, 0xfd, 0x22,
+ 0xe2, 0x2e, 0x35, 0x8e, 0x1b, 0x19, 0x1e, 0x1f, 0xe2, 0xfa, 0x7e, 0x9b,
+ 0xdf, 0x1b, 0x43, 0x39, 0xef, 0x8d, 0x79, 0xdc, 0x33, 0x67, 0x32, 0x49,
+ 0xe0, 0x22, 0x51, 0x98, 0xfb, 0x5e, 0x55, 0xe3, 0x9a, 0x68, 0x39, 0xc7,
+ 0xa9, 0x6c, 0x3d, 0xe8, 0xe4, 0x7a, 0xbc, 0x13, 0x86, 0x8e, 0xb1, 0x5f,
+ 0x3a, 0x28, 0x4e, 0xad, 0x0b, 0xe9, 0x95, 0xde, 0xc9, 0xe0, 0x9b, 0xe2,
+ 0x73, 0xc3, 0xdc, 0x4f, 0xc2, 0xc8, 0x3f, 0x51, 0x91, 0xe4, 0x77, 0xcb,
+ 0x04, 0xee, 0x9d, 0x53, 0x06, 0x68, 0x38, 0xa0, 0xf5, 0x45, 0x3e, 0x26,
+ 0x52, 0xc8, 0x3b, 0xac, 0x3b, 0x2c, 0xeb, 0x7c, 0x1f, 0x59, 0xf6, 0xce,
+ 0x51, 0x74, 0xd1, 0x51, 0xea, 0xd0, 0x76, 0x62, 0xb5, 0x3f, 0xa0, 0xf0,
+ 0x7b, 0xd3, 0xcc, 0xab, 0x79, 0xf2, 0x5b, 0xf5, 0x4c, 0x86, 0xf4, 0xaf,
+ 0x12, 0xa5, 0xd4, 0x87, 0x2b, 0x83, 0x0b, 0xf0, 0x63, 0x74, 0x9a, 0xfd,
+ 0x3f, 0xb2, 0x09, 0xf4, 0x18, 0xe3, 0x4f, 0xe3, 0xea, 0xca, 0x46, 0x83,
+ 0xf6, 0xcd, 0x8d, 0xe2, 0x1c, 0x7d, 0x8f, 0xc8, 0x7d, 0x8f, 0x6b, 0x3c,
+ 0x56, 0xb6, 0xa3, 0x90, 0x0e, 0x1c, 0x55, 0xe7, 0x04, 0x24, 0x8e, 0x94,
+ 0xfe, 0xd2, 0x27, 0x9c, 0x8f, 0x76, 0x9c, 0x2a, 0x1c, 0xeb, 0xfc, 0xb0,
+ 0xe2, 0x3b, 0x37, 0xdf, 0xb3, 0x78, 0x0d, 0xd2, 0xbd, 0x5c, 0x16, 0xb9,
+ 0x04, 0xbf, 0x9b, 0xf8, 0x7e, 0xb0, 0x52, 0xfc, 0xde, 0x46, 0xfc, 0xa2,
+ 0xac, 0xb7, 0x11, 0x1f, 0x43, 0x5f, 0x1c, 0x67, 0x1c, 0xcd, 0x37, 0xf1,
+ 0xfd, 0x87, 0xf5, 0xfb, 0x8d, 0xdf, 0x67, 0xc0, 0x9b, 0xd7, 0x88, 0xa5,
+ 0x19, 0x5f, 0x8c, 0xfb, 0x43, 0x6c, 0xf7, 0x6d, 0xd8, 0x6d, 0x68, 0xbb,
+ 0xe3, 0xa6, 0xdd, 0xfa, 0x7e, 0x65, 0x95, 0x53, 0x22, 0x71, 0xab, 0xe8,
+ 0x2a, 0xe3, 0x0a, 0xd5, 0xb3, 0x02, 0xb6, 0x53, 0xf2, 0xb5, 0x2b, 0x7b,
+ 0x82, 0x6c, 0x4f, 0x40, 0x1c, 0x6c, 0xb5, 0xee, 0x2b, 0xe2, 0x7d, 0x7e,
+ 0xb9, 0x0f, 0xf3, 0xa8, 0x0b, 0xc6, 0x0a, 0xfe, 0x54, 0x7e, 0xd3, 0x72,
+ 0x73, 0xf3, 0xde, 0xea, 0x3f, 0xba, 0x91, 0xd2, 0x07, 0xf5, 0x4d, 0xc6,
+ 0xa9, 0x05, 0xff, 0x1f, 0xe8, 0xfa, 0x76, 0x97, 0xee, 0xaf, 0xfe, 0x33,
+ 0xc3, 0xa8, 0x4f, 0x67, 0x86, 0xcf, 0xf2, 0xbb, 0x83, 0xfd, 0xd2, 0x43,
+ 0xff, 0x5b, 0xc8, 0xd8, 0xd5, 0xdb, 0xeb, 0x9b, 0x5d, 0x8f, 0x6a, 0x8b,
+ 0x1e, 0xfa, 0xdc, 0x7f, 0x00, 0x5a, 0x33, 0xe6, 0xc0, 0x30, 0x14, 0x00,
0x00, 0x00 };
static u8 bnx2_TPAT_b09FwText[] = {
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 6ef6b8b39e7..f651a816b28 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -508,7 +508,7 @@ static int __init macvlan_init_module(void)
goto err1;
return 0;
err1:
- macvlan_handle_frame_hook = macvlan_handle_frame;
+ macvlan_handle_frame_hook = NULL;
unregister_netdevice_notifier(&macvlan_notifier_block);
return err;
}
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index 569028b2baf..6f245cfb662 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -33,8 +33,7 @@
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/crc32.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
#define DRIVER_VERSION "14-Jun-2006"
static const char driver_name [] = "asix";
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index a42acc3cc60..a934428a589 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -31,8 +31,7 @@
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/usb/cdc.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
#if defined(CONFIG_USB_NET_RNDIS_HOST) || defined(CONFIG_USB_NET_RNDIS_HOST_MODULE)
@@ -228,15 +227,16 @@ next_desc:
buf += buf [0];
}
- /* Microsoft ActiveSync based RNDIS devices lack the CDC descriptors,
- * so we'll hard-wire the interfaces and not check for descriptors.
+ /* Microsoft ActiveSync based and some regular RNDIS devices lack the
+ * CDC descriptors, so we'll hard-wire the interfaces and not check
+ * for descriptors.
*/
- if (is_activesync(&intf->cur_altsetting->desc) && !info->u) {
+ if (rndis && !info->u) {
info->control = usb_ifnum_to_if(dev->udev, 0);
info->data = usb_ifnum_to_if(dev->udev, 1);
if (!info->control || !info->data) {
dev_dbg(&intf->dev,
- "activesync: master #0/%p slave #1/%p\n",
+ "rndis: master #0/%p slave #1/%p\n",
info->control,
info->data);
goto bad_desc;
@@ -316,7 +316,6 @@ void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf)
}
EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
-
/*-------------------------------------------------------------------------
*
* Communications Device Class, Ethernet Control model
diff --git a/drivers/net/usb/cdc_subset.c b/drivers/net/usb/cdc_subset.c
index 943988ed01d..0ec7936cbe2 100644
--- a/drivers/net/usb/cdc_subset.c
+++ b/drivers/net/usb/cdc_subset.c
@@ -26,8 +26,7 @@
#include <linux/workqueue.h>
#include <linux/mii.h>
#include <linux/usb.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
/*
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 633a511d6cb..4b131a6c6b7 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -20,8 +20,7 @@
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/crc32.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
/* datasheet:
http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-P01-930914.pdf
diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c
index 031cf5ca4db..f7ccfad9384 100644
--- a/drivers/net/usb/gl620a.c
+++ b/drivers/net/usb/gl620a.c
@@ -29,8 +29,7 @@
#include <linux/workqueue.h>
#include <linux/mii.h>
#include <linux/usb.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
/*
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index 5ea7411e133..c3d119f997f 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -31,8 +31,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/usb.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
/* requests */
#define MCS7830_RD_BMREQ (USB_DIR_IN | USB_TYPE_VENDOR | \
diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c
index 19bf8dae70c..034e8a73ca6 100644
--- a/drivers/net/usb/net1080.c
+++ b/drivers/net/usb/net1080.c
@@ -28,11 +28,10 @@
#include <linux/workqueue.h>
#include <linux/mii.h>
#include <linux/usb.h>
+#include <linux/usb/usbnet.h>
#include <asm/unaligned.h>
-#include "usbnet.h"
-
/*
* Netchip 1080 driver ... http://www.netchip.com
diff --git a/drivers/net/usb/plusb.c b/drivers/net/usb/plusb.c
index 45300939d18..08555f8b15f 100644
--- a/drivers/net/usb/plusb.c
+++ b/drivers/net/usb/plusb.c
@@ -28,8 +28,7 @@
#include <linux/workqueue.h>
#include <linux/mii.h>
#include <linux/usb.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
/*
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index 1ebe3259be0..a61324757b1 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -29,8 +29,8 @@
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/usb/cdc.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
+#include <linux/usb/rndis_host.h>
/*
@@ -56,217 +56,17 @@
*/
/*
- * CONTROL uses CDC "encapsulated commands" with funky notifications.
- * - control-out: SEND_ENCAPSULATED
- * - interrupt-in: RESPONSE_AVAILABLE
- * - control-in: GET_ENCAPSULATED
- *
- * We'll try to ignore the RESPONSE_AVAILABLE notifications.
- *
- * REVISIT some RNDIS implementations seem to have curious issues still
- * to be resolved.
- */
-struct rndis_msg_hdr {
- __le32 msg_type; /* RNDIS_MSG_* */
- __le32 msg_len;
- // followed by data that varies between messages
- __le32 request_id;
- __le32 status;
- // ... and more
-} __attribute__ ((packed));
-
-/* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */
-#define CONTROL_BUFFER_SIZE 1025
-
-/* RNDIS defines an (absurdly huge) 10 second control timeout,
- * but ActiveSync seems to use a more usual 5 second timeout
- * (which matches the USB 2.0 spec).
- */
-#define RNDIS_CONTROL_TIMEOUT_MS (5 * 1000)
-
-
-#define ccpu2 __constant_cpu_to_le32
-
-#define RNDIS_MSG_COMPLETION ccpu2(0x80000000)
-
-/* codes for "msg_type" field of rndis messages;
- * only the data channel uses packet messages (maybe batched);
- * everything else goes on the control channel.
- */
-#define RNDIS_MSG_PACKET ccpu2(0x00000001) /* 1-N packets */
-#define RNDIS_MSG_INIT ccpu2(0x00000002)
-#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION)
-#define RNDIS_MSG_HALT ccpu2(0x00000003)
-#define RNDIS_MSG_QUERY ccpu2(0x00000004)
-#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION)
-#define RNDIS_MSG_SET ccpu2(0x00000005)
-#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION)
-#define RNDIS_MSG_RESET ccpu2(0x00000006)
-#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION)
-#define RNDIS_MSG_INDICATE ccpu2(0x00000007)
-#define RNDIS_MSG_KEEPALIVE ccpu2(0x00000008)
-#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION)
-
-/* codes for "status" field of completion messages */
-#define RNDIS_STATUS_SUCCESS ccpu2(0x00000000)
-#define RNDIS_STATUS_FAILURE ccpu2(0xc0000001)
-#define RNDIS_STATUS_INVALID_DATA ccpu2(0xc0010015)
-#define RNDIS_STATUS_NOT_SUPPORTED ccpu2(0xc00000bb)
-#define RNDIS_STATUS_MEDIA_CONNECT ccpu2(0x4001000b)
-#define RNDIS_STATUS_MEDIA_DISCONNECT ccpu2(0x4001000c)
-
-
-struct rndis_data_hdr {
- __le32 msg_type; /* RNDIS_MSG_PACKET */
- __le32 msg_len; // rndis_data_hdr + data_len + pad
- __le32 data_offset; // 36 -- right after header
- __le32 data_len; // ... real packet size
-
- __le32 oob_data_offset; // zero
- __le32 oob_data_len; // zero
- __le32 num_oob; // zero
- __le32 packet_data_offset; // zero
-
- __le32 packet_data_len; // zero
- __le32 vc_handle; // zero
- __le32 reserved; // zero
-} __attribute__ ((packed));
-
-struct rndis_init { /* OUT */
- // header and:
- __le32 msg_type; /* RNDIS_MSG_INIT */
- __le32 msg_len; // 24
- __le32 request_id;
- __le32 major_version; // of rndis (1.0)
- __le32 minor_version;
- __le32 max_transfer_size;
-} __attribute__ ((packed));
-
-struct rndis_init_c { /* IN */
- // header and:
- __le32 msg_type; /* RNDIS_MSG_INIT_C */
- __le32 msg_len;
- __le32 request_id;
- __le32 status;
- __le32 major_version; // of rndis (1.0)
- __le32 minor_version;
- __le32 device_flags;
- __le32 medium; // zero == 802.3
- __le32 max_packets_per_message;
- __le32 max_transfer_size;
- __le32 packet_alignment; // max 7; (1<<n) bytes
- __le32 af_list_offset; // zero
- __le32 af_list_size; // zero
-} __attribute__ ((packed));
-
-struct rndis_halt { /* OUT (no reply) */
- // header and:
- __le32 msg_type; /* RNDIS_MSG_HALT */
- __le32 msg_len;
- __le32 request_id;
-} __attribute__ ((packed));
-
-struct rndis_query { /* OUT */
- // header and:
- __le32 msg_type; /* RNDIS_MSG_QUERY */
- __le32 msg_len;
- __le32 request_id;
- __le32 oid;
- __le32 len;
- __le32 offset;
-/*?*/ __le32 handle; // zero
-} __attribute__ ((packed));
-
-struct rndis_query_c { /* IN */
- // header and:
- __le32 msg_type; /* RNDIS_MSG_QUERY_C */
- __le32 msg_len;
- __le32 request_id;
- __le32 status;
- __le32 len;
- __le32 offset;
-} __attribute__ ((packed));
-
-struct rndis_set { /* OUT */
- // header and:
- __le32 msg_type; /* RNDIS_MSG_SET */
- __le32 msg_len;
- __le32 request_id;
- __le32 oid;
- __le32 len;
- __le32 offset;
-/*?*/ __le32 handle; // zero
-} __attribute__ ((packed));
-
-struct rndis_set_c { /* IN */
- // header and:
- __le32 msg_type; /* RNDIS_MSG_SET_C */
- __le32 msg_len;
- __le32 request_id;
- __le32 status;
-} __attribute__ ((packed));
-
-struct rndis_reset { /* IN */
- // header and:
- __le32 msg_type; /* RNDIS_MSG_RESET */
- __le32 msg_len;
- __le32 reserved;
-} __attribute__ ((packed));
-
-struct rndis_reset_c { /* OUT */
- // header and:
- __le32 msg_type; /* RNDIS_MSG_RESET_C */
- __le32 msg_len;
- __le32 status;
- __le32 addressing_lost;
-} __attribute__ ((packed));
-
-struct rndis_indicate { /* IN (unrequested) */
- // header and:
- __le32 msg_type; /* RNDIS_MSG_INDICATE */
- __le32 msg_len;
- __le32 status;
- __le32 length;
- __le32 offset;
-/**/ __le32 diag_status;
- __le32 error_offset;
-/**/ __le32 message;
-} __attribute__ ((packed));
-
-struct rndis_keepalive { /* OUT (optionally IN) */
- // header and:
- __le32 msg_type; /* RNDIS_MSG_KEEPALIVE */
- __le32 msg_len;
- __le32 request_id;
-} __attribute__ ((packed));
-
-struct rndis_keepalive_c { /* IN (optionally OUT) */
- // header and:
- __le32 msg_type; /* RNDIS_MSG_KEEPALIVE_C */
- __le32 msg_len;
- __le32 request_id;
- __le32 status;
-} __attribute__ ((packed));
-
-/* NOTE: about 30 OIDs are "mandatory" for peripherals to support ... and
- * there are gobs more that may optionally be supported. We'll avoid as much
- * of that mess as possible.
- */
-#define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101)
-#define OID_GEN_MAXIMUM_FRAME_SIZE ccpu2(0x00010106)
-#define OID_GEN_CURRENT_PACKET_FILTER ccpu2(0x0001010e)
-
-/*
* RNDIS notifications from device: command completion; "reverse"
* keepalives; etc
*/
-static void rndis_status(struct usbnet *dev, struct urb *urb)
+void rndis_status(struct usbnet *dev, struct urb *urb)
{
devdbg(dev, "rndis status urb, len %d stat %d",
urb->actual_length, urb->status);
// FIXME for keepalives, respond immediately (asynchronously)
// if not an RNDIS status, do like cdc_status(dev,urb) does
}
+EXPORT_SYMBOL_GPL(rndis_status);
/*
* RPC done RNDIS-style. Caller guarantees:
@@ -278,7 +78,7 @@ static void rndis_status(struct usbnet *dev, struct urb *urb)
* Call context is likely probe(), before interface name is known,
* which is why we won't try to use it in the diagnostics.
*/
-static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
+int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
{
struct cdc_state *info = (void *) &dev->data;
int master_ifnum;
@@ -347,10 +147,26 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
request_id, xid);
/* then likely retry */
} else switch (buf->msg_type) {
- case RNDIS_MSG_INDICATE: { /* fault */
- // struct rndis_indicate *msg = (void *)buf;
- dev_info(&info->control->dev,
- "rndis fault indication\n");
+ case RNDIS_MSG_INDICATE: { /* fault/event */
+ struct rndis_indicate *msg = (void *)buf;
+ int state = 0;
+
+ switch (msg->status) {
+ case RNDIS_STATUS_MEDIA_CONNECT:
+ state = 1;
+ case RNDIS_STATUS_MEDIA_DISCONNECT:
+ dev_info(&info->control->dev,
+ "rndis media %sconnect\n",
+ !state?"dis":"");
+ if (dev->driver_info->link_change)
+ dev->driver_info->link_change(
+ dev, state);
+ break;
+ default:
+ dev_info(&info->control->dev,
+ "rndis indication: 0x%08x\n",
+ le32_to_cpu(msg->status));
+ }
}
break;
case RNDIS_MSG_KEEPALIVE: { /* ping */
@@ -387,6 +203,7 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
dev_dbg(&info->control->dev, "rndis response timeout\n");
return -ETIMEDOUT;
}
+EXPORT_SYMBOL_GPL(rndis_command);
/*
* rndis_query:
@@ -453,7 +270,8 @@ response_error:
return -EDOM;
}
-static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
+int
+generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
{
int retval;
struct net_device *net = dev->net;
@@ -467,8 +285,9 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
struct rndis_query_c *get_c;
struct rndis_set *set;
struct rndis_set_c *set_c;
+ struct rndis_halt *halt;
} u;
- u32 tmp;
+ u32 tmp, *phym;
int reply_len;
unsigned char *bp;
@@ -517,7 +336,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
"dev can't take %u byte packets (max %u)\n",
dev->hard_mtu, tmp);
retval = -EINVAL;
- goto fail_and_release;
+ goto halt_fail_and_release;
}
dev->hard_mtu = tmp;
net->mtu = dev->hard_mtu - net->hard_header_len;
@@ -533,13 +352,43 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
dev->hard_mtu, tmp, dev->rx_urb_size,
1 << le32_to_cpu(u.init_c->packet_alignment));
+ /* module has some device initialization code needs to be done right
+ * after RNDIS_INIT */
+ if (dev->driver_info->early_init &&
+ dev->driver_info->early_init(dev) != 0)
+ goto halt_fail_and_release;
+
+ /* Check physical medium */
+ reply_len = sizeof *phym;
+ retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM,
+ 0, (void **) &phym, &reply_len);
+ if (retval != 0)
+ /* OID is optional so don't fail here. */
+ *phym = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED;
+ if ((flags & FLAG_RNDIS_PHYM_WIRELESS) &&
+ *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
+ if (netif_msg_probe(dev))
+ dev_dbg(&intf->dev, "driver requires wireless "
+ "physical medium, but device is not.\n");
+ retval = -ENODEV;
+ goto halt_fail_and_release;
+ }
+ if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) &&
+ *phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
+ if (netif_msg_probe(dev))
+ dev_dbg(&intf->dev, "driver requires non-wireless "
+ "physical medium, but device is wireless.\n");
+ retval = -ENODEV;
+ goto halt_fail_and_release;
+ }
+
/* Get designated host ethernet address */
reply_len = ETH_ALEN;
retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS,
48, (void **) &bp, &reply_len);
if (unlikely(retval< 0)) {
dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval);
- goto fail_and_release;
+ goto halt_fail_and_release;
}
memcpy(net->dev_addr, bp, ETH_ALEN);
@@ -550,12 +399,12 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
u.set->oid = OID_GEN_CURRENT_PACKET_FILTER;
u.set->len = ccpu2(4);
u.set->offset = ccpu2((sizeof *u.set) - 8);
- *(__le32 *)(u.buf + sizeof *u.set) = ccpu2(DEFAULT_FILTER);
+ *(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER;
retval = rndis_command(dev, u.header);
if (unlikely(retval < 0)) {
dev_err(&intf->dev, "rndis set packet filter, %d\n", retval);
- goto fail_and_release;
+ goto halt_fail_and_release;
}
retval = 0;
@@ -563,6 +412,11 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
kfree(u.buf);
return retval;
+halt_fail_and_release:
+ memset(u.halt, 0, sizeof *u.halt);
+ u.halt->msg_type = RNDIS_MSG_HALT;
+ u.halt->msg_len = ccpu2(sizeof *u.halt);
+ (void) rndis_command(dev, (void *)u.halt);
fail_and_release:
usb_set_intfdata(info->data, NULL);
usb_driver_release_interface(driver_of(intf), info->data);
@@ -571,13 +425,19 @@ fail:
kfree(u.buf);
return retval;
}
+EXPORT_SYMBOL_GPL(generic_rndis_bind);
+
+static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ return generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_NOT_WIRELESS);
+}
-static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
+void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
{
struct rndis_halt *halt;
/* try to clear any rndis state/activity (no i/o from stack!) */
- halt = kzalloc(sizeof *halt, GFP_KERNEL);
+ halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
if (halt) {
halt->msg_type = RNDIS_MSG_HALT;
halt->msg_len = ccpu2(sizeof *halt);
@@ -585,13 +445,14 @@ static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
kfree(halt);
}
- return usbnet_cdc_unbind(dev, intf);
+ usbnet_cdc_unbind(dev, intf);
}
+EXPORT_SYMBOL_GPL(rndis_unbind);
/*
* DATA -- host must not write zlps
*/
-static int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
/* peripheral may have batched packets to us... */
while (likely(skb->len)) {
@@ -633,8 +494,9 @@ static int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
/* caller will usbnet_skb_return the remaining packet */
return 1;
}
+EXPORT_SYMBOL_GPL(rndis_rx_fixup);
-static struct sk_buff *
+struct sk_buff *
rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
struct rndis_data_hdr *hdr;
@@ -679,6 +541,7 @@ fill:
/* FIXME make the last packet always be short ... */
return skb;
}
+EXPORT_SYMBOL_GPL(rndis_tx_fixup);
static const struct driver_info rndis_info = {
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 8ed1fc5cbc7..8463efb9e0b 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -41,8 +41,7 @@
#include <linux/workqueue.h>
#include <linux/mii.h>
#include <linux/usb.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
#define DRIVER_VERSION "22-Aug-2005"
@@ -1204,6 +1203,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
if ((dev->driver_info->flags & FLAG_ETHER) != 0
&& (net->dev_addr [0] & 0x02) == 0)
strcpy (net->name, "eth%d");
+ /* WLAN devices should always be named "wlan%d" */
+ if ((dev->driver_info->flags & FLAG_WLAN) != 0)
+ strcpy(net->name, "wlan%d");
/* maybe the remote can't receive an Ethernet MTU */
if (net->mtu > (dev->hard_mtu - net->hard_header_len))
diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c
index 9f98e8ce487..e24f7b3ace4 100644
--- a/drivers/net/usb/zaurus.c
+++ b/drivers/net/usb/zaurus.c
@@ -29,8 +29,7 @@
#include <linux/crc32.h>
#include <linux/usb.h>
#include <linux/usb/cdc.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
/*
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index f372960904b..714a6ca30ad 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -545,6 +545,34 @@ config USB_ZD1201
To compile this driver as a module, choose M here: the
module will be called zd1201.
+config USB_NET_RNDIS_WLAN
+ tristate "Wireless RNDIS USB support"
+ depends on USB && WLAN_80211 && EXPERIMENTAL
+ select USB_USBNET
+ select USB_NET_CDCETHER
+ select USB_NET_RNDIS_HOST
+ select WIRELESS_EXT
+ ---help---
+ This is a driver for wireless RNDIS devices.
+ These are USB based adapters found in devices such as:
+
+ Buffalo WLI-U2-KG125S
+ U.S. Robotics USR5421
+ Belkin F5D7051
+ Linksys WUSB54GSv2
+ Linksys WUSB54GSC
+ Asus WL169gE
+ Eminent EM4045
+ BT Voyager 1055
+ Linksys WUSB54GSv1
+ U.S. Robotics USR5420
+ BUFFALO WLI-USB-G54
+
+ All of these devices are based on Broadcom 4320 chip which is the
+ only wireless RNDIS chip known to date.
+
+ If you choose to build a module, it'll be called rndis_wlan.
+
config RTL8180
tristate "Realtek 8180/8185 PCI support"
depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 6af7b158624..091dfe2e574 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -44,6 +44,8 @@ obj-$(CONFIG_ZD1211RW) += zd1211rw/
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
+obj-$(CONFIG_USB_NET_RNDIS_WLAN) += rndis_wlan.o
+
obj-$(CONFIG_USB_ZD1201) += zd1201.o
obj-$(CONFIG_LIBERTAS) += libertas/
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 72bcf321d1c..d6599d21919 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -1980,7 +1980,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
struct ath5k_buf *bf = sc->bbuf;
struct ath5k_hw *ah = sc->ah;
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "in beacon_send\n");
+ ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
if (unlikely(bf->skb == NULL || sc->opmode == IEEE80211_IF_TYPE_STA ||
sc->opmode == IEEE80211_IF_TYPE_MNTR)) {
@@ -1996,10 +1996,10 @@ ath5k_beacon_send(struct ath5k_softc *sc)
*/
if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) {
sc->bmisscount++;
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
+ ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
"missed %u consecutive beacons\n", sc->bmisscount);
if (sc->bmisscount > 3) { /* NB: 3 is a guess */
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
+ ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
"stuck beacon time (%u missed)\n",
sc->bmisscount);
tasklet_schedule(&sc->restq);
@@ -2007,7 +2007,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
return;
}
if (unlikely(sc->bmisscount != 0)) {
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
+ ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
"resume beacon xmit after %u misses\n",
sc->bmisscount);
sc->bmisscount = 0;
@@ -2027,7 +2027,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr);
ath5k_hw_tx_start(ah, sc->bhalq);
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "TXDP[%u] = %llx (%p)\n",
+ ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
sc->bsent++;
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c
index 4ba649e2026..bb581ef6d1e 100644
--- a/drivers/net/wireless/ath5k/debug.c
+++ b/drivers/net/wireless/ath5k/debug.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 Bruno Randolf <bruno@thinktube.com>
+ * Copyright (c) 2007-2008 Bruno Randolf <bruno@thinktube.com>
*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -200,7 +200,7 @@ static ssize_t read_file_tsf(struct file *file, char __user *user_buf,
{
struct ath5k_softc *sc = file->private_data;
char buf[100];
- snprintf(buf, 100, "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah));
+ snprintf(buf, sizeof(buf), "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah));
return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
}
@@ -209,7 +209,12 @@ static ssize_t write_file_tsf(struct file *file,
size_t count, loff_t *ppos)
{
struct ath5k_softc *sc = file->private_data;
- if (strncmp(userbuf, "reset", 5) == 0) {
+ char buf[20];
+
+ if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ return -EFAULT;
+
+ if (strncmp(buf, "reset", 5) == 0) {
ath5k_hw_reset_tsf(sc->ah);
printk(KERN_INFO "debugfs reset TSF\n");
}
@@ -231,8 +236,8 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
{
struct ath5k_softc *sc = file->private_data;
struct ath5k_hw *ah = sc->ah;
- char buf[1000];
- int len = 0;
+ char buf[500];
+ unsigned int len = 0;
unsigned int v;
u64 tsf;
@@ -277,11 +282,15 @@ static ssize_t write_file_beacon(struct file *file,
{
struct ath5k_softc *sc = file->private_data;
struct ath5k_hw *ah = sc->ah;
+ char buf[20];
+
+ if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ return -EFAULT;
- if (strncmp(userbuf, "disable", 7) == 0) {
+ if (strncmp(buf, "disable", 7) == 0) {
AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
printk(KERN_INFO "debugfs disable beacons\n");
- } else if (strncmp(userbuf, "enable", 6) == 0) {
+ } else if (strncmp(buf, "enable", 6) == 0) {
AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
printk(KERN_INFO "debugfs enable beacons\n");
}
@@ -314,6 +323,82 @@ static const struct file_operations fops_reset = {
};
+/* debugfs: debug level */
+
+static struct {
+ enum ath5k_debug_level level;
+ const char *name;
+ const char *desc;
+} dbg_info[] = {
+ { ATH5K_DEBUG_RESET, "reset", "reset and initialization" },
+ { ATH5K_DEBUG_INTR, "intr", "interrupt handling" },
+ { ATH5K_DEBUG_MODE, "mode", "mode init/setup" },
+ { ATH5K_DEBUG_XMIT, "xmit", "basic xmit operation" },
+ { ATH5K_DEBUG_BEACON, "beacon", "beacon handling" },
+ { ATH5K_DEBUG_CALIBRATE, "calib", "periodic calibration" },
+ { ATH5K_DEBUG_TXPOWER, "txpower", "transmit power setting" },
+ { ATH5K_DEBUG_LED, "led", "LED mamagement" },
+ { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" },
+ { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
+ { ATH5K_DEBUG_DUMPMODES, "dumpmodes", "dump modes" },
+ { ATH5K_DEBUG_TRACE, "trace", "trace function calls" },
+ { ATH5K_DEBUG_ANY, "all", "show all debug levels" },
+};
+
+static ssize_t read_file_debug(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath5k_softc *sc = file->private_data;
+ char buf[700];
+ unsigned int len = 0;
+ unsigned int i;
+
+ len += snprintf(buf+len, sizeof(buf)-len,
+ "DEBUG LEVEL: 0x%08x\n\n", sc->debug.level);
+
+ for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) {
+ len += snprintf(buf+len, sizeof(buf)-len,
+ "%10s %c 0x%08x - %s\n", dbg_info[i].name,
+ sc->debug.level & dbg_info[i].level ? '+' : ' ',
+ dbg_info[i].level, dbg_info[i].desc);
+ }
+ len += snprintf(buf+len, sizeof(buf)-len,
+ "%10s %c 0x%08x - %s\n", dbg_info[i].name,
+ sc->debug.level == dbg_info[i].level ? '+' : ' ',
+ dbg_info[i].level, dbg_info[i].desc);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_debug(struct file *file,
+ const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct ath5k_softc *sc = file->private_data;
+ unsigned int i;
+ char buf[20];
+
+ if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ return -EFAULT;
+
+ for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
+ if (strncmp(buf, dbg_info[i].name,
+ strlen(dbg_info[i].name)) == 0) {
+ sc->debug.level ^= dbg_info[i].level; /* toggle bit */
+ break;
+ }
+ }
+ return count;
+}
+
+static const struct file_operations fops_debug = {
+ .read = read_file_debug,
+ .write = write_file_debug,
+ .open = ath5k_debugfs_open,
+ .owner = THIS_MODULE,
+};
+
+
/* init */
void
@@ -326,26 +411,24 @@ void
ath5k_debug_init_device(struct ath5k_softc *sc)
{
sc->debug.level = ath5k_debug;
+
sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
- ath5k_global_debugfs);
- sc->debug.debugfs_debug = debugfs_create_u32("debug",
- 0666, sc->debug.debugfs_phydir, &sc->debug.level);
+ ath5k_global_debugfs);
+
+ sc->debug.debugfs_debug = debugfs_create_file("debug", 0666,
+ sc->debug.debugfs_phydir, sc, &fops_debug);
sc->debug.debugfs_registers = debugfs_create_file("registers", 0444,
- sc->debug.debugfs_phydir,
- sc, &fops_registers);
+ sc->debug.debugfs_phydir, sc, &fops_registers);
sc->debug.debugfs_tsf = debugfs_create_file("tsf", 0666,
- sc->debug.debugfs_phydir,
- sc, &fops_tsf);
+ sc->debug.debugfs_phydir, sc, &fops_tsf);
sc->debug.debugfs_beacon = debugfs_create_file("beacon", 0666,
- sc->debug.debugfs_phydir,
- sc, &fops_beacon);
+ sc->debug.debugfs_phydir, sc, &fops_beacon);
sc->debug.debugfs_reset = debugfs_create_file("reset", 0222,
- sc->debug.debugfs_phydir,
- sc, &fops_reset);
+ sc->debug.debugfs_phydir, sc, &fops_reset);
}
void
@@ -415,8 +498,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
struct ath5k_buf *bf;
int status;
- if (likely(!(sc->debug.level &
- (ATH5K_DEBUG_RESET | ATH5K_DEBUG_FATAL))))
+ if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
return;
printk(KERN_DEBUG "rx queue %x, link %p\n",
@@ -426,7 +508,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
list_for_each_entry(bf, &sc->rxbuf, list) {
ds = bf->desc;
status = ah->ah_proc_rx_desc(ah, ds);
- if (!status || (sc->debug.level & ATH5K_DEBUG_FATAL))
+ if (!status)
ath5k_debug_printrxbuf(bf, status == 0);
}
spin_unlock_bh(&sc->rxbuflock);
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h
index 2b491cbc8c8..c4fd8c43df0 100644
--- a/drivers/net/wireless/ath5k/debug.h
+++ b/drivers/net/wireless/ath5k/debug.h
@@ -91,7 +91,6 @@ struct ath5k_dbg_info {
* @ATH5K_DEBUG_MODE: mode init/setup
* @ATH5K_DEBUG_XMIT: basic xmit operation
* @ATH5K_DEBUG_BEACON: beacon handling
- * @ATH5K_DEBUG_BEACON_PROC: beacon ISR proc
* @ATH5K_DEBUG_CALIBRATE: periodic calibration
* @ATH5K_DEBUG_TXPOWER: transmit power setting
* @ATH5K_DEBUG_LED: led management
@@ -99,7 +98,6 @@ struct ath5k_dbg_info {
* @ATH5K_DEBUG_DUMP_TX: print transmit skb content
* @ATH5K_DEBUG_DUMPMODES: dump modes
* @ATH5K_DEBUG_TRACE: trace function calls
- * @ATH5K_DEBUG_FATAL: fatal errors
* @ATH5K_DEBUG_ANY: show at any debug level
*
* The debug level is used to control the amount and type of debugging output
@@ -115,15 +113,13 @@ enum ath5k_debug_level {
ATH5K_DEBUG_MODE = 0x00000004,
ATH5K_DEBUG_XMIT = 0x00000008,
ATH5K_DEBUG_BEACON = 0x00000010,
- ATH5K_DEBUG_BEACON_PROC = 0x00000020,
- ATH5K_DEBUG_CALIBRATE = 0x00000100,
- ATH5K_DEBUG_TXPOWER = 0x00000200,
- ATH5K_DEBUG_LED = 0x00000400,
- ATH5K_DEBUG_DUMP_RX = 0x00001000,
- ATH5K_DEBUG_DUMP_TX = 0x00002000,
- ATH5K_DEBUG_DUMPMODES = 0x00004000,
- ATH5K_DEBUG_TRACE = 0x00010000,
- ATH5K_DEBUG_FATAL = 0x80000000,
+ ATH5K_DEBUG_CALIBRATE = 0x00000020,
+ ATH5K_DEBUG_TXPOWER = 0x00000040,
+ ATH5K_DEBUG_LED = 0x00000080,
+ ATH5K_DEBUG_DUMP_RX = 0x00000100,
+ ATH5K_DEBUG_DUMP_TX = 0x00000200,
+ ATH5K_DEBUG_DUMPMODES = 0x00000400,
+ ATH5K_DEBUG_TRACE = 0x00001000,
ATH5K_DEBUG_ANY = 0xffffffff
};
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 3e73d2a523a..8a708b77925 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1114,7 +1114,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
{
const struct b43_dma_ops *ops = ring->ops;
u8 *header;
- int slot;
+ int slot, old_top_slot, old_used_slots;
int err;
struct b43_dmadesc_generic *desc;
struct b43_dmadesc_meta *meta;
@@ -1126,6 +1126,9 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
#define SLOTS_PER_PACKET 2
B43_WARN_ON(skb_shinfo(skb)->nr_frags);
+ old_top_slot = ring->current_slot;
+ old_used_slots = ring->used_slots;
+
/* Get a slot for the header. */
slot = request_slot(ring);
desc = ops->idx2desc(ring, slot, &meta_hdr);
@@ -1133,13 +1136,21 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
header = &(ring->txhdr_cache[slot * hdrsize]);
cookie = generate_cookie(ring, slot);
- b43_generate_txhdr(ring->dev, header,
- skb->data, skb->len, ctl, cookie);
+ err = b43_generate_txhdr(ring->dev, header,
+ skb->data, skb->len, ctl, cookie);
+ if (unlikely(err)) {
+ ring->current_slot = old_top_slot;
+ ring->used_slots = old_used_slots;
+ return err;
+ }
meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
hdrsize, 1);
- if (dma_mapping_error(meta_hdr->dmaaddr))
+ if (dma_mapping_error(meta_hdr->dmaaddr)) {
+ ring->current_slot = old_top_slot;
+ ring->used_slots = old_used_slots;
return -EIO;
+ }
ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr,
hdrsize, 1, 0, 0);
@@ -1157,6 +1168,8 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
if (dma_mapping_error(meta->dmaaddr)) {
bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
if (!bounce_skb) {
+ ring->current_slot = old_top_slot;
+ ring->used_slots = old_used_slots;
err = -ENOMEM;
goto out_unmap_hdr;
}
@@ -1167,6 +1180,8 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
meta->skb = skb;
meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
if (dma_mapping_error(meta->dmaaddr)) {
+ ring->current_slot = old_top_slot;
+ ring->used_slots = old_used_slots;
err = -EIO;
goto out_free_bounce;
}
@@ -1252,6 +1267,13 @@ int b43_dma_tx(struct b43_wldev *dev,
B43_WARN_ON(ring->stopped);
err = dma_tx_fragment(ring, skb, ctl);
+ if (unlikely(err == -ENOKEY)) {
+ /* Drop this packet, as we don't have the encryption key
+ * anymore and must not transmit it unencrypted. */
+ dev_kfree_skb_any(skb);
+ err = 0;
+ goto out_unlock;
+ }
if (unlikely(err)) {
b43err(dev->wl, "DMA tx mapping failure\n");
goto out_unlock;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 88d2c15d3fb..64c154d080d 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3532,8 +3532,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
b43_bluetooth_coext_enable(dev);
ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
- memset(wl->bssid, 0, ETH_ALEN);
- memset(wl->mac_addr, 0, ETH_ALEN);
b43_upload_card_macaddress(dev);
b43_security_init(dev);
b43_rng_init(wl);
@@ -3630,6 +3628,15 @@ static int b43_op_start(struct ieee80211_hw *hw)
struct b43_wldev *dev = wl->current_dev;
int did_init = 0;
int err = 0;
+ bool do_rfkill_exit = 0;
+
+ /* Kill all old instance specific information to make sure
+ * the card won't use it in the short timeframe between start
+ * and mac80211 reconfiguring it. */
+ memset(wl->bssid, 0, ETH_ALEN);
+ memset(wl->mac_addr, 0, ETH_ALEN);
+ wl->filter_flags = 0;
+ wl->radiotap_enabled = 0;
/* First register RFkill.
* LEDs that are registered later depend on it. */
@@ -3639,8 +3646,10 @@ static int b43_op_start(struct ieee80211_hw *hw)
if (b43_status(dev) < B43_STAT_INITIALIZED) {
err = b43_wireless_core_init(dev);
- if (err)
+ if (err) {
+ do_rfkill_exit = 1;
goto out_mutex_unlock;
+ }
did_init = 1;
}
@@ -3649,6 +3658,7 @@ static int b43_op_start(struct ieee80211_hw *hw)
if (err) {
if (did_init)
b43_wireless_core_exit(dev);
+ do_rfkill_exit = 1;
goto out_mutex_unlock;
}
}
@@ -3656,6 +3666,9 @@ static int b43_op_start(struct ieee80211_hw *hw)
out_mutex_unlock:
mutex_unlock(&wl->mutex);
+ if (do_rfkill_exit)
+ b43_rfkill_exit(dev);
+
return err;
}
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 3fc53e8b441..7caa26eb410 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -178,12 +178,12 @@ static u8 b43_calc_fallback_rate(u8 bitrate)
}
/* Generate a TX data header. */
-void b43_generate_txhdr(struct b43_wldev *dev,
- u8 *_txhdr,
- const unsigned char *fragment_data,
- unsigned int fragment_len,
- const struct ieee80211_tx_control *txctl,
- u16 cookie)
+int b43_generate_txhdr(struct b43_wldev *dev,
+ u8 *_txhdr,
+ const unsigned char *fragment_data,
+ unsigned int fragment_len,
+ const struct ieee80211_tx_control *txctl,
+ u16 cookie)
{
struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
const struct b43_phy *phy = &dev->phy;
@@ -237,7 +237,15 @@ void b43_generate_txhdr(struct b43_wldev *dev,
B43_WARN_ON(key_idx >= dev->max_nr_keys);
key = &(dev->key[key_idx]);
- B43_WARN_ON(!key->keyconf);
+
+ if (unlikely(!key->keyconf)) {
+ /* This key is invalid. This might only happen
+ * in a short timeframe after machine resume before
+ * we were able to reconfigure keys.
+ * Drop this packet completely. Do not transmit it
+ * unencrypted to avoid leaking information. */
+ return -ENOKEY;
+ }
/* Hardware appends ICV. */
plcp_fragment_len += txctl->icv_len;
@@ -408,6 +416,7 @@ void b43_generate_txhdr(struct b43_wldev *dev,
txhdr->phy_ctl = cpu_to_le16(phy_ctl);
txhdr->extra_ft = extra_ft;
+ return 0;
}
static s8 b43_rssi_postprocess(struct b43_wldev *dev,
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index ca2a2ab8654..41765039552 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -174,11 +174,11 @@ size_t b43_txhdr_size(struct b43_wldev *dev)
}
-void b43_generate_txhdr(struct b43_wldev *dev,
- u8 * txhdr,
- const unsigned char *fragment_data,
- unsigned int fragment_len,
- const struct ieee80211_tx_control *txctl, u16 cookie);
+int b43_generate_txhdr(struct b43_wldev *dev,
+ u8 * txhdr,
+ const unsigned char *fragment_data,
+ unsigned int fragment_len,
+ const struct ieee80211_tx_control *txctl, u16 cookie);
/* Transmit Status */
struct b43_txstatus {
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index 93419adb925..c80edd2b904 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -23,7 +23,7 @@
#include "phy.h"
-#define B43legacy_IRQWAIT_MAX_RETRIES 100
+#define B43legacy_IRQWAIT_MAX_RETRIES 20
#define B43legacy_RX_MAX_SSI 60 /* best guess at max ssi */
@@ -40,9 +40,8 @@
#define B43legacy_MMIO_DMA4_IRQ_MASK 0x44
#define B43legacy_MMIO_DMA5_REASON 0x48
#define B43legacy_MMIO_DMA5_IRQ_MASK 0x4C
-#define B43legacy_MMIO_MACCTL 0x120
-#define B43legacy_MMIO_STATUS_BITFIELD 0x120
-#define B43legacy_MMIO_STATUS2_BITFIELD 0x124
+#define B43legacy_MMIO_MACCTL 0x120 /* MAC control */
+#define B43legacy_MMIO_MACCMD 0x124 /* MAC command */
#define B43legacy_MMIO_GEN_IRQ_REASON 0x128
#define B43legacy_MMIO_GEN_IRQ_MASK 0x12C
#define B43legacy_MMIO_RAM_CONTROL 0x130
@@ -177,31 +176,25 @@
#define B43legacy_RADIOCTL_ID 0x01
/* MAC Control bitfield */
+#define B43legacy_MACCTL_ENABLED 0x00000001 /* MAC Enabled */
+#define B43legacy_MACCTL_PSM_RUN 0x00000002 /* Run Microcode */
+#define B43legacy_MACCTL_PSM_JMP0 0x00000004 /* Microcode jump to 0 */
+#define B43legacy_MACCTL_SHM_ENABLED 0x00000100 /* SHM Enabled */
#define B43legacy_MACCTL_IHR_ENABLED 0x00000400 /* IHR Region Enabled */
+#define B43legacy_MACCTL_BE 0x00010000 /* Big Endian mode */
#define B43legacy_MACCTL_INFRA 0x00020000 /* Infrastructure mode */
#define B43legacy_MACCTL_AP 0x00040000 /* AccessPoint mode */
+#define B43legacy_MACCTL_RADIOLOCK 0x00080000 /* Radio lock */
#define B43legacy_MACCTL_BEACPROMISC 0x00100000 /* Beacon Promiscuous */
#define B43legacy_MACCTL_KEEP_BADPLCP 0x00200000 /* Keep bad PLCP frames */
#define B43legacy_MACCTL_KEEP_CTL 0x00400000 /* Keep control frames */
#define B43legacy_MACCTL_KEEP_BAD 0x00800000 /* Keep bad frames (FCS) */
#define B43legacy_MACCTL_PROMISC 0x01000000 /* Promiscuous mode */
+#define B43legacy_MACCTL_HWPS 0x02000000 /* Hardware Power Saving */
+#define B43legacy_MACCTL_AWAKE 0x04000000 /* Device is awake */
+#define B43legacy_MACCTL_TBTTHOLD 0x10000000 /* TBTT Hold */
#define B43legacy_MACCTL_GMODE 0x80000000 /* G Mode */
-/* StatusBitField */
-#define B43legacy_SBF_MAC_ENABLED 0x00000001
-#define B43legacy_SBF_CORE_READY 0x00000004
-#define B43legacy_SBF_400 0x00000400 /*FIXME: fix name*/
-#define B43legacy_SBF_XFER_REG_BYTESWAP 0x00010000
-#define B43legacy_SBF_MODE_NOTADHOC 0x00020000
-#define B43legacy_SBF_MODE_AP 0x00040000
-#define B43legacy_SBF_RADIOREG_LOCK 0x00080000
-#define B43legacy_SBF_MODE_MONITOR 0x00400000
-#define B43legacy_SBF_MODE_PROMISC 0x01000000
-#define B43legacy_SBF_PS1 0x02000000
-#define B43legacy_SBF_PS2 0x04000000
-#define B43legacy_SBF_NO_SSID_BCAST 0x08000000
-#define B43legacy_SBF_TIME_UPDATE 0x10000000
-
/* 802.11 core specific TM State Low flags */
#define B43legacy_TMSLOW_GMODE 0x20000000 /* G Mode Enable */
#define B43legacy_TMSLOW_PLLREFSEL 0x00200000 /* PLL Freq Ref Select */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 4ed4243feea..aa20d5d56e2 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -225,8 +225,8 @@ static void b43legacy_ram_write(struct b43legacy_wldev *dev, u16 offset,
B43legacy_WARN_ON(offset % 4 != 0);
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- if (status & B43legacy_SBF_XFER_REG_BYTESWAP)
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ if (status & B43legacy_MACCTL_BE)
val = swab32(val);
b43legacy_write32(dev, B43legacy_MMIO_RAM_CONTROL, offset);
@@ -434,9 +434,9 @@ static void b43legacy_time_lock(struct b43legacy_wldev *dev)
{
u32 status;
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- status |= B43legacy_SBF_TIME_UPDATE;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ status |= B43legacy_MACCTL_TBTTHOLD;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
mmiowb();
}
@@ -444,9 +444,9 @@ static void b43legacy_time_unlock(struct b43legacy_wldev *dev)
{
u32 status;
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- status &= ~B43legacy_SBF_TIME_UPDATE;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ status &= ~B43legacy_MACCTL_TBTTHOLD;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
}
static void b43legacy_tsf_write_locked(struct b43legacy_wldev *dev, u64 tsf)
@@ -647,7 +647,7 @@ void b43legacy_dummy_transmission(struct b43legacy_wldev *dev)
b43legacy_ram_write(dev, i * 4, buffer[i]);
/* dummy read follows */
- b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
+ b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
b43legacy_write16(dev, 0x0568, 0x0000);
b43legacy_write16(dev, 0x07C0, 0x0000);
@@ -794,9 +794,9 @@ static void b43legacy_jssi_write(struct b43legacy_wldev *dev, u32 jssi)
static void b43legacy_generate_noise_sample(struct b43legacy_wldev *dev)
{
b43legacy_jssi_write(dev, 0x7F7F7F7F);
- b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD,
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
b43legacy_read32(dev,
- B43legacy_MMIO_STATUS2_BITFIELD)
+ B43legacy_MMIO_MACCMD)
| (1 << 4));
B43legacy_WARN_ON(dev->noisecalc.channel_at_start !=
dev->phy.channel);
@@ -895,8 +895,8 @@ static void handle_irq_atim_end(struct b43legacy_wldev *dev)
{
if (!dev->reg124_set_0x4) /*FIXME rename this variable*/
return;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD,
- b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD)
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
+ b43legacy_read32(dev, B43legacy_MMIO_MACCMD)
| 0x4);
}
@@ -1106,9 +1106,9 @@ static void b43legacy_update_templates(struct b43legacy_wldev *dev)
b43legacy_write_probe_resp_template(dev, 0x268, 0x4A,
B43legacy_CCK_RATE_11MB);
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
status |= 0x03;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD, status);
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD, status);
}
static void b43legacy_refresh_templates(struct b43legacy_wldev *dev,
@@ -1166,7 +1166,7 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev)
return;
dev->irq_savedstate &= ~B43legacy_IRQ_BEACON;
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
if (!dev->cached_beacon || ((status & 0x1) && (status & 0x2))) {
/* ACK beacon IRQ. */
@@ -1182,14 +1182,14 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev)
b43legacy_write_beacon_template(dev, 0x68, 0x18,
B43legacy_CCK_RATE_1MB);
status |= 0x1;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD,
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
status);
}
if (!(status & 0x2)) {
b43legacy_write_beacon_template(dev, 0x468, 0x1A,
B43legacy_CCK_RATE_1MB);
status |= 0x2;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD,
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
status);
}
}
@@ -1548,9 +1548,20 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
u16 fwpatch;
u16 fwdate;
u16 fwtime;
- u32 tmp;
+ u32 tmp, macctl;
int err = 0;
+ /* Jump the microcode PSM to offset 0 */
+ macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ B43legacy_WARN_ON(macctl & B43legacy_MACCTL_PSM_RUN);
+ macctl |= B43legacy_MACCTL_PSM_JMP0;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
+ /* Zero out all microcode PSM registers and shared memory. */
+ for (i = 0; i < 64; i++)
+ b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, i, 0);
+ for (i = 0; i < 4096; i += 2)
+ b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, i, 0);
+
/* Upload Microcode. */
data = (__be32 *) (dev->fw.ucode->data + hdr_len);
len = (dev->fw.ucode->size - hdr_len) / sizeof(__be32);
@@ -1581,7 +1592,12 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON,
B43legacy_IRQ_ALL);
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 0x00020402);
+
+ /* Start the microcode PSM */
+ macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ macctl &= ~B43legacy_MACCTL_PSM_JMP0;
+ macctl |= B43legacy_MACCTL_PSM_RUN;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
/* Wait for the microcode to load and respond */
i = 0;
@@ -1594,9 +1610,13 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
b43legacyerr(dev->wl, "Microcode not responding\n");
b43legacy_print_fw_helptext(dev->wl);
err = -ENODEV;
- goto out;
+ goto error;
+ }
+ msleep_interruptible(50);
+ if (signal_pending(current)) {
+ err = -EINTR;
+ goto error;
}
- udelay(10);
}
/* dummy read follows */
b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
@@ -1617,9 +1637,8 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
" is supported. You must change your firmware"
" files.\n");
b43legacy_print_fw_helptext(dev->wl);
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 0);
err = -EOPNOTSUPP;
- goto out;
+ goto error;
}
b43legacydbg(dev->wl, "Loading firmware version 0x%X, patch level %u "
"(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch,
@@ -1629,7 +1648,14 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
dev->fw.rev = fwrev;
dev->fw.patch = fwpatch;
-out:
+ return 0;
+
+error:
+ macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ macctl &= ~B43legacy_MACCTL_PSM_RUN;
+ macctl |= B43legacy_MACCTL_PSM_JMP0;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
+
return err;
}
@@ -1736,9 +1762,9 @@ static int b43legacy_gpio_init(struct b43legacy_wldev *dev)
u32 mask;
u32 set;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
b43legacy_read32(dev,
- B43legacy_MMIO_STATUS_BITFIELD)
+ B43legacy_MMIO_MACCTL)
& 0xFFFF3FFF);
b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK,
@@ -1798,14 +1824,14 @@ void b43legacy_mac_enable(struct b43legacy_wldev *dev)
B43legacy_WARN_ON(dev->mac_suspended < 0);
B43legacy_WARN_ON(irqs_disabled());
if (dev->mac_suspended == 0) {
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
b43legacy_read32(dev,
- B43legacy_MMIO_STATUS_BITFIELD)
- | B43legacy_SBF_MAC_ENABLED);
+ B43legacy_MMIO_MACCTL)
+ | B43legacy_MACCTL_ENABLED);
b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON,
B43legacy_IRQ_MAC_SUSPENDED);
/* the next two are dummy reads */
- b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
+ b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
b43legacy_power_saving_ctl_bits(dev, -1, -1);
@@ -1836,10 +1862,10 @@ void b43legacy_mac_suspend(struct b43legacy_wldev *dev)
dev->irq_savedstate = tmp;
b43legacy_power_saving_ctl_bits(dev, -1, 1);
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
b43legacy_read32(dev,
- B43legacy_MMIO_STATUS_BITFIELD)
- & ~B43legacy_SBF_MAC_ENABLED);
+ B43legacy_MMIO_MACCTL)
+ & ~B43legacy_MACCTL_ENABLED);
b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
for (i = 40; i; i--) {
tmp = b43legacy_read32(dev,
@@ -2007,12 +2033,15 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
struct b43legacy_phy *phy = &dev->phy;
int err;
int tmp;
- u32 value32;
+ u32 value32, macctl;
u16 value16;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,
- B43legacy_SBF_CORE_READY
- | B43legacy_SBF_400);
+ /* Initialize the MAC control */
+ macctl = B43legacy_MACCTL_IHR_ENABLED | B43legacy_MACCTL_SHM_ENABLED;
+ if (dev->phy.gmode)
+ macctl |= B43legacy_MACCTL_GMODE;
+ macctl |= B43legacy_MACCTL_INFRA;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
err = b43legacy_request_firmware(dev);
if (err)
@@ -2052,12 +2081,12 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
if (dev->dev->id.revision < 5)
b43legacy_write32(dev, 0x010C, 0x01000000);
- value32 = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- value32 &= ~B43legacy_SBF_MODE_NOTADHOC;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value32);
- value32 = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- value32 |= B43legacy_SBF_MODE_NOTADHOC;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value32);
+ value32 = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ value32 &= ~B43legacy_MACCTL_INFRA;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value32);
+ value32 = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ value32 |= B43legacy_MACCTL_INFRA;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value32);
if (b43legacy_using_pio(dev)) {
b43legacy_write32(dev, 0x0210, 0x00000100);
@@ -2951,12 +2980,19 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev)
{
struct b43legacy_wl *wl = dev->wl;
struct b43legacy_phy *phy = &dev->phy;
+ u32 macctl;
B43legacy_WARN_ON(b43legacy_status(dev) > B43legacy_STAT_INITIALIZED);
if (b43legacy_status(dev) != B43legacy_STAT_INITIALIZED)
return;
b43legacy_set_status(dev, B43legacy_STAT_UNINIT);
+ /* Stop the microcode PSM. */
+ macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ macctl &= ~B43legacy_MACCTL_PSM_RUN;
+ macctl |= B43legacy_MACCTL_PSM_JMP0;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
+
mutex_unlock(&wl->mutex);
/* Must unlock as it would otherwise deadlock. No races here.
* Cancel possibly pending workqueues. */
@@ -3221,6 +3257,7 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
struct b43legacy_wldev *dev = wl->current_dev;
int did_init = 0;
int err = 0;
+ bool do_rfkill_exit = 0;
/* First register RFkill.
* LEDs that are registered later depend on it. */
@@ -3230,8 +3267,10 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) {
err = b43legacy_wireless_core_init(dev);
- if (err)
+ if (err) {
+ do_rfkill_exit = 1;
goto out_mutex_unlock;
+ }
did_init = 1;
}
@@ -3240,6 +3279,7 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
if (err) {
if (did_init)
b43legacy_wireless_core_exit(dev);
+ do_rfkill_exit = 1;
goto out_mutex_unlock;
}
}
@@ -3247,6 +3287,9 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
out_mutex_unlock:
mutex_unlock(&wl->mutex);
+ if (do_rfkill_exit)
+ b43legacy_rfkill_exit(dev);
+
return err;
}
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c
index c16febbdbf5..8e5c09b8187 100644
--- a/drivers/net/wireless/b43legacy/phy.c
+++ b/drivers/net/wireless/b43legacy/phy.c
@@ -140,7 +140,7 @@ void b43legacy_phy_calibrate(struct b43legacy_wldev *dev)
{
struct b43legacy_phy *phy = &dev->phy;
- b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); /* Dummy read. */
+ b43legacy_read32(dev, B43legacy_MMIO_MACCTL); /* Dummy read. */
if (phy->calibrated)
return;
if (phy->type == B43legacy_PHYTYPE_G && phy->rev == 1) {
@@ -2231,16 +2231,16 @@ bit26 = 1;
* or the latest PS-Poll packet sent was successful,
* set bit26 */
}
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
if (bit25)
- status |= B43legacy_SBF_PS1;
+ status |= B43legacy_MACCTL_HWPS;
else
- status &= ~B43legacy_SBF_PS1;
+ status &= ~B43legacy_MACCTL_HWPS;
if (bit26)
- status |= B43legacy_SBF_PS2;
+ status |= B43legacy_MACCTL_AWAKE;
else
- status &= ~B43legacy_SBF_PS2;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+ status &= ~B43legacy_MACCTL_AWAKE;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
if (bit26 && dev->dev->id.revision >= 5) {
for (i = 0; i < 100; i++) {
if (b43legacy_shm_read32(dev, B43legacy_SHM_SHARED,
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c
index de843ac147a..e4f4c5c39e3 100644
--- a/drivers/net/wireless/b43legacy/pio.c
+++ b/drivers/net/wireless/b43legacy/pio.c
@@ -334,9 +334,9 @@ struct b43legacy_pioqueue *b43legacy_setup_pioqueue(struct b43legacy_wldev *dev,
tasklet_init(&queue->txtask, tx_tasklet,
(unsigned long)queue);
- value = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- value &= ~B43legacy_SBF_XFER_REG_BYTESWAP;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value);
+ value = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ value &= ~B43legacy_MACCTL_BE;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value);
qsize = b43legacy_read16(dev, queue->mmio_base
+ B43legacy_PIO_TXQBUFSIZE);
diff --git a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c
index 318a270cf9b..955832e8654 100644
--- a/drivers/net/wireless/b43legacy/radio.c
+++ b/drivers/net/wireless/b43legacy/radio.c
@@ -91,10 +91,10 @@ void b43legacy_radio_lock(struct b43legacy_wldev *dev)
{
u32 status;
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- B43legacy_WARN_ON(status & B43legacy_SBF_RADIOREG_LOCK);
- status |= B43legacy_SBF_RADIOREG_LOCK;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ B43legacy_WARN_ON(status & B43legacy_MACCTL_RADIOLOCK);
+ status |= B43legacy_MACCTL_RADIOLOCK;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
mmiowb();
udelay(10);
}
@@ -104,10 +104,10 @@ void b43legacy_radio_unlock(struct b43legacy_wldev *dev)
u32 status;
b43legacy_read16(dev, B43legacy_MMIO_PHY_VER); /* dummy read */
- status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
- B43legacy_WARN_ON(!(status & B43legacy_SBF_RADIOREG_LOCK));
- status &= ~B43legacy_SBF_RADIOREG_LOCK;
- b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+ status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+ B43legacy_WARN_ON(!(status & B43legacy_MACCTL_RADIOLOCK));
+ status &= ~B43legacy_MACCTL_RADIOLOCK;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
mmiowb();
}
diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h
index d6b9362a3d5..3694b1eba52 100644
--- a/drivers/net/wireless/hostap/hostap_80211.h
+++ b/drivers/net/wireless/hostap/hostap_80211.h
@@ -71,11 +71,6 @@ struct hostap_80211_rx_status {
u16 rate; /* in 100 kbps */
};
-
-void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
- struct hostap_80211_rx_status *rx_stats);
-
-
/* prism2_rx_80211 'type' argument */
enum {
PRISM2_RX_MONITOR, PRISM2_RX_MGMT, PRISM2_RX_NON_ASSOC,
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 07593803065..437a9bcc9bd 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -891,6 +891,9 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
PCMCIA_DEVICE_PROD_ID123(
"The Linksys Group, Inc.", "Wireless Network CF Card", "ISL37300P",
0xa5f472c2, 0x9c05598d, 0xc9049a39),
+ PCMCIA_DEVICE_PROD_ID123(
+ "Wireless LAN" , "11Mbps PC Card", "Version 01.02",
+ 0x4b8870ff, 0x70e946d1, 0x4b74baa0),
PCMCIA_DEVICE_NULL
};
MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 6e0187393af..571815d7e8b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -373,7 +373,7 @@ struct iwl3945_eeprom {
#define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */
#define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */
#define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */
-#define CSR_INT_BIT_MAC_CLK_ACTV (1 << 26) /* NIC controller's clock toggled on/off */
+#define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */
#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */
#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */
#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 76c4ed1135f..4fdeb532324 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2369,18 +2369,4 @@ struct pci_device_id iwl3945_hw_card_ids[] = {
{0}
};
-/*
- * Clear the OWNER_MSK, to establish driver (instead of uCode running on
- * embedded controller) as EEPROM reader; each read is a series of pulses
- * to/from the EEPROM chip, not a single event, so even reads could conflict
- * if they weren't arbitrated by some ownership mechanism. Here, the driver
- * simply claims ownership, which should be safe when this function is called
- * (i.e. before loading uCode!).
- */
-inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
-{
- _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
- return 0;
-}
-
MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 20b925f57e3..1da14f9bbe0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -671,7 +671,6 @@ extern int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel);
/*
* Forward declare iwl-3945.c functions for iwl-base.c
*/
-extern int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv);
extern __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv);
extern int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv);
extern void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv);
@@ -791,7 +790,6 @@ struct iwl3945_priv {
u16 active_rate_basic;
u8 call_post_assoc_from_beacon;
- u8 assoc_station_added;
/* Rate scaling data */
s8 data_retry_limit;
u8 retry_rate;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index ff71c09ab1a..ffe1e9dfdec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -465,7 +465,7 @@ struct iwl4965_eeprom {
#define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */
#define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */
#define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */
-#define CSR_INT_BIT_MAC_CLK_ACTV (1 << 26) /* NIC controller's clock toggled on/off */
+#define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */
#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */
#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */
#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 04db34ba814..569347ff377 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -4961,11 +4961,4 @@ int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv)
return rc;
}
-inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv)
-{
- iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-}
-
-
MODULE_DEVICE_TABLE(pci, iwl4965_hw_card_ids);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h
index 78bc148c9f7..9cb82be0ff8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.h
@@ -750,7 +750,6 @@ struct iwl4965_priv;
* Forward declare iwl-4965.c functions for iwl-base.c
*/
extern int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv);
-extern void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv);
extern int iwl4965_tx_queue_update_wr_ptr(struct iwl4965_priv *priv,
struct iwl4965_tx_queue *txq,
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index cd2eb184831..cb009f4c401 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -246,10 +246,10 @@ static inline int iwl_check_bits(unsigned long field, unsigned long mask)
static inline unsigned long elapsed_jiffies(unsigned long start,
unsigned long end)
{
- if (end > start)
+ if (end >= start)
return end - start;
- return end + (MAX_JIFFY_OFFSET - start);
+ return end + (MAX_JIFFY_OFFSET - start) + 1;
}
static inline u8 iwl_get_dma_hi_address(dma_addr_t addr)
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 748ac1222ab..33239f19798 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1557,6 +1557,20 @@ static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac)
memcpy(mac, priv->eeprom.mac_address, 6);
}
+/*
+ * Clear the OWNER_MSK, to establish driver (instead of uCode running on
+ * embedded controller) as EEPROM reader; each read is a series of pulses
+ * to/from the EEPROM chip, not a single event, so even reads could conflict
+ * if they weren't arbitrated by some ownership mechanism. Here, the driver
+ * simply claims ownership, which should be safe when this function is called
+ * (i.e. before loading uCode!).
+ */
+static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
+{
+ _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
+ return 0;
+}
+
/**
* iwl3945_eeprom_init - read EEPROM contents
*
@@ -2792,7 +2806,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
#endif
/* drop all data frame if we are not associated */
- if (!iwl3945_is_associated(priv) && !priv->assoc_id &&
+ if ((!iwl3945_is_associated(priv) || !priv->assoc_id) &&
((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
goto drop_unlock;
@@ -4745,8 +4759,9 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
#ifdef CONFIG_IWL3945_DEBUG
if (iwl3945_debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
- if (inta & CSR_INT_BIT_MAC_CLK_ACTV)
- IWL_DEBUG_ISR("Microcode started or stopped.\n");
+ if (inta & CSR_INT_BIT_SCD)
+ IWL_DEBUG_ISR("Scheduler finished to transmit "
+ "the frame/frames.\n");
/* Alive notification via Rx interrupt will do the real work */
if (inta & CSR_INT_BIT_ALIVE)
@@ -4754,7 +4769,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
}
#endif
/* Safely ignore these bits for debug checks below */
- inta &= ~(CSR_INT_BIT_MAC_CLK_ACTV | CSR_INT_BIT_ALIVE);
+ inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
/* HW RF KILL switch toggled (4965 only) */
if (inta & CSR_INT_BIT_RF_KILL) {
@@ -4890,8 +4905,11 @@ static irqreturn_t iwl3945_isr(int irq, void *data)
IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
inta, inta_mask, inta_fh);
+ inta &= ~CSR_INT_BIT_SCD;
+
/* iwl3945_irq_tasklet() will service interrupts and re-enable them */
- tasklet_schedule(&priv->irq_tasklet);
+ if (likely(inta || inta_fh))
+ tasklet_schedule(&priv->irq_tasklet);
unplugged:
spin_unlock(&priv->lock);
@@ -5146,6 +5164,15 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
return 0;
}
+/*
+ * iwl3945_free_channel_map - undo allocations in iwl3945_init_channel_map
+ */
+static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
+{
+ kfree(priv->channel_info);
+ priv->channel_count = 0;
+}
+
/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
* sending probe req. This should be set long enough to hear probe responses
* from more than one AP. */
@@ -5471,6 +5498,17 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
return 0;
}
+/*
+ * iwl3945_free_geos - undo allocations in iwl3945_init_geos
+ */
+static void iwl3945_free_geos(struct iwl3945_priv *priv)
+{
+ kfree(priv->modes);
+ kfree(priv->ieee_channels);
+ kfree(priv->ieee_rates);
+ clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
+}
+
/******************************************************************************
*
* uCode download functions
@@ -6130,15 +6168,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
/* Clear out the uCode error bit if it is set */
clear_bit(STATUS_FW_ERROR, &priv->status);
- rc = iwl3945_init_channel_map(priv);
- if (rc) {
- IWL_ERROR("initializing regulatory failed: %d\n", rc);
- return;
- }
-
- iwl3945_init_geos(priv);
- iwl3945_reset_channel_flag(priv);
-
if (iwl3945_is_rfkill(priv))
return;
@@ -6599,7 +6628,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
* that based on the direct_mask added to each channel entry */
scan->tx_cmd.len = cpu_to_le16(
iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(scan), 0));
+ IWL_MAX_SCAN_SIZE - sizeof(*scan), 0));
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
@@ -7120,7 +7149,7 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
{
int rc = 0;
- if (priv->status & STATUS_EXIT_PENDING)
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
/* The following should be done only at AP bring up */
@@ -8614,11 +8643,24 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
+ err = iwl3945_init_channel_map(priv);
+ if (err) {
+ IWL_ERROR("initializing regulatory failed: %d\n", err);
+ goto out_remove_sysfs;
+ }
+
+ err = iwl3945_init_geos(priv);
+ if (err) {
+ IWL_ERROR("initializing geos failed: %d\n", err);
+ goto out_free_channel_map;
+ }
+ iwl3945_reset_channel_flag(priv);
+
iwl3945_rate_control_register(priv->hw);
err = ieee80211_register_hw(priv->hw);
if (err) {
IWL_ERROR("Failed to register network device (error %d)\n", err);
- goto out_remove_sysfs;
+ goto out_free_geos;
}
priv->hw->conf.beacon_int = 100;
@@ -8628,6 +8670,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
return 0;
+ out_free_geos:
+ iwl3945_free_geos(priv);
+ out_free_channel_map:
+ iwl3945_free_channel_map(priv);
out_remove_sysfs:
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
@@ -8702,10 +8748,8 @@ static void iwl3945_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
- kfree(priv->channel_info);
-
- kfree(priv->ieee_channels);
- kfree(priv->ieee_rates);
+ iwl3945_free_channel_map(priv);
+ iwl3945_free_geos(priv);
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index c86da5cd1df..bf3a60c037a 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1639,6 +1639,12 @@ static void get_eeprom_mac(struct iwl4965_priv *priv, u8 *mac)
memcpy(mac, priv->eeprom.mac_address, 6);
}
+static inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv)
+{
+ iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+}
+
/**
* iwl4965_eeprom_init - read EEPROM contents
*
@@ -2927,8 +2933,10 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv,
#endif
/* drop all data frame if we are not associated */
- if (!iwl4965_is_associated(priv) && !priv->assoc_id &&
- ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
+ if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
+ (!iwl4965_is_associated(priv) ||
+ !priv->assoc_id ||
+ !priv->assoc_station_added)) {
IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n");
goto drop_unlock;
}
@@ -5131,8 +5139,9 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv)
#ifdef CONFIG_IWL4965_DEBUG
if (iwl4965_debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
- if (inta & CSR_INT_BIT_MAC_CLK_ACTV)
- IWL_DEBUG_ISR("Microcode started or stopped.\n");
+ if (inta & CSR_INT_BIT_SCD)
+ IWL_DEBUG_ISR("Scheduler finished to transmit "
+ "the frame/frames.\n");
/* Alive notification via Rx interrupt will do the real work */
if (inta & CSR_INT_BIT_ALIVE)
@@ -5140,7 +5149,7 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv)
}
#endif
/* Safely ignore these bits for debug checks below */
- inta &= ~(CSR_INT_BIT_MAC_CLK_ACTV | CSR_INT_BIT_ALIVE);
+ inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
/* HW RF KILL switch toggled */
if (inta & CSR_INT_BIT_RF_KILL) {
@@ -5269,8 +5278,11 @@ static irqreturn_t iwl4965_isr(int irq, void *data)
IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
inta, inta_mask, inta_fh);
+ inta &= ~CSR_INT_BIT_SCD;
+
/* iwl4965_irq_tasklet() will service interrupts and re-enable them */
- tasklet_schedule(&priv->irq_tasklet);
+ if (likely(inta || inta_fh))
+ tasklet_schedule(&priv->irq_tasklet);
unplugged:
spin_unlock(&priv->lock);
@@ -5576,6 +5588,15 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv)
return 0;
}
+/*
+ * iwl4965_free_channel_map - undo allocations in iwl4965_init_channel_map
+ */
+static void iwl4965_free_channel_map(struct iwl4965_priv *priv)
+{
+ kfree(priv->channel_info);
+ priv->channel_count = 0;
+}
+
/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
* sending probe req. This should be set long enough to hear probe responses
* from more than one AP. */
@@ -5909,6 +5930,17 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv)
return 0;
}
+/*
+ * iwl4965_free_geos - undo allocations in iwl4965_init_geos
+ */
+static void iwl4965_free_geos(struct iwl4965_priv *priv)
+{
+ kfree(priv->modes);
+ kfree(priv->ieee_channels);
+ kfree(priv->ieee_rates);
+ clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
+}
+
/******************************************************************************
*
* uCode download functions
@@ -6560,15 +6592,6 @@ static void iwl4965_alive_start(struct iwl4965_priv *priv)
/* Clear out the uCode error bit if it is set */
clear_bit(STATUS_FW_ERROR, &priv->status);
- rc = iwl4965_init_channel_map(priv);
- if (rc) {
- IWL_ERROR("initializing regulatory failed: %d\n", rc);
- return;
- }
-
- iwl4965_init_geos(priv);
- iwl4965_reset_channel_flag(priv);
-
if (iwl4965_is_rfkill(priv))
return;
@@ -7023,7 +7046,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
* that based on the direct_mask added to each channel entry */
scan->tx_cmd.len = cpu_to_le16(
iwl4965_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(scan), 0));
+ IWL_MAX_SCAN_SIZE - sizeof(*scan), 0));
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
@@ -7448,7 +7471,7 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw,
if (priv->vif) {
IWL_DEBUG_MAC80211("leave - vif != NULL\n");
- return 0;
+ return -EOPNOTSUPP;
}
spin_lock_irqsave(&priv->lock, flags);
@@ -7580,7 +7603,7 @@ static void iwl4965_config_ap(struct iwl4965_priv *priv)
{
int rc = 0;
- if (priv->status & STATUS_EXIT_PENDING)
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
/* The following should be done only at AP bring up */
@@ -9198,11 +9221,24 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
+ err = iwl4965_init_channel_map(priv);
+ if (err) {
+ IWL_ERROR("initializing regulatory failed: %d\n", err);
+ goto out_remove_sysfs;
+ }
+
+ err = iwl4965_init_geos(priv);
+ if (err) {
+ IWL_ERROR("initializing geos failed: %d\n", err);
+ goto out_free_channel_map;
+ }
+ iwl4965_reset_channel_flag(priv);
+
iwl4965_rate_control_register(priv->hw);
err = ieee80211_register_hw(priv->hw);
if (err) {
IWL_ERROR("Failed to register network device (error %d)\n", err);
- goto out_remove_sysfs;
+ goto out_free_geos;
}
priv->hw->conf.beacon_int = 100;
@@ -9212,6 +9248,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
return 0;
+ out_free_geos:
+ iwl4965_free_geos(priv);
+ out_free_channel_map:
+ iwl4965_free_channel_map(priv);
out_remove_sysfs:
sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
@@ -9286,10 +9326,8 @@ static void iwl4965_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
- kfree(priv->channel_info);
-
- kfree(priv->ieee_channels);
- kfree(priv->ieee_rates);
+ iwl4965_free_channel_map(priv);
+ iwl4965_free_geos(priv);
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index c622e9b63cd..87e145ffe8f 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -12,8 +12,10 @@
#include "cmd.h"
-static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) =
+ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static int assoc_helper_essid(struct lbs_private *priv,
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 58d7ef6b5ff..5a69f2b6086 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -349,7 +349,7 @@ struct assoc_request {
u8 channel;
u8 band;
u8 mode;
- u8 bssid[ETH_ALEN];
+ u8 bssid[ETH_ALEN] __attribute__ ((aligned (2)));
/** WEP keys */
struct enc_key wep_keys[4];
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 4b5ab9a6b97..5a9cadb9750 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -249,14 +249,14 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
lbs_deb_enter(LBS_DEB_CS);
int_cause = if_cs_read16(card, IF_CS_C_INT_CAUSE);
- if(int_cause == 0x0) {
+ if (int_cause == 0x0) {
/* Not for us */
return IRQ_NONE;
} else if (int_cause == 0xffff) {
/* Read in junk, the card has probably been removed */
card->priv->surpriseremoved = 1;
-
+ return IRQ_HANDLED;
} else {
if (int_cause & IF_CS_H_IC_TX_OVER)
lbs_host_to_card_done(card->priv);
@@ -717,8 +717,8 @@ static void if_cs_release(struct pcmcia_device *p_dev)
lbs_deb_enter(LBS_DEB_CS);
- pcmcia_disable_device(p_dev);
free_irq(p_dev->irq.AssignedIRQ, card);
+ pcmcia_disable_device(p_dev);
if (card->iobase)
ioport_unmap(card->iobase);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
new file mode 100644
index 00000000000..d3ecf89abd9
--- /dev/null
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -0,0 +1,2757 @@
+/*
+ * Driver for RNDIS based wireless USB devices.
+ *
+ * Copyright (C) 2007 by Bjorge Dijkstra <bjd@jooz.net>
+ * Copyright (C) 2008 by Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Portions of this file are based on NDISwrapper project,
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
+ * http://ndiswrapper.sourceforge.net/
+ */
+
+// #define DEBUG // error path messages, extra info
+// #define VERBOSE // more; success messages
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <linux/wireless.h>
+#include <linux/if_arp.h>
+#include <linux/ctype.h>
+#include <linux/spinlock.h>
+#include <net/iw_handler.h>
+#include <net/ieee80211.h>
+#include <linux/usb/usbnet.h>
+#include <linux/usb/rndis_host.h>
+
+
+/* NOTE: All these are settings for Broadcom chipset */
+static char modparam_country[4] = "EU";
+module_param_string(country, modparam_country, 4, 0444);
+MODULE_PARM_DESC(country, "Country code (ISO 3166-1 alpha-2), default: EU");
+
+static int modparam_frameburst = 1;
+module_param_named(frameburst, modparam_frameburst, int, 0444);
+MODULE_PARM_DESC(frameburst, "enable frame bursting (default: on)");
+
+static int modparam_afterburner = 0;
+module_param_named(afterburner, modparam_afterburner, int, 0444);
+MODULE_PARM_DESC(afterburner,
+ "enable afterburner aka '125 High Speed Mode' (default: off)");
+
+static int modparam_power_save = 0;
+module_param_named(power_save, modparam_power_save, int, 0444);
+MODULE_PARM_DESC(power_save,
+ "set power save mode: 0=off, 1=on, 2=fast (default: off)");
+
+static int modparam_power_output = 3;
+module_param_named(power_output, modparam_power_output, int, 0444);
+MODULE_PARM_DESC(power_output,
+ "set power output: 0=25%, 1=50%, 2=75%, 3=100% (default: 100%)");
+
+static int modparam_roamtrigger = -70;
+module_param_named(roamtrigger, modparam_roamtrigger, int, 0444);
+MODULE_PARM_DESC(roamtrigger,
+ "set roaming dBm trigger: -80=optimize for distance, "
+ "-60=bandwidth (default: -70)");
+
+static int modparam_roamdelta = 1;
+module_param_named(roamdelta, modparam_roamdelta, int, 0444);
+MODULE_PARM_DESC(roamdelta,
+ "set roaming tendency: 0=aggressive, 1=moderate, "
+ "2=conservative (default: moderate)");
+
+static int modparam_workaround_interval = 500;
+module_param_named(workaround_interval, modparam_workaround_interval,
+ int, 0444);
+MODULE_PARM_DESC(workaround_interval,
+ "set stall workaround interval in msecs (default: 500)");
+
+
+/* various RNDIS OID defs */
+#define OID_GEN_LINK_SPEED ccpu2(0x00010107)
+#define OID_GEN_RNDIS_CONFIG_PARAMETER ccpu2(0x0001021b)
+
+#define OID_GEN_XMIT_OK ccpu2(0x00020101)
+#define OID_GEN_RCV_OK ccpu2(0x00020102)
+#define OID_GEN_XMIT_ERROR ccpu2(0x00020103)
+#define OID_GEN_RCV_ERROR ccpu2(0x00020104)
+#define OID_GEN_RCV_NO_BUFFER ccpu2(0x00020105)
+
+#define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101)
+#define OID_802_3_CURRENT_ADDRESS ccpu2(0x01010102)
+#define OID_802_3_MULTICAST_LIST ccpu2(0x01010103)
+#define OID_802_3_MAXIMUM_LIST_SIZE ccpu2(0x01010104)
+
+#define OID_802_11_BSSID ccpu2(0x0d010101)
+#define OID_802_11_SSID ccpu2(0x0d010102)
+#define OID_802_11_INFRASTRUCTURE_MODE ccpu2(0x0d010108)
+#define OID_802_11_ADD_WEP ccpu2(0x0d010113)
+#define OID_802_11_REMOVE_WEP ccpu2(0x0d010114)
+#define OID_802_11_DISASSOCIATE ccpu2(0x0d010115)
+#define OID_802_11_AUTHENTICATION_MODE ccpu2(0x0d010118)
+#define OID_802_11_PRIVACY_FILTER ccpu2(0x0d010119)
+#define OID_802_11_BSSID_LIST_SCAN ccpu2(0x0d01011a)
+#define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b)
+#define OID_802_11_ADD_KEY ccpu2(0x0d01011d)
+#define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e)
+#define OID_802_11_PMKID ccpu2(0x0d010123)
+#define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203)
+#define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204)
+#define OID_802_11_TX_POWER_LEVEL ccpu2(0x0d010205)
+#define OID_802_11_RSSI ccpu2(0x0d010206)
+#define OID_802_11_RSSI_TRIGGER ccpu2(0x0d010207)
+#define OID_802_11_FRAGMENTATION_THRESHOLD ccpu2(0x0d010209)
+#define OID_802_11_RTS_THRESHOLD ccpu2(0x0d01020a)
+#define OID_802_11_SUPPORTED_RATES ccpu2(0x0d01020e)
+#define OID_802_11_CONFIGURATION ccpu2(0x0d010211)
+#define OID_802_11_BSSID_LIST ccpu2(0x0d010217)
+
+
+/* Typical noise/maximum signal level values taken from ndiswrapper iw_ndis.h */
+#define WL_NOISE -96 /* typical noise level in dBm */
+#define WL_SIGMAX -32 /* typical maximum signal level in dBm */
+
+
+/* Assume that Broadcom 4320 (only chipset at time of writing known to be
+ * based on wireless rndis) has default txpower of 13dBm.
+ * This value is from Linksys WUSB54GSC User Guide, Appendix F: Specifications.
+ * 13dBm == 19.9mW
+ */
+#define BCM4320_DEFAULT_TXPOWER 20
+
+
+/* codes for "status" field of completion messages */
+#define RNDIS_STATUS_ADAPTER_NOT_READY ccpu2(0xc0010011)
+#define RNDIS_STATUS_ADAPTER_NOT_OPEN ccpu2(0xc0010012)
+
+
+/* NDIS data structures. Taken from wpa_supplicant driver_ndis.c
+ * slightly modified for datatype endianess, etc
+ */
+#define NDIS_802_11_LENGTH_SSID 32
+#define NDIS_802_11_LENGTH_RATES 8
+#define NDIS_802_11_LENGTH_RATES_EX 16
+
+struct NDIS_802_11_SSID {
+ __le32 SsidLength;
+ u8 Ssid[NDIS_802_11_LENGTH_SSID];
+} __attribute__((packed));
+
+enum NDIS_802_11_NETWORK_TYPE {
+ Ndis802_11FH,
+ Ndis802_11DS,
+ Ndis802_11OFDM5,
+ Ndis802_11OFDM24,
+ Ndis802_11NetworkTypeMax
+};
+
+struct NDIS_802_11_CONFIGURATION_FH {
+ __le32 Length;
+ __le32 HopPattern;
+ __le32 HopSet;
+ __le32 DwellTime;
+} __attribute__((packed));
+
+struct NDIS_802_11_CONFIGURATION {
+ __le32 Length;
+ __le32 BeaconPeriod;
+ __le32 ATIMWindow;
+ __le32 DSConfig;
+ struct NDIS_802_11_CONFIGURATION_FH FHConfig;
+} __attribute__((packed));
+
+enum NDIS_802_11_NETWORK_INFRASTRUCTURE {
+ Ndis802_11IBSS,
+ Ndis802_11Infrastructure,
+ Ndis802_11AutoUnknown,
+ Ndis802_11InfrastructureMax
+};
+
+enum NDIS_802_11_AUTHENTICATION_MODE {
+ Ndis802_11AuthModeOpen,
+ Ndis802_11AuthModeShared,
+ Ndis802_11AuthModeAutoSwitch,
+ Ndis802_11AuthModeWPA,
+ Ndis802_11AuthModeWPAPSK,
+ Ndis802_11AuthModeWPANone,
+ Ndis802_11AuthModeWPA2,
+ Ndis802_11AuthModeWPA2PSK,
+ Ndis802_11AuthModeMax
+};
+
+enum NDIS_802_11_ENCRYPTION_STATUS {
+ Ndis802_11WEPEnabled,
+ Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
+ Ndis802_11WEPDisabled,
+ Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
+ Ndis802_11WEPKeyAbsent,
+ Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
+ Ndis802_11WEPNotSupported,
+ Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
+ Ndis802_11Encryption2Enabled,
+ Ndis802_11Encryption2KeyAbsent,
+ Ndis802_11Encryption3Enabled,
+ Ndis802_11Encryption3KeyAbsent
+};
+
+enum NDIS_802_11_PRIVACY_FILTER {
+ Ndis802_11PrivFilterAcceptAll,
+ Ndis802_11PrivFilter8021xWEP
+};
+
+struct NDIS_WLAN_BSSID_EX {
+ __le32 Length;
+ u8 MacAddress[6];
+ u8 Padding[2];
+ struct NDIS_802_11_SSID Ssid;
+ __le32 Privacy;
+ __le32 Rssi;
+ enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
+ struct NDIS_802_11_CONFIGURATION Configuration;
+ enum NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
+ u8 SupportedRates[NDIS_802_11_LENGTH_RATES_EX];
+ __le32 IELength;
+ u8 IEs[0];
+} __attribute__((packed));
+
+struct NDIS_802_11_BSSID_LIST_EX {
+ __le32 NumberOfItems;
+ struct NDIS_WLAN_BSSID_EX Bssid[0];
+} __attribute__((packed));
+
+struct NDIS_802_11_FIXED_IEs {
+ u8 Timestamp[8];
+ __le16 BeaconInterval;
+ __le16 Capabilities;
+} __attribute__((packed));
+
+struct NDIS_802_11_WEP {
+ __le32 Length;
+ __le32 KeyIndex;
+ __le32 KeyLength;
+ u8 KeyMaterial[32];
+} __attribute__((packed));
+
+struct NDIS_802_11_KEY {
+ __le32 Length;
+ __le32 KeyIndex;
+ __le32 KeyLength;
+ u8 Bssid[6];
+ u8 Padding[6];
+ __le64 KeyRSC;
+ u8 KeyMaterial[32];
+} __attribute__((packed));
+
+struct NDIS_802_11_REMOVE_KEY {
+ __le32 Length;
+ __le32 KeyIndex;
+ u8 Bssid[6];
+} __attribute__((packed));
+
+struct RNDIS_CONFIG_PARAMETER_INFOBUFFER {
+ __le32 ParameterNameOffset;
+ __le32 ParameterNameLength;
+ __le32 ParameterType;
+ __le32 ParameterValueOffset;
+ __le32 ParameterValueLength;
+} __attribute__((packed));
+
+/* these have to match what is in wpa_supplicant */
+enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
+enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, CIPHER_WEP104 }
+ wpa_cipher;
+enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, KEY_MGMT_802_1X_NO_WPA,
+ KEY_MGMT_WPA_NONE } wpa_key_mgmt;
+
+/*
+ * private data
+ */
+#define NET_TYPE_11FB 0
+
+#define CAP_MODE_80211A 1
+#define CAP_MODE_80211B 2
+#define CAP_MODE_80211G 4
+#define CAP_MODE_MASK 7
+#define CAP_SUPPORT_TXPOWER 8
+
+#define WORK_CONNECTION_EVENT (1<<0)
+#define WORK_SET_MULTICAST_LIST (1<<1)
+
+/* RNDIS device private data */
+struct rndis_wext_private {
+ char name[32];
+
+ struct usbnet *usbdev;
+
+ struct workqueue_struct *workqueue;
+ struct delayed_work stats_work;
+ struct work_struct work;
+ struct mutex command_lock;
+ spinlock_t stats_lock;
+ unsigned long work_pending;
+
+ struct iw_statistics iwstats;
+ struct iw_statistics privstats;
+
+ int nick_len;
+ char nick[32];
+
+ int caps;
+ int multicast_size;
+
+ /* module parameters */
+ char param_country[4];
+ int param_frameburst;
+ int param_afterburner;
+ int param_power_save;
+ int param_power_output;
+ int param_roamtrigger;
+ int param_roamdelta;
+ u32 param_workaround_interval;
+
+ /* hardware state */
+ int radio_on;
+ int infra_mode;
+ struct NDIS_802_11_SSID essid;
+
+ /* encryption stuff */
+ int encr_tx_key_index;
+ char encr_keys[4][32];
+ int encr_key_len[4];
+ int wpa_version;
+ int wpa_keymgmt;
+ int wpa_authalg;
+ int wpa_ie_len;
+ u8 *wpa_ie;
+ int wpa_cipher_pair;
+ int wpa_cipher_group;
+};
+
+
+static const int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+ 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
+
+static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 };
+
+static const int bcm4320_power_output[4] = { 25, 50, 75, 100 };
+
+static const unsigned char zero_bssid[ETH_ALEN] = {0,};
+static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff };
+
+
+static struct rndis_wext_private *get_rndis_wext_priv(struct usbnet *dev)
+{
+ return (struct rndis_wext_private *)dev->driver_priv;
+}
+
+
+static u32 get_bcm4320_power(struct rndis_wext_private *priv)
+{
+ return BCM4320_DEFAULT_TXPOWER *
+ bcm4320_power_output[priv->param_power_output] / 100;
+}
+
+
+/* translate error code */
+static int rndis_error_status(__le32 rndis_status)
+{
+ int ret = -EINVAL;
+ switch (rndis_status) {
+ case RNDIS_STATUS_SUCCESS:
+ ret = 0;
+ break;
+ case RNDIS_STATUS_FAILURE:
+ case RNDIS_STATUS_INVALID_DATA:
+ ret = -EINVAL;
+ break;
+ case RNDIS_STATUS_NOT_SUPPORTED:
+ ret = -EOPNOTSUPP;
+ break;
+ case RNDIS_STATUS_ADAPTER_NOT_READY:
+ case RNDIS_STATUS_ADAPTER_NOT_OPEN:
+ ret = -EBUSY;
+ break;
+ }
+ return ret;
+}
+
+
+static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+ union {
+ void *buf;
+ struct rndis_msg_hdr *header;
+ struct rndis_query *get;
+ struct rndis_query_c *get_c;
+ } u;
+ int ret, buflen;
+
+ buflen = *len + sizeof(*u.get);
+ if (buflen < CONTROL_BUFFER_SIZE)
+ buflen = CONTROL_BUFFER_SIZE;
+ u.buf = kmalloc(buflen, GFP_KERNEL);
+ if (!u.buf)
+ return -ENOMEM;
+ memset(u.get, 0, sizeof *u.get);
+ u.get->msg_type = RNDIS_MSG_QUERY;
+ u.get->msg_len = ccpu2(sizeof *u.get);
+ u.get->oid = oid;
+
+ mutex_lock(&priv->command_lock);
+ ret = rndis_command(dev, u.header);
+ mutex_unlock(&priv->command_lock);
+
+ if (ret == 0) {
+ ret = le32_to_cpu(u.get_c->len);
+ *len = (*len > ret) ? ret : *len;
+ memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len);
+ ret = rndis_error_status(u.get_c->status);
+ }
+
+ kfree(u.buf);
+ return ret;
+}
+
+
+static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+ union {
+ void *buf;
+ struct rndis_msg_hdr *header;
+ struct rndis_set *set;
+ struct rndis_set_c *set_c;
+ } u;
+ int ret, buflen;
+
+ buflen = len + sizeof(*u.set);
+ if (buflen < CONTROL_BUFFER_SIZE)
+ buflen = CONTROL_BUFFER_SIZE;
+ u.buf = kmalloc(buflen, GFP_KERNEL);
+ if (!u.buf)
+ return -ENOMEM;
+
+ memset(u.set, 0, sizeof *u.set);
+ u.set->msg_type = RNDIS_MSG_SET;
+ u.set->msg_len = cpu_to_le32(sizeof(*u.set) + len);
+ u.set->oid = oid;
+ u.set->len = cpu_to_le32(len);
+ u.set->offset = ccpu2(sizeof(*u.set) - 8);
+ u.set->handle = ccpu2(0);
+ memcpy(u.buf + sizeof(*u.set), data, len);
+
+ mutex_lock(&priv->command_lock);
+ ret = rndis_command(dev, u.header);
+ mutex_unlock(&priv->command_lock);
+
+ if (ret == 0)
+ ret = rndis_error_status(u.set_c->status);
+
+ kfree(u.buf);
+ return ret;
+}
+
+
+/*
+ * Specs say that we can only set config parameters only soon after device
+ * initialization.
+ * value_type: 0 = u32, 2 = unicode string
+ */
+static int rndis_set_config_parameter(struct usbnet *dev, char *param,
+ int value_type, void *value)
+{
+ struct RNDIS_CONFIG_PARAMETER_INFOBUFFER *infobuf;
+ int value_len, info_len, param_len, ret, i;
+ __le16 *unibuf;
+ __le32 *dst_value;
+
+ if (value_type == 0)
+ value_len = sizeof(__le32);
+ else if (value_type == 2)
+ value_len = strlen(value) * sizeof(__le16);
+ else
+ return -EINVAL;
+
+ param_len = strlen(param) * sizeof(__le16);
+ info_len = sizeof(*infobuf) + param_len + value_len;
+
+#ifdef DEBUG
+ info_len += 12;
+#endif
+ infobuf = kmalloc(info_len, GFP_KERNEL);
+ if (!infobuf)
+ return -ENOMEM;
+
+#ifdef DEBUG
+ info_len -= 12;
+ /* extra 12 bytes are for padding (debug output) */
+ memset(infobuf, 0xCC, info_len + 12);
+#endif
+
+ if (value_type == 2)
+ devdbg(dev, "setting config parameter: %s, value: %s",
+ param, (u8 *)value);
+ else
+ devdbg(dev, "setting config parameter: %s, value: %d",
+ param, *(u32 *)value);
+
+ infobuf->ParameterNameOffset = cpu_to_le32(sizeof(*infobuf));
+ infobuf->ParameterNameLength = cpu_to_le32(param_len);
+ infobuf->ParameterType = cpu_to_le32(value_type);
+ infobuf->ParameterValueOffset = cpu_to_le32(sizeof(*infobuf) +
+ param_len);
+ infobuf->ParameterValueLength = cpu_to_le32(value_len);
+
+ /* simple string to unicode string conversion */
+ unibuf = (void *)infobuf + sizeof(*infobuf);
+ for (i = 0; i < param_len / sizeof(__le16); i++)
+ unibuf[i] = cpu_to_le16(param[i]);
+
+ if (value_type == 2) {
+ unibuf = (void *)infobuf + sizeof(*infobuf) + param_len;
+ for (i = 0; i < value_len / sizeof(__le16); i++)
+ unibuf[i] = cpu_to_le16(((u8 *)value)[i]);
+ } else {
+ dst_value = (void *)infobuf + sizeof(*infobuf) + param_len;
+ *dst_value = cpu_to_le32(*(u32 *)value);
+ }
+
+#ifdef DEBUG
+ devdbg(dev, "info buffer (len: %d):", info_len);
+ for (i = 0; i < info_len; i += 12) {
+ u32 *tmp = (u32 *)((u8 *)infobuf + i);
+ devdbg(dev, "%08X:%08X:%08X",
+ cpu_to_be32(tmp[0]),
+ cpu_to_be32(tmp[1]),
+ cpu_to_be32(tmp[2]));
+ }
+#endif
+
+ ret = rndis_set_oid(dev, OID_GEN_RNDIS_CONFIG_PARAMETER,
+ infobuf, info_len);
+ if (ret != 0)
+ devdbg(dev, "setting rndis config paramater failed, %d.", ret);
+
+ kfree(infobuf);
+ return ret;
+}
+
+static int rndis_set_config_parameter_str(struct usbnet *dev,
+ char *param, char *value)
+{
+ return(rndis_set_config_parameter(dev, param, 2, value));
+}
+
+/*static int rndis_set_config_parameter_u32(struct usbnet *dev,
+ char *param, u32 value)
+{
+ return(rndis_set_config_parameter(dev, param, 0, &value));
+}*/
+
+
+/*
+ * data conversion functions
+ */
+static int level_to_qual(int level)
+{
+ int qual = 100 * (level - WL_NOISE) / (WL_SIGMAX - WL_NOISE);
+ return qual >= 0 ? (qual <= 100 ? qual : 100) : 0;
+}
+
+
+static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq)
+{
+ freq->e = 0;
+ freq->i = 0;
+ freq->flags = 0;
+
+ /* see comment in wireless.h above the "struct iw_freq"
+ * definition for an explanation of this if
+ * NOTE: 1000000 is due to the kHz
+ */
+ if (dsconfig > 1000000) {
+ freq->m = dsconfig / 10;
+ freq->e = 1;
+ } else
+ freq->m = dsconfig;
+
+ /* convert from kHz to Hz */
+ freq->e += 3;
+}
+
+
+static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
+{
+ if (freq->m < 1000 && freq->e == 0) {
+ if (freq->m >= 1 &&
+ freq->m <= (sizeof(freq_chan) / sizeof(freq_chan[0])))
+ *dsconfig = freq_chan[freq->m - 1] * 1000;
+ else
+ return -1;
+ } else {
+ int i;
+ *dsconfig = freq->m;
+ for (i = freq->e; i > 0; i--)
+ *dsconfig *= 10;
+ *dsconfig /= 1000;
+ }
+
+ return 0;
+}
+
+
+/*
+ * common functions
+ */
+static int
+add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index);
+
+static int get_essid(struct usbnet *usbdev, struct NDIS_802_11_SSID *ssid)
+{
+ int ret, len;
+
+ len = sizeof(*ssid);
+ ret = rndis_query_oid(usbdev, OID_802_11_SSID, ssid, &len);
+
+ if (ret != 0)
+ ssid->SsidLength = 0;
+
+#ifdef DEBUG
+ {
+ unsigned char tmp[NDIS_802_11_LENGTH_SSID + 1];
+
+ memcpy(tmp, ssid->Ssid, le32_to_cpu(ssid->SsidLength));
+ tmp[le32_to_cpu(ssid->SsidLength)] = 0;
+ devdbg(usbdev, "get_essid: '%s', ret: %d", tmp, ret);
+ }
+#endif
+ return ret;
+}
+
+
+static int set_essid(struct usbnet *usbdev, struct NDIS_802_11_SSID *ssid)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ int ret;
+
+ ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid));
+ if (ret == 0) {
+ memcpy(&priv->essid, ssid, sizeof(priv->essid));
+ priv->radio_on = 1;
+ devdbg(usbdev, "set_essid: radio_on = 1");
+ }
+
+ return ret;
+}
+
+
+static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
+{
+ int ret, len;
+
+ len = ETH_ALEN;
+ ret = rndis_query_oid(usbdev, OID_802_11_BSSID, bssid, &len);
+
+ if (ret != 0)
+ memset(bssid, 0, ETH_ALEN);
+
+ return ret;
+}
+
+
+static int is_associated(struct usbnet *usbdev)
+{
+ u8 bssid[ETH_ALEN];
+ int ret;
+
+ ret = get_bssid(usbdev, bssid);
+
+ return(ret == 0 && memcmp(bssid, zero_bssid, ETH_ALEN) != 0);
+}
+
+
+static int disassociate(struct usbnet *usbdev, int reset_ssid)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct NDIS_802_11_SSID ssid;
+ int i, ret = 0;
+
+ if (priv->radio_on) {
+ ret = rndis_set_oid(usbdev, OID_802_11_DISASSOCIATE, NULL, 0);
+ if (ret == 0) {
+ priv->radio_on = 0;
+ devdbg(usbdev, "disassociate: radio_on = 0");
+
+ if (reset_ssid)
+ msleep(100);
+ }
+ }
+
+ /* disassociate causes radio to be turned off; if reset_ssid
+ * is given, set random ssid to enable radio */
+ if (reset_ssid) {
+ ssid.SsidLength = cpu_to_le32(sizeof(ssid.Ssid));
+ get_random_bytes(&ssid.Ssid[2], sizeof(ssid.Ssid)-2);
+ ssid.Ssid[0] = 0x1;
+ ssid.Ssid[1] = 0xff;
+ for (i = 2; i < sizeof(ssid.Ssid); i++)
+ ssid.Ssid[i] = 0x1 + (ssid.Ssid[i] * 0xfe / 0xff);
+ ret = set_essid(usbdev, &ssid);
+ }
+ return ret;
+}
+
+
+static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ __le32 tmp;
+ int auth_mode, ret;
+
+ devdbg(usbdev, "set_auth_mode: wpa_version=0x%x authalg=0x%x "
+ "keymgmt=0x%x", wpa_version, authalg, priv->wpa_keymgmt);
+
+ if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) {
+ if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
+ auth_mode = Ndis802_11AuthModeWPA2;
+ else
+ auth_mode = Ndis802_11AuthModeWPA2PSK;
+ } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) {
+ if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
+ auth_mode = Ndis802_11AuthModeWPA;
+ else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK)
+ auth_mode = Ndis802_11AuthModeWPAPSK;
+ else
+ auth_mode = Ndis802_11AuthModeWPANone;
+ } else if (authalg & IW_AUTH_ALG_SHARED_KEY) {
+ if (authalg & IW_AUTH_ALG_OPEN_SYSTEM)
+ auth_mode = Ndis802_11AuthModeAutoSwitch;
+ else
+ auth_mode = Ndis802_11AuthModeShared;
+ } else
+ auth_mode = Ndis802_11AuthModeOpen;
+
+ tmp = cpu_to_le32(auth_mode);
+ ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp,
+ sizeof(tmp));
+ if (ret != 0) {
+ devwarn(usbdev, "setting auth mode failed (%08X)", ret);
+ return ret;
+ }
+
+ priv->wpa_version = wpa_version;
+ priv->wpa_authalg = authalg;
+ return 0;
+}
+
+
+static int set_priv_filter(struct usbnet *usbdev)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ __le32 tmp;
+
+ devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version);
+
+ if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 ||
+ priv->wpa_version & IW_AUTH_WPA_VERSION_WPA)
+ tmp = cpu_to_le32(Ndis802_11PrivFilter8021xWEP);
+ else
+ tmp = cpu_to_le32(Ndis802_11PrivFilterAcceptAll);
+
+ return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp,
+ sizeof(tmp));
+}
+
+
+static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ __le32 tmp;
+ int encr_mode, ret;
+
+ devdbg(usbdev, "set_encr_mode: cipher_pair=0x%x cipher_group=0x%x",
+ pairwise,
+ groupwise);
+
+ if (pairwise & IW_AUTH_CIPHER_CCMP)
+ encr_mode = Ndis802_11Encryption3Enabled;
+ else if (pairwise & IW_AUTH_CIPHER_TKIP)
+ encr_mode = Ndis802_11Encryption2Enabled;
+ else if (pairwise &
+ (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
+ encr_mode = Ndis802_11Encryption1Enabled;
+ else if (groupwise & IW_AUTH_CIPHER_CCMP)
+ encr_mode = Ndis802_11Encryption3Enabled;
+ else if (groupwise & IW_AUTH_CIPHER_TKIP)
+ encr_mode = Ndis802_11Encryption2Enabled;
+ else
+ encr_mode = Ndis802_11EncryptionDisabled;
+
+ tmp = cpu_to_le32(encr_mode);
+ ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp,
+ sizeof(tmp));
+ if (ret != 0) {
+ devwarn(usbdev, "setting encr mode failed (%08X)", ret);
+ return ret;
+ }
+
+ priv->wpa_cipher_pair = pairwise;
+ priv->wpa_cipher_group = groupwise;
+ return 0;
+}
+
+
+static int set_assoc_params(struct usbnet *usbdev)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+ set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg);
+ set_priv_filter(usbdev);
+ set_encr_mode(usbdev, priv->wpa_cipher_pair, priv->wpa_cipher_group);
+
+ return 0;
+}
+
+
+static int set_infra_mode(struct usbnet *usbdev, int mode)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ __le32 tmp;
+ int ret, i;
+
+ devdbg(usbdev, "set_infra_mode: infra_mode=0x%x", priv->infra_mode);
+
+ tmp = cpu_to_le32(mode);
+ ret = rndis_set_oid(usbdev, OID_802_11_INFRASTRUCTURE_MODE, &tmp,
+ sizeof(tmp));
+ if (ret != 0) {
+ devwarn(usbdev, "setting infra mode failed (%08X)", ret);
+ return ret;
+ }
+
+ /* NDIS drivers clear keys when infrastructure mode is
+ * changed. But Linux tools assume otherwise. So set the
+ * keys */
+ if (priv->wpa_keymgmt == 0 ||
+ priv->wpa_keymgmt == IW_AUTH_KEY_MGMT_802_1X) {
+ for (i = 0; i < 4; i++) {
+ if (priv->encr_key_len[i] > 0)
+ add_wep_key(usbdev, priv->encr_keys[i],
+ priv->encr_key_len[i], i);
+ }
+ }
+
+ priv->infra_mode = mode;
+ return 0;
+}
+
+
+static void set_default_iw_params(struct usbnet *usbdev)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+ priv->wpa_keymgmt = 0;
+ priv->wpa_version = 0;
+
+ set_infra_mode(usbdev, Ndis802_11Infrastructure);
+ set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
+ IW_AUTH_ALG_OPEN_SYSTEM);
+ set_priv_filter(usbdev);
+ set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE);
+}
+
+
+static int deauthenticate(struct usbnet *usbdev)
+{
+ int ret;
+
+ ret = disassociate(usbdev, 1);
+ set_default_iw_params(usbdev);
+ return ret;
+}
+
+
+/* index must be 0 - N, as per NDIS */
+static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct NDIS_802_11_WEP ndis_key;
+ int ret;
+
+ if (key_len <= 0 || key_len > 32 || index < 0 || index >= 4)
+ return -EINVAL;
+
+ memset(&ndis_key, 0, sizeof(ndis_key));
+
+ ndis_key.Length = cpu_to_le32(sizeof(ndis_key));
+ ndis_key.KeyLength = cpu_to_le32(key_len);
+ ndis_key.KeyIndex = cpu_to_le32(index);
+ memcpy(&ndis_key.KeyMaterial, key, key_len);
+
+ if (index == priv->encr_tx_key_index) {
+ ndis_key.KeyIndex |= cpu_to_le32(1 << 31);
+ ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104,
+ IW_AUTH_CIPHER_NONE);
+ if (ret)
+ devwarn(usbdev, "encryption couldn't be enabled (%08X)",
+ ret);
+ }
+
+ ret = rndis_set_oid(usbdev, OID_802_11_ADD_WEP, &ndis_key,
+ sizeof(ndis_key));
+ if (ret != 0) {
+ devwarn(usbdev, "adding encryption key %d failed (%08X)",
+ index+1, ret);
+ return ret;
+ }
+
+ priv->encr_key_len[index] = key_len;
+ memcpy(&priv->encr_keys[index], key, key_len);
+
+ return 0;
+}
+
+
+/* remove_key is for both wep and wpa */
+static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct NDIS_802_11_REMOVE_KEY remove_key;
+ __le32 keyindex;
+ int ret;
+
+ if (priv->encr_key_len[index] == 0)
+ return 0;
+
+ priv->encr_key_len[index] = 0;
+ memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index]));
+
+ if (priv->wpa_cipher_pair == IW_AUTH_CIPHER_TKIP ||
+ priv->wpa_cipher_pair == IW_AUTH_CIPHER_CCMP ||
+ priv->wpa_cipher_group == IW_AUTH_CIPHER_TKIP ||
+ priv->wpa_cipher_group == IW_AUTH_CIPHER_CCMP) {
+ remove_key.Length = cpu_to_le32(sizeof(remove_key));
+ remove_key.KeyIndex = cpu_to_le32(index);
+ if (bssid) {
+ /* pairwise key */
+ if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0)
+ remove_key.KeyIndex |= cpu_to_le32(1 << 30);
+ memcpy(remove_key.Bssid, bssid,
+ sizeof(remove_key.Bssid));
+ } else
+ memset(remove_key.Bssid, 0xff,
+ sizeof(remove_key.Bssid));
+
+ ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_KEY, &remove_key,
+ sizeof(remove_key));
+ if (ret != 0)
+ return ret;
+ } else {
+ keyindex = cpu_to_le32(index);
+ ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_WEP, &keyindex,
+ sizeof(keyindex));
+ if (ret != 0) {
+ devwarn(usbdev,
+ "removing encryption key %d failed (%08X)",
+ index, ret);
+ return ret;
+ }
+ }
+
+ /* if it is transmit key, disable encryption */
+ if (index == priv->encr_tx_key_index)
+ set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE);
+
+ return 0;
+}
+
+
+static void set_multicast_list(struct usbnet *usbdev)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct dev_mc_list *mclist;
+ __le32 filter;
+ int ret, i, size;
+ char *buf;
+
+ filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
+
+ if (usbdev->net->flags & IFF_PROMISC) {
+ filter |= RNDIS_PACKET_TYPE_PROMISCUOUS |
+ RNDIS_PACKET_TYPE_ALL_LOCAL;
+ } else if (usbdev->net->flags & IFF_ALLMULTI ||
+ usbdev->net->mc_count > priv->multicast_size) {
+ filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
+ } else if (usbdev->net->mc_count > 0) {
+ size = min(priv->multicast_size, usbdev->net->mc_count);
+ buf = kmalloc(size * ETH_ALEN, GFP_KERNEL);
+ if (!buf) {
+ devwarn(usbdev,
+ "couldn't alloc %d bytes of memory",
+ size * ETH_ALEN);
+ return;
+ }
+
+ mclist = usbdev->net->mc_list;
+ for (i = 0; i < size && mclist; mclist = mclist->next) {
+ if (mclist->dmi_addrlen != ETH_ALEN)
+ continue;
+
+ memcpy(buf + i * ETH_ALEN, mclist->dmi_addr, ETH_ALEN);
+ i++;
+ }
+
+ ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf,
+ i * ETH_ALEN);
+ if (ret == 0 && i > 0)
+ filter |= RNDIS_PACKET_TYPE_MULTICAST;
+ else
+ filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
+
+ devdbg(usbdev, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d",
+ i, priv->multicast_size, ret);
+
+ kfree(buf);
+ }
+
+ ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
+ sizeof(filter));
+ if (ret < 0) {
+ devwarn(usbdev, "couldn't set packet filter: %08x",
+ le32_to_cpu(filter));
+ }
+
+ devdbg(usbdev, "OID_GEN_CURRENT_PACKET_FILTER(%08x) -> %d",
+ le32_to_cpu(filter), ret);
+}
+
+
+/*
+ * wireless extension handlers
+ */
+
+static int rndis_iw_commit(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ /* dummy op */
+ return 0;
+}
+
+
+static int rndis_iw_get_range(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct iw_range *range = (struct iw_range *)extra;
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ int len, ret, i, j, num, has_80211g_rates;
+ u8 rates[8];
+ __le32 tx_power;
+
+ devdbg(usbdev, "SIOCGIWRANGE");
+
+ /* clear iw_range struct */
+ memset(range, 0, sizeof(*range));
+ wrqu->data.length = sizeof(*range);
+
+ range->txpower_capa = IW_TXPOW_MWATT;
+ range->num_txpower = 1;
+ if (priv->caps & CAP_SUPPORT_TXPOWER) {
+ len = sizeof(tx_power);
+ ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
+ &tx_power, &len);
+ if (ret == 0 && le32_to_cpu(tx_power) != 0xFF)
+ range->txpower[0] = le32_to_cpu(tx_power);
+ else
+ range->txpower[0] = get_bcm4320_power(priv);
+ } else
+ range->txpower[0] = get_bcm4320_power(priv);
+
+ len = sizeof(rates);
+ ret = rndis_query_oid(usbdev, OID_802_11_SUPPORTED_RATES, &rates,
+ &len);
+ has_80211g_rates = 0;
+ if (ret == 0) {
+ j = 0;
+ for (i = 0; i < len; i++) {
+ if (rates[i] == 0)
+ break;
+ range->bitrate[j] = (rates[i] & 0x7f) * 500000;
+ /* check for non 802.11b rates */
+ if (range->bitrate[j] == 6000000 ||
+ range->bitrate[j] == 9000000 ||
+ (range->bitrate[j] >= 12000000 &&
+ range->bitrate[j] != 22000000))
+ has_80211g_rates = 1;
+ j++;
+ }
+ range->num_bitrates = j;
+ } else
+ range->num_bitrates = 0;
+
+ /* fill in 802.11g rates */
+ if (has_80211g_rates) {
+ num = range->num_bitrates;
+ for (i = 0; i < sizeof(rates_80211g); i++) {
+ for (j = 0; j < num; j++) {
+ if (range->bitrate[j] ==
+ rates_80211g[i] * 1000000)
+ break;
+ }
+ if (j == num)
+ range->bitrate[range->num_bitrates++] =
+ rates_80211g[i] * 1000000;
+ if (range->num_bitrates == IW_MAX_BITRATES)
+ break;
+ }
+
+ /* estimated max real througput in bps */
+ range->throughput = 54 * 1000 * 1000 / 2;
+
+ /* ~35% more with afterburner */
+ if (priv->param_afterburner)
+ range->throughput = range->throughput / 100 * 135;
+ } else {
+ /* estimated max real througput in bps */
+ range->throughput = 11 * 1000 * 1000 / 2;
+ }
+
+ range->num_channels = (sizeof(freq_chan)/sizeof(freq_chan[0]));
+
+ for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])) &&
+ i < IW_MAX_FREQUENCIES; i++) {
+ range->freq[i].i = i + 1;
+ range->freq[i].m = freq_chan[i] * 100000;
+ range->freq[i].e = 1;
+ }
+ range->num_frequency = i;
+
+ range->min_rts = 0;
+ range->max_rts = 2347;
+ range->min_frag = 256;
+ range->max_frag = 2346;
+
+ range->max_qual.qual = 100;
+ range->max_qual.level = 154;
+ range->max_qual.updated = IW_QUAL_QUAL_UPDATED
+ | IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_NOISE_INVALID;
+
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = WIRELESS_EXT;
+
+ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+ return 0;
+}
+
+
+static int rndis_iw_get_name(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+ strcpy(wrqu->name, priv->name);
+ return 0;
+}
+
+
+static int rndis_iw_set_essid(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
+{
+ struct NDIS_802_11_SSID ssid;
+ int length = wrqu->essid.length;
+ struct usbnet *usbdev = dev->priv;
+
+ devdbg(usbdev, "SIOCSIWESSID: [flags:%d,len:%d] '%.32s'",
+ wrqu->essid.flags, wrqu->essid.length, essid);
+
+ if (length > NDIS_802_11_LENGTH_SSID)
+ length = NDIS_802_11_LENGTH_SSID;
+
+ ssid.SsidLength = cpu_to_le32(length);
+ if (length > 0)
+ memcpy(ssid.Ssid, essid, length);
+ else
+ memset(ssid.Ssid, 0, NDIS_802_11_LENGTH_SSID);
+
+ set_assoc_params(usbdev);
+
+ if (!wrqu->essid.flags || length == 0)
+ return disassociate(usbdev, 1);
+ else
+ return set_essid(usbdev, &ssid);
+}
+
+
+static int rndis_iw_get_essid(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
+{
+ struct NDIS_802_11_SSID ssid;
+ struct usbnet *usbdev = dev->priv;
+ int ret;
+
+ ret = get_essid(usbdev, &ssid);
+
+ if (ret == 0 && le32_to_cpu(ssid.SsidLength) > 0) {
+ wrqu->essid.flags = 1;
+ wrqu->essid.length = le32_to_cpu(ssid.SsidLength);
+ memcpy(essid, ssid.Ssid, wrqu->essid.length);
+ essid[wrqu->essid.length] = 0;
+ } else {
+ memset(essid, 0, sizeof(NDIS_802_11_LENGTH_SSID));
+ wrqu->essid.flags = 0;
+ wrqu->essid.length = 0;
+ }
+ devdbg(usbdev, "SIOCGIWESSID: %s", essid);
+ return ret;
+}
+
+
+static int rndis_iw_get_bssid(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ unsigned char bssid[ETH_ALEN];
+ int ret;
+ DECLARE_MAC_BUF(mac);
+
+ ret = get_bssid(usbdev, bssid);
+
+ if (ret == 0)
+ devdbg(usbdev, "SIOCGIWAP: %s", print_mac(mac, bssid));
+ else
+ devdbg(usbdev, "SIOCGIWAP: <not associated>");
+
+ wrqu->ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(wrqu->ap_addr.sa_data, bssid, ETH_ALEN);
+
+ return ret;
+}
+
+
+static int rndis_iw_set_bssid(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ u8 *bssid = (u8 *)wrqu->ap_addr.sa_data;
+ DECLARE_MAC_BUF(mac);
+ int ret;
+
+ devdbg(usbdev, "SIOCSIWAP: %s", print_mac(mac, bssid));
+
+ ret = rndis_set_oid(usbdev, OID_802_11_BSSID, bssid, ETH_ALEN);
+
+ /* user apps may set ap's mac address, which is not required;
+ * they may fail to work if this function fails, so return
+ * success */
+ if (ret)
+ devwarn(usbdev, "setting AP mac address failed (%08X)", ret);
+
+ return 0;
+}
+
+
+static int rndis_iw_set_auth(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct iw_param *p = &wrqu->param;
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ int ret = -ENOTSUPP;
+
+ switch (p->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ devdbg(usbdev, "SIOCSIWAUTH: WPA_VERSION, %08x", p->value);
+ priv->wpa_version = p->value;
+ ret = 0;
+ break;
+
+ case IW_AUTH_CIPHER_PAIRWISE:
+ devdbg(usbdev, "SIOCSIWAUTH: CIPHER_PAIRWISE, %08x", p->value);
+ priv->wpa_cipher_pair = p->value;
+ ret = 0;
+ break;
+
+ case IW_AUTH_CIPHER_GROUP:
+ devdbg(usbdev, "SIOCSIWAUTH: CIPHER_GROUP, %08x", p->value);
+ priv->wpa_cipher_group = p->value;
+ ret = 0;
+ break;
+
+ case IW_AUTH_KEY_MGMT:
+ devdbg(usbdev, "SIOCSIWAUTH: KEY_MGMT, %08x", p->value);
+ priv->wpa_keymgmt = p->value;
+ ret = 0;
+ break;
+
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ devdbg(usbdev, "SIOCSIWAUTH: TKIP_COUNTERMEASURES, %08x",
+ p->value);
+ ret = 0;
+ break;
+
+ case IW_AUTH_DROP_UNENCRYPTED:
+ devdbg(usbdev, "SIOCSIWAUTH: DROP_UNENCRYPTED, %08x", p->value);
+ ret = 0;
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ devdbg(usbdev, "SIOCSIWAUTH: 80211_AUTH_ALG, %08x", p->value);
+ priv->wpa_authalg = p->value;
+ ret = 0;
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ devdbg(usbdev, "SIOCSIWAUTH: WPA_ENABLED, %08x", p->value);
+ if (wrqu->param.value)
+ deauthenticate(usbdev);
+ ret = 0;
+ break;
+
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ devdbg(usbdev, "SIOCSIWAUTH: RX_UNENCRYPTED_EAPOL, %08x",
+ p->value);
+ ret = 0;
+ break;
+
+ case IW_AUTH_ROAMING_CONTROL:
+ devdbg(usbdev, "SIOCSIWAUTH: ROAMING_CONTROL, %08x", p->value);
+ ret = 0;
+ break;
+
+ case IW_AUTH_PRIVACY_INVOKED:
+ devdbg(usbdev, "SIOCSIWAUTH: invalid cmd %d",
+ wrqu->param.flags & IW_AUTH_INDEX);
+ return -EOPNOTSUPP;
+
+ default:
+ devdbg(usbdev, "SIOCSIWAUTH: UNKNOWN %08x, %08x",
+ p->flags & IW_AUTH_INDEX, p->value);
+ }
+ return ret;
+}
+
+
+static int rndis_iw_get_auth(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct iw_param *p = &wrqu->param;
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+ switch (p->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ p->value = priv->wpa_version;
+ break;
+ case IW_AUTH_CIPHER_PAIRWISE:
+ p->value = priv->wpa_cipher_pair;
+ break;
+ case IW_AUTH_CIPHER_GROUP:
+ p->value = priv->wpa_cipher_group;
+ break;
+ case IW_AUTH_KEY_MGMT:
+ p->value = priv->wpa_keymgmt;
+ break;
+ case IW_AUTH_80211_AUTH_ALG:
+ p->value = priv->wpa_authalg;
+ break;
+ default:
+ devdbg(usbdev, "SIOCGIWAUTH: invalid cmd %d",
+ wrqu->param.flags & IW_AUTH_INDEX);
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+
+static int rndis_iw_get_mode(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+ switch (priv->infra_mode) {
+ case Ndis802_11IBSS:
+ wrqu->mode = IW_MODE_ADHOC;
+ break;
+ case Ndis802_11Infrastructure:
+ wrqu->mode = IW_MODE_INFRA;
+ break;
+ /*case Ndis802_11AutoUnknown:*/
+ default:
+ wrqu->mode = IW_MODE_AUTO;
+ break;
+ }
+ devdbg(usbdev, "SIOCGIWMODE: %08x", wrqu->mode);
+ return 0;
+}
+
+
+static int rndis_iw_set_mode(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ int mode;
+
+ devdbg(usbdev, "SIOCSIWMODE: %08x", wrqu->mode);
+
+ switch (wrqu->mode) {
+ case IW_MODE_ADHOC:
+ mode = Ndis802_11IBSS;
+ break;
+ case IW_MODE_INFRA:
+ mode = Ndis802_11Infrastructure;
+ break;
+ /*case IW_MODE_AUTO:*/
+ default:
+ mode = Ndis802_11AutoUnknown;
+ break;
+ }
+
+ return set_infra_mode(usbdev, mode);
+}
+
+
+static int rndis_iw_set_encode(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ int ret, index, key_len;
+ u8 *key;
+
+ index = (wrqu->encoding.flags & IW_ENCODE_INDEX);
+
+ /* iwconfig gives index as 1 - N */
+ if (index > 0)
+ index--;
+ else
+ index = priv->encr_tx_key_index;
+
+ if (index < 0 || index >= 4) {
+ devwarn(usbdev, "encryption index out of range (%u)", index);
+ return -EINVAL;
+ }
+
+ /* remove key if disabled */
+ if (wrqu->data.flags & IW_ENCODE_DISABLED) {
+ if (remove_key(usbdev, index, NULL))
+ return -EINVAL;
+ else
+ return 0;
+ }
+
+ /* global encryption state (for all keys) */
+ if (wrqu->data.flags & IW_ENCODE_OPEN)
+ ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
+ IW_AUTH_ALG_OPEN_SYSTEM);
+ else /*if (wrqu->data.flags & IW_ENCODE_RESTRICTED)*/
+ ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
+ IW_AUTH_ALG_SHARED_KEY);
+ if (ret != 0)
+ return ret;
+
+ if (wrqu->data.length > 0) {
+ key_len = wrqu->data.length;
+ key = extra;
+ } else {
+ /* must be set as tx key */
+ if (priv->encr_key_len[index] == 0)
+ return -EINVAL;
+ key_len = priv->encr_key_len[index];
+ key = priv->encr_keys[index];
+ priv->encr_tx_key_index = index;
+ }
+
+ if (add_wep_key(usbdev, key, key_len, index) != 0)
+ return -EINVAL;
+
+ if (index == priv->encr_tx_key_index)
+ /* ndis drivers want essid to be set after setting encr */
+ set_essid(usbdev, &priv->essid);
+
+ return 0;
+}
+
+
+static int rndis_iw_set_encode_ext(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct NDIS_802_11_KEY ndis_key;
+ int i, keyidx, ret;
+ u8 *addr;
+
+ keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX;
+
+ /* iwconfig gives index as 1 - N */
+ if (keyidx)
+ keyidx--;
+ else
+ keyidx = priv->encr_tx_key_index;
+
+ if (keyidx < 0 || keyidx >= 4)
+ return -EINVAL;
+
+ if (ext->alg == WPA_ALG_WEP) {
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+ priv->encr_tx_key_index = keyidx;
+ return add_wep_key(usbdev, ext->key, ext->key_len, keyidx);
+ }
+
+ if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) ||
+ ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0)
+ return remove_key(usbdev, keyidx, NULL);
+
+ if (ext->key_len > sizeof(ndis_key.KeyMaterial))
+ return -1;
+
+ memset(&ndis_key, 0, sizeof(ndis_key));
+
+ ndis_key.Length = cpu_to_le32(sizeof(ndis_key) -
+ sizeof(ndis_key.KeyMaterial) + ext->key_len);
+ ndis_key.KeyLength = cpu_to_le32(ext->key_len);
+ ndis_key.KeyIndex = cpu_to_le32(keyidx);
+
+ if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+ for (i = 0; i < 6; i++)
+ ndis_key.KeyRSC |=
+ cpu_to_le64(ext->rx_seq[i] << (i * 8));
+ ndis_key.KeyIndex |= cpu_to_le32(1 << 29);
+ }
+
+ addr = ext->addr.sa_data;
+ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+ /* group key */
+ if (priv->infra_mode == Ndis802_11IBSS)
+ memset(ndis_key.Bssid, 0xff, ETH_ALEN);
+ else
+ get_bssid(usbdev, ndis_key.Bssid);
+ } else {
+ /* pairwise key */
+ ndis_key.KeyIndex |= cpu_to_le32(1 << 30);
+ memcpy(ndis_key.Bssid, addr, ETH_ALEN);
+ }
+
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+ ndis_key.KeyIndex |= cpu_to_le32(1 << 31);
+
+ if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) {
+ /* wpa_supplicant gives us the Michael MIC RX/TX keys in
+ * different order than NDIS spec, so swap the order here. */
+ memcpy(ndis_key.KeyMaterial, ext->key, 16);
+ memcpy(ndis_key.KeyMaterial + 16, ext->key + 24, 8);
+ memcpy(ndis_key.KeyMaterial + 24, ext->key + 16, 8);
+ } else
+ memcpy(ndis_key.KeyMaterial, ext->key, ext->key_len);
+
+ ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
+ le32_to_cpu(ndis_key.Length));
+ devdbg(usbdev, "SIOCSIWENCODEEXT: OID_802_11_ADD_KEY -> %08X", ret);
+ if (ret != 0)
+ return ret;
+
+ priv->encr_key_len[keyidx] = ext->key_len;
+ memcpy(&priv->encr_keys[keyidx], ndis_key.KeyMaterial, ext->key_len);
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+ priv->encr_tx_key_index = keyidx;
+
+ return 0;
+}
+
+
+static int rndis_iw_set_scan(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct iw_param *param = &wrqu->param;
+ struct usbnet *usbdev = dev->priv;
+ union iwreq_data evt;
+ int ret = -EINVAL;
+ __le32 tmp;
+
+ devdbg(usbdev, "SIOCSIWSCAN");
+
+ if (param->flags == 0) {
+ tmp = ccpu2(1);
+ ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
+ sizeof(tmp));
+ evt.data.flags = 0;
+ evt.data.length = 0;
+ wireless_send_event(dev, SIOCGIWSCAN, &evt, NULL);
+ }
+ return ret;
+}
+
+
+static char *rndis_translate_scan(struct net_device *dev,
+ char *cev, char *end_buf, struct NDIS_WLAN_BSSID_EX *bssid)
+{
+#ifdef DEBUG
+ struct usbnet *usbdev = dev->priv;
+#endif
+ struct ieee80211_info_element *ie;
+ char *current_val;
+ int bssid_len, ie_len, i;
+ u32 beacon, atim;
+ struct iw_event iwe;
+ unsigned char sbuf[32];
+ DECLARE_MAC_BUF(mac);
+
+ bssid_len = le32_to_cpu(bssid->Length);
+
+ devdbg(usbdev, "BSSID %s", print_mac(mac, bssid->MacAddress));
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, bssid->MacAddress, ETH_ALEN);
+ cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN);
+
+ devdbg(usbdev, "SSID(%d) %s",
+ le32_to_cpu(bssid->Ssid.SsidLength),
+ bssid->Ssid.Ssid);
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.essid.length = le32_to_cpu(bssid->Ssid.SsidLength);
+ iwe.u.essid.flags = 1;
+ cev = iwe_stream_add_point(cev, end_buf, &iwe,
+ bssid->Ssid.Ssid);
+
+ devdbg(usbdev, "MODE %d",
+ le32_to_cpu(bssid->InfrastructureMode));
+ iwe.cmd = SIOCGIWMODE;
+ switch (le32_to_cpu(bssid->InfrastructureMode)) {
+ case Ndis802_11IBSS:
+ iwe.u.mode = IW_MODE_ADHOC;
+ break;
+ case Ndis802_11Infrastructure:
+ iwe.u.mode = IW_MODE_INFRA;
+ break;
+ /*case Ndis802_11AutoUnknown:*/
+ default:
+ iwe.u.mode = IW_MODE_AUTO;
+ break;
+ }
+ cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN);
+
+ devdbg(usbdev, "FREQ %d kHz",
+ le32_to_cpu(bssid->Configuration.DSConfig));
+ iwe.cmd = SIOCGIWFREQ;
+ dsconfig_to_freq(le32_to_cpu(bssid->Configuration.DSConfig),
+ &iwe.u.freq);
+ cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN);
+
+ devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->Rssi));
+ iwe.cmd = IWEVQUAL;
+ iwe.u.qual.qual = level_to_qual(le32_to_cpu(bssid->Rssi));
+ iwe.u.qual.level = le32_to_cpu(bssid->Rssi);
+ iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
+ | IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_NOISE_INVALID;
+ cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);
+
+ devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->Privacy));
+ iwe.cmd = SIOCGIWENCODE;
+ iwe.u.data.length = 0;
+ if (le32_to_cpu(bssid->Privacy) == Ndis802_11PrivFilterAcceptAll)
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+ else
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+
+ cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL);
+
+ devdbg(usbdev, "RATES:");
+ current_val = cev + IW_EV_LCP_LEN;
+ iwe.cmd = SIOCGIWRATE;
+ for (i = 0; i < sizeof(bssid->SupportedRates); i++) {
+ if (bssid->SupportedRates[i] & 0x7f) {
+ iwe.u.bitrate.value =
+ ((bssid->SupportedRates[i] & 0x7f) *
+ 500000);
+ devdbg(usbdev, " %d", iwe.u.bitrate.value);
+ current_val = iwe_stream_add_value(cev,
+ current_val, end_buf, &iwe,
+ IW_EV_PARAM_LEN);
+ }
+ }
+
+ if ((current_val - cev) > IW_EV_LCP_LEN)
+ cev = current_val;
+
+ beacon = le32_to_cpu(bssid->Configuration.BeaconPeriod);
+ devdbg(usbdev, "BCN_INT %d", beacon);
+ iwe.cmd = IWEVCUSTOM;
+ snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
+ iwe.u.data.length = strlen(sbuf);
+ cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf);
+
+ atim = le32_to_cpu(bssid->Configuration.ATIMWindow);
+ devdbg(usbdev, "ATIM %d", atim);
+ iwe.cmd = IWEVCUSTOM;
+ snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
+ iwe.u.data.length = strlen(sbuf);
+ cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf);
+
+ ie = (void *)(bssid->IEs + sizeof(struct NDIS_802_11_FIXED_IEs));
+ ie_len = min(bssid_len - (int)sizeof(*bssid),
+ (int)le32_to_cpu(bssid->IELength));
+ ie_len -= sizeof(struct NDIS_802_11_FIXED_IEs);
+ while (ie_len >= sizeof(*ie) && sizeof(*ie) + ie->len <= ie_len) {
+ if ((ie->id == MFIE_TYPE_GENERIC && ie->len >= 4 &&
+ memcmp(ie->data, "\x00\x50\xf2\x01", 4) == 0) ||
+ ie->id == MFIE_TYPE_RSN) {
+ devdbg(usbdev, "IE: WPA%d",
+ (ie->id == MFIE_TYPE_RSN) ? 2 : 1);
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN);
+ cev = iwe_stream_add_point(cev, end_buf, &iwe,
+ (u8 *)ie);
+ }
+
+ ie_len -= sizeof(*ie) + ie->len;
+ ie = (struct ieee80211_info_element *)&ie->data[ie->len];
+ }
+
+ return cev;
+}
+
+
+static int rndis_iw_get_scan(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ void *buf = NULL;
+ char *cev = extra;
+ struct NDIS_802_11_BSSID_LIST_EX *bssid_list;
+ struct NDIS_WLAN_BSSID_EX *bssid;
+ int ret = -EINVAL, len, count, bssid_len;
+
+ devdbg(usbdev, "SIOCGIWSCAN");
+
+ len = CONTROL_BUFFER_SIZE;
+ buf = kmalloc(len, GFP_KERNEL);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
+
+ if (ret != 0)
+ goto out;
+
+ bssid_list = buf;
+ bssid = bssid_list->Bssid;
+ bssid_len = le32_to_cpu(bssid->Length);
+ count = le32_to_cpu(bssid_list->NumberOfItems);
+ devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
+
+ while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
+ cev = rndis_translate_scan(dev, cev, extra + IW_SCAN_MAX_DATA,
+ bssid);
+ bssid = (void *)bssid + bssid_len;
+ bssid_len = le32_to_cpu(bssid->Length);
+ count--;
+ }
+
+out:
+ wrqu->data.length = cev - extra;
+ wrqu->data.flags = 0;
+ kfree(buf);
+ return ret;
+}
+
+
+static int rndis_iw_set_genie(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ int ret = 0;
+
+#ifdef DEBUG
+ int j;
+ u8 *gie = extra;
+ for (j = 0; j < wrqu->data.length; j += 8)
+ devdbg(usbdev,
+ "SIOCSIWGENIE %04x - "
+ "%02x %02x %02x %02x %02x %02x %02x %02x", j,
+ gie[j + 0], gie[j + 1], gie[j + 2], gie[j + 3],
+ gie[j + 4], gie[j + 5], gie[j + 6], gie[j + 7]);
+#endif
+ /* clear existing IEs */
+ if (priv->wpa_ie_len) {
+ kfree(priv->wpa_ie);
+ priv->wpa_ie_len = 0;
+ }
+
+ /* set new IEs */
+ priv->wpa_ie = kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (priv->wpa_ie) {
+ priv->wpa_ie_len = wrqu->data.length;
+ memcpy(priv->wpa_ie, extra, priv->wpa_ie_len);
+ } else
+ ret = -ENOMEM;
+ return ret;
+}
+
+
+static int rndis_iw_get_genie(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+ devdbg(usbdev, "SIOCGIWGENIE");
+
+ if (priv->wpa_ie_len == 0 || priv->wpa_ie == NULL) {
+ wrqu->data.length = 0;
+ return 0;
+ }
+
+ if (wrqu->data.length < priv->wpa_ie_len)
+ return -E2BIG;
+
+ wrqu->data.length = priv->wpa_ie_len;
+ memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
+
+ return 0;
+}
+
+
+static int rndis_iw_set_rts(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ __le32 tmp;
+ devdbg(usbdev, "SIOCSIWRTS");
+
+ tmp = cpu_to_le32(wrqu->rts.value);
+ return rndis_set_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp,
+ sizeof(tmp));
+}
+
+
+static int rndis_iw_get_rts(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ __le32 tmp;
+ int len, ret;
+
+ len = sizeof(tmp);
+ ret = rndis_query_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp, &len);
+ if (ret == 0) {
+ wrqu->rts.value = le32_to_cpu(tmp);
+ wrqu->rts.flags = 1;
+ wrqu->rts.disabled = 0;
+ }
+
+ devdbg(usbdev, "SIOCGIWRTS: %d", wrqu->rts.value);
+
+ return ret;
+}
+
+
+static int rndis_iw_set_frag(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ __le32 tmp;
+
+ devdbg(usbdev, "SIOCSIWFRAG");
+
+ tmp = cpu_to_le32(wrqu->frag.value);
+ return rndis_set_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp,
+ sizeof(tmp));
+}
+
+
+static int rndis_iw_get_frag(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ __le32 tmp;
+ int len, ret;
+
+ len = sizeof(tmp);
+ ret = rndis_query_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp,
+ &len);
+ if (ret == 0) {
+ wrqu->frag.value = le32_to_cpu(tmp);
+ wrqu->frag.flags = 1;
+ wrqu->frag.disabled = 0;
+ }
+ devdbg(usbdev, "SIOCGIWFRAG: %d", wrqu->frag.value);
+ return ret;
+}
+
+
+static int rndis_iw_set_nick(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+ devdbg(usbdev, "SIOCSIWNICK");
+
+ priv->nick_len = wrqu->data.length;
+ if (priv->nick_len > 32)
+ priv->nick_len = 32;
+
+ memcpy(priv->nick, extra, priv->nick_len);
+ return 0;
+}
+
+
+static int rndis_iw_get_nick(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+ wrqu->data.flags = 1;
+ wrqu->data.length = priv->nick_len;
+ memcpy(extra, priv->nick, priv->nick_len);
+
+ devdbg(usbdev, "SIOCGIWNICK: '%s'", priv->nick);
+
+ return 0;
+}
+
+
+static int rndis_iw_set_freq(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct NDIS_802_11_CONFIGURATION config;
+ unsigned int dsconfig;
+ int len, ret;
+
+ /* this OID is valid only when not associated */
+ if (is_associated(usbdev))
+ return 0;
+
+ dsconfig = 0;
+ if (freq_to_dsconfig(&wrqu->freq, &dsconfig))
+ return -EINVAL;
+
+ len = sizeof(config);
+ ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
+ if (ret != 0) {
+ devdbg(usbdev, "SIOCSIWFREQ: querying configuration failed");
+ return 0;
+ }
+
+ config.DSConfig = cpu_to_le32(dsconfig);
+
+ devdbg(usbdev, "SIOCSIWFREQ: %d * 10^%d", wrqu->freq.m, wrqu->freq.e);
+ return rndis_set_oid(usbdev, OID_802_11_CONFIGURATION, &config,
+ sizeof(config));
+}
+
+
+static int rndis_iw_get_freq(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct NDIS_802_11_CONFIGURATION config;
+ int len, ret;
+
+ len = sizeof(config);
+ ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
+ if (ret == 0)
+ dsconfig_to_freq(le32_to_cpu(config.DSConfig), &wrqu->freq);
+
+ devdbg(usbdev, "SIOCGIWFREQ: %d", wrqu->freq.m);
+ return ret;
+}
+
+
+static int rndis_iw_get_txpower(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ __le32 tx_power;
+ int ret = 0, len;
+
+ if (priv->radio_on) {
+ if (priv->caps & CAP_SUPPORT_TXPOWER) {
+ len = sizeof(tx_power);
+ ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
+ &tx_power, &len);
+ if (ret != 0)
+ return ret;
+ } else
+ /* fake incase not supported */
+ tx_power = cpu_to_le32(get_bcm4320_power(priv));
+
+ wrqu->txpower.flags = IW_TXPOW_MWATT;
+ wrqu->txpower.value = le32_to_cpu(tx_power);
+ wrqu->txpower.disabled = 0;
+ } else {
+ wrqu->txpower.flags = IW_TXPOW_MWATT;
+ wrqu->txpower.value = 0;
+ wrqu->txpower.disabled = 1;
+ }
+
+ devdbg(usbdev, "SIOCGIWTXPOW: %d", wrqu->txpower.value);
+
+ return ret;
+}
+
+
+static int rndis_iw_set_txpower(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ __le32 tx_power = 0;
+ int ret = 0;
+
+ if (!wrqu->txpower.disabled) {
+ if (wrqu->txpower.flags == IW_TXPOW_MWATT)
+ tx_power = cpu_to_le32(wrqu->txpower.value);
+ else { /* wrqu->txpower.flags == IW_TXPOW_DBM */
+ if (wrqu->txpower.value > 20)
+ tx_power = cpu_to_le32(128);
+ else if (wrqu->txpower.value < -43)
+ tx_power = cpu_to_le32(127);
+ else {
+ signed char tmp;
+ tmp = wrqu->txpower.value;
+ tmp = -12 - tmp;
+ tmp <<= 2;
+ tx_power = cpu_to_le32((unsigned char)tmp);
+ }
+ }
+ }
+
+ devdbg(usbdev, "SIOCSIWTXPOW: %d", le32_to_cpu(tx_power));
+
+ if (le32_to_cpu(tx_power) != 0) {
+ if (priv->caps & CAP_SUPPORT_TXPOWER) {
+ /* turn radio on first */
+ if (!priv->radio_on)
+ disassociate(usbdev, 1);
+
+ ret = rndis_set_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
+ &tx_power, sizeof(tx_power));
+ if (ret != 0)
+ ret = -EOPNOTSUPP;
+ return ret;
+ } else {
+ /* txpower unsupported, just turn radio on */
+ if (!priv->radio_on)
+ return disassociate(usbdev, 1);
+ return 0; /* all ready on */
+ }
+ }
+
+ /* tx_power == 0, turn off radio */
+ return disassociate(usbdev, 0);
+}
+
+
+static int rndis_iw_get_rate(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ __le32 tmp;
+ int ret, len;
+
+ len = sizeof(tmp);
+ ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &tmp, &len);
+ if (ret == 0) {
+ wrqu->bitrate.value = le32_to_cpu(tmp) * 100;
+ wrqu->bitrate.disabled = 0;
+ wrqu->bitrate.flags = 1;
+ }
+ return ret;
+}
+
+
+static int rndis_iw_set_mlme(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct iw_mlme *mlme = (struct iw_mlme *)extra;
+ unsigned char bssid[ETH_ALEN];
+
+ get_bssid(usbdev, bssid);
+
+ if (memcmp(bssid, mlme->addr.sa_data, ETH_ALEN))
+ return -EINVAL;
+
+ switch (mlme->cmd) {
+ case IW_MLME_DEAUTH:
+ return deauthenticate(usbdev);
+ case IW_MLME_DISASSOC:
+ return disassociate(usbdev, priv->radio_on);
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+
+static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->stats_lock, flags);
+ memcpy(&priv->iwstats, &priv->privstats, sizeof(priv->iwstats));
+ spin_unlock_irqrestore(&priv->stats_lock, flags);
+
+ return &priv->iwstats;
+}
+
+
+#define IW_IOCTL(x) [(x) - SIOCSIWCOMMIT]
+static const iw_handler rndis_iw_handler[] =
+{
+ IW_IOCTL(SIOCSIWCOMMIT) = rndis_iw_commit,
+ IW_IOCTL(SIOCGIWNAME) = rndis_iw_get_name,
+ IW_IOCTL(SIOCSIWFREQ) = rndis_iw_set_freq,
+ IW_IOCTL(SIOCGIWFREQ) = rndis_iw_get_freq,
+ IW_IOCTL(SIOCSIWMODE) = rndis_iw_set_mode,
+ IW_IOCTL(SIOCGIWMODE) = rndis_iw_get_mode,
+ IW_IOCTL(SIOCGIWRANGE) = rndis_iw_get_range,
+ IW_IOCTL(SIOCSIWAP) = rndis_iw_set_bssid,
+ IW_IOCTL(SIOCGIWAP) = rndis_iw_get_bssid,
+ IW_IOCTL(SIOCSIWSCAN) = rndis_iw_set_scan,
+ IW_IOCTL(SIOCGIWSCAN) = rndis_iw_get_scan,
+ IW_IOCTL(SIOCSIWESSID) = rndis_iw_set_essid,
+ IW_IOCTL(SIOCGIWESSID) = rndis_iw_get_essid,
+ IW_IOCTL(SIOCSIWNICKN) = rndis_iw_set_nick,
+ IW_IOCTL(SIOCGIWNICKN) = rndis_iw_get_nick,
+ IW_IOCTL(SIOCGIWRATE) = rndis_iw_get_rate,
+ IW_IOCTL(SIOCSIWRTS) = rndis_iw_set_rts,
+ IW_IOCTL(SIOCGIWRTS) = rndis_iw_get_rts,
+ IW_IOCTL(SIOCSIWFRAG) = rndis_iw_set_frag,
+ IW_IOCTL(SIOCGIWFRAG) = rndis_iw_get_frag,
+ IW_IOCTL(SIOCSIWTXPOW) = rndis_iw_set_txpower,
+ IW_IOCTL(SIOCGIWTXPOW) = rndis_iw_get_txpower,
+ IW_IOCTL(SIOCSIWENCODE) = rndis_iw_set_encode,
+ IW_IOCTL(SIOCSIWENCODEEXT) = rndis_iw_set_encode_ext,
+ IW_IOCTL(SIOCSIWAUTH) = rndis_iw_set_auth,
+ IW_IOCTL(SIOCGIWAUTH) = rndis_iw_get_auth,
+ IW_IOCTL(SIOCSIWGENIE) = rndis_iw_set_genie,
+ IW_IOCTL(SIOCGIWGENIE) = rndis_iw_get_genie,
+ IW_IOCTL(SIOCSIWMLME) = rndis_iw_set_mlme,
+};
+
+static const iw_handler rndis_wext_private_handler[] = {
+};
+
+static const struct iw_priv_args rndis_wext_private_args[] = {
+};
+
+
+static const struct iw_handler_def rndis_iw_handlers = {
+ .num_standard = ARRAY_SIZE(rndis_iw_handler),
+ .num_private = ARRAY_SIZE(rndis_wext_private_handler),
+ .num_private_args = ARRAY_SIZE(rndis_wext_private_args),
+ .standard = (iw_handler *)rndis_iw_handler,
+ .private = (iw_handler *)rndis_wext_private_handler,
+ .private_args = (struct iw_priv_args *)rndis_wext_private_args,
+ .get_wireless_stats = rndis_get_wireless_stats,
+};
+
+
+static void rndis_wext_worker(struct work_struct *work)
+{
+ struct rndis_wext_private *priv =
+ container_of(work, struct rndis_wext_private, work);
+ struct usbnet *usbdev = priv->usbdev;
+ union iwreq_data evt;
+ unsigned char bssid[ETH_ALEN];
+ int ret;
+
+ if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) {
+ ret = get_bssid(usbdev, bssid);
+
+ if (!ret) {
+ evt.data.flags = 0;
+ evt.data.length = 0;
+ memcpy(evt.ap_addr.sa_data, bssid, ETH_ALEN);
+ wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
+ }
+ }
+
+ if (test_and_clear_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
+ set_multicast_list(usbdev);
+}
+
+static void rndis_wext_set_multicast_list(struct net_device *dev)
+{
+ struct usbnet *usbdev = dev->priv;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+ set_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending);
+ queue_work(priv->workqueue, &priv->work);
+}
+
+static void rndis_wext_link_change(struct usbnet *dev, int state)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+ union iwreq_data evt;
+
+ if (state) {
+ /* queue work to avoid recursive calls into rndis_command */
+ set_bit(WORK_CONNECTION_EVENT, &priv->work_pending);
+ queue_work(priv->workqueue, &priv->work);
+ } else {
+ evt.data.flags = 0;
+ evt.data.length = 0;
+ memset(evt.ap_addr.sa_data, 0, ETH_ALEN);
+ wireless_send_event(dev->net, SIOCGIWAP, &evt, NULL);
+ }
+}
+
+
+static int rndis_wext_get_caps(struct usbnet *dev)
+{
+ struct {
+ __le32 num_items;
+ __le32 items[8];
+ } networks_supported;
+ int len, retval, i, n;
+ __le32 tx_power;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+
+ /* determine if supports setting txpower */
+ len = sizeof(tx_power);
+ retval = rndis_query_oid(dev, OID_802_11_TX_POWER_LEVEL, &tx_power,
+ &len);
+ if (retval == 0 && le32_to_cpu(tx_power) != 0xFF)
+ priv->caps |= CAP_SUPPORT_TXPOWER;
+
+ /* determine supported modes */
+ len = sizeof(networks_supported);
+ retval = rndis_query_oid(dev, OID_802_11_NETWORK_TYPES_SUPPORTED,
+ &networks_supported, &len);
+ if (retval >= 0) {
+ n = le32_to_cpu(networks_supported.num_items);
+ if (n > 8)
+ n = 8;
+ for (i = 0; i < n; i++) {
+ switch (le32_to_cpu(networks_supported.items[i])) {
+ case Ndis802_11FH:
+ case Ndis802_11DS:
+ priv->caps |= CAP_MODE_80211B;
+ break;
+ case Ndis802_11OFDM5:
+ priv->caps |= CAP_MODE_80211A;
+ break;
+ case Ndis802_11OFDM24:
+ priv->caps |= CAP_MODE_80211G;
+ break;
+ }
+ }
+ if (priv->caps & CAP_MODE_80211A)
+ strcat(priv->name, "a");
+ if (priv->caps & CAP_MODE_80211B)
+ strcat(priv->name, "b");
+ if (priv->caps & CAP_MODE_80211G)
+ strcat(priv->name, "g");
+ }
+
+ return retval;
+}
+
+
+#define STATS_UPDATE_JIFFIES (HZ)
+static void rndis_update_wireless_stats(struct work_struct *work)
+{
+ struct rndis_wext_private *priv =
+ container_of(work, struct rndis_wext_private, stats_work.work);
+ struct usbnet *usbdev = priv->usbdev;
+ struct iw_statistics iwstats;
+ __le32 rssi, tmp;
+ int len, ret, bitrate, j;
+ unsigned long flags;
+ int update_jiffies = STATS_UPDATE_JIFFIES;
+ void *buf;
+
+ spin_lock_irqsave(&priv->stats_lock, flags);
+ memcpy(&iwstats, &priv->privstats, sizeof(iwstats));
+ spin_unlock_irqrestore(&priv->stats_lock, flags);
+
+ /* only update stats when connected */
+ if (!is_associated(usbdev)) {
+ iwstats.qual.qual = 0;
+ iwstats.qual.level = 0;
+ iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
+ | IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_NOISE_INVALID
+ | IW_QUAL_QUAL_INVALID
+ | IW_QUAL_LEVEL_INVALID;
+ goto end;
+ }
+
+ len = sizeof(rssi);
+ ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
+
+ devdbg(usbdev, "stats: OID_802_11_RSSI -> %d, rssi:%d", ret,
+ le32_to_cpu(rssi));
+ if (ret == 0) {
+ memset(&iwstats.qual, 0, sizeof(iwstats.qual));
+ iwstats.qual.qual = level_to_qual(le32_to_cpu(rssi));
+ iwstats.qual.level = le32_to_cpu(rssi);
+ iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
+ | IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_NOISE_INVALID;
+ }
+
+ memset(&iwstats.discard, 0, sizeof(iwstats.discard));
+
+ len = sizeof(tmp);
+ ret = rndis_query_oid(usbdev, OID_GEN_XMIT_ERROR, &tmp, &len);
+ if (ret == 0)
+ iwstats.discard.misc += le32_to_cpu(tmp);
+
+ len = sizeof(tmp);
+ ret = rndis_query_oid(usbdev, OID_GEN_RCV_ERROR, &tmp, &len);
+ if (ret == 0)
+ iwstats.discard.misc += le32_to_cpu(tmp);
+
+ len = sizeof(tmp);
+ ret = rndis_query_oid(usbdev, OID_GEN_RCV_NO_BUFFER, &tmp, &len);
+ if (ret == 0)
+ iwstats.discard.misc += le32_to_cpu(tmp);
+
+ /* Workaround transfer stalls on poor quality links. */
+ len = sizeof(tmp);
+ ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &tmp, &len);
+ if (ret == 0) {
+ bitrate = le32_to_cpu(tmp) * 100;
+ if (bitrate > 11000000)
+ goto end;
+
+ /* Decrease stats worker interval to catch stalls.
+ * faster. Faster than 400-500ms causes packet loss,
+ * Slower doesn't catch stalls fast enough.
+ */
+ j = msecs_to_jiffies(priv->param_workaround_interval);
+ if (j > STATS_UPDATE_JIFFIES)
+ j = STATS_UPDATE_JIFFIES;
+ else if (j <= 0)
+ j = 1;
+ update_jiffies = j;
+
+ /* Send scan OID. Use of both OIDs is required to get device
+ * working.
+ */
+ tmp = ccpu2(1);
+ rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
+ sizeof(tmp));
+
+ len = CONTROL_BUFFER_SIZE;
+ buf = kmalloc(len, GFP_KERNEL);
+ if (!buf)
+ goto end;
+
+ rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
+ kfree(buf);
+ }
+end:
+ spin_lock_irqsave(&priv->stats_lock, flags);
+ memcpy(&priv->privstats, &iwstats, sizeof(iwstats));
+ spin_unlock_irqrestore(&priv->stats_lock, flags);
+
+ if (update_jiffies >= HZ)
+ update_jiffies = round_jiffies_relative(update_jiffies);
+ else {
+ j = round_jiffies_relative(update_jiffies);
+ if (abs(j - update_jiffies) <= 10)
+ update_jiffies = j;
+ }
+
+ queue_delayed_work(priv->workqueue, &priv->stats_work, update_jiffies);
+}
+
+
+static int bcm4320_early_init(struct usbnet *dev)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+ char buf[8];
+
+ /* Early initialization settings, setting these won't have effect
+ * if called after generic_rndis_bind().
+ */
+
+ priv->param_country[0] = modparam_country[0];
+ priv->param_country[1] = modparam_country[1];
+ priv->param_country[2] = 0;
+ priv->param_frameburst = modparam_frameburst;
+ priv->param_afterburner = modparam_afterburner;
+ priv->param_power_save = modparam_power_save;
+ priv->param_power_output = modparam_power_output;
+ priv->param_roamtrigger = modparam_roamtrigger;
+ priv->param_roamdelta = modparam_roamdelta;
+ priv->param_workaround_interval = modparam_workaround_interval;
+
+ priv->param_country[0] = toupper(priv->param_country[0]);
+ priv->param_country[1] = toupper(priv->param_country[1]);
+ /* doesn't support EU as country code, use FI instead */
+ if (!strcmp(priv->param_country, "EU"))
+ strcpy(priv->param_country, "FI");
+
+ if (priv->param_power_save < 0)
+ priv->param_power_save = 0;
+ else if (priv->param_power_save > 2)
+ priv->param_power_save = 2;
+
+ if (priv->param_roamtrigger < -80)
+ priv->param_roamtrigger = -80;
+ else if (priv->param_roamtrigger > -60)
+ priv->param_roamtrigger = -60;
+
+ if (priv->param_roamdelta < 0)
+ priv->param_roamdelta = 0;
+ else if (priv->param_roamdelta > 2)
+ priv->param_roamdelta = 2;
+
+ if (priv->param_workaround_interval < 0)
+ priv->param_workaround_interval = 500;
+
+ rndis_set_config_parameter_str(dev, "Country", priv->param_country);
+ rndis_set_config_parameter_str(dev, "FrameBursting",
+ priv->param_frameburst ? "1" : "0");
+ rndis_set_config_parameter_str(dev, "Afterburner",
+ priv->param_afterburner ? "1" : "0");
+ sprintf(buf, "%d", priv->param_power_save);
+ rndis_set_config_parameter_str(dev, "PowerSaveMode", buf);
+ sprintf(buf, "%d", priv->param_power_output);
+ rndis_set_config_parameter_str(dev, "PwrOut", buf);
+ sprintf(buf, "%d", priv->param_roamtrigger);
+ rndis_set_config_parameter_str(dev, "RoamTrigger", buf);
+ sprintf(buf, "%d", priv->param_roamdelta);
+ rndis_set_config_parameter_str(dev, "RoamDelta", buf);
+
+ return 0;
+}
+
+
+static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ struct net_device *net = dev->net;
+ struct rndis_wext_private *priv;
+ int retval, len;
+ __le32 tmp;
+
+ /* allocate rndis private data */
+ priv = kmalloc(sizeof(struct rndis_wext_private), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ /* These have to be initialized before calling generic_rndis_bind().
+ * Otherwise we'll be in big trouble in rndis_wext_early_init().
+ */
+ dev->driver_priv = priv;
+ memset(priv, 0, sizeof(*priv));
+ memset(priv->name, 0, sizeof(priv->name));
+ strcpy(priv->name, "IEEE802.11");
+ net->wireless_handlers = &rndis_iw_handlers;
+ priv->usbdev = dev;
+
+ mutex_init(&priv->command_lock);
+ spin_lock_init(&priv->stats_lock);
+
+ /* try bind rndis_host */
+ retval = generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_WIRELESS);
+ if (retval < 0)
+ goto fail;
+
+ /* generic_rndis_bind set packet filter to multicast_all+
+ * promisc mode which doesn't work well for our devices (device
+ * picks up rssi to closest station instead of to access point).
+ *
+ * rndis_host wants to avoid all OID as much as possible
+ * so do promisc/multicast handling in rndis_wext.
+ */
+ dev->net->set_multicast_list = rndis_wext_set_multicast_list;
+ tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
+ retval = rndis_set_oid(dev, OID_GEN_CURRENT_PACKET_FILTER, &tmp,
+ sizeof(tmp));
+
+ len = sizeof(tmp);
+ retval = rndis_query_oid(dev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp, &len);
+ priv->multicast_size = le32_to_cpu(tmp);
+ if (retval < 0 || priv->multicast_size < 0)
+ priv->multicast_size = 0;
+ if (priv->multicast_size > 0)
+ dev->net->flags |= IFF_MULTICAST;
+ else
+ dev->net->flags &= ~IFF_MULTICAST;
+
+ priv->iwstats.qual.qual = 0;
+ priv->iwstats.qual.level = 0;
+ priv->iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
+ | IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_NOISE_INVALID
+ | IW_QUAL_QUAL_INVALID
+ | IW_QUAL_LEVEL_INVALID;
+
+ rndis_wext_get_caps(dev);
+ set_default_iw_params(dev);
+
+ /* turn radio on */
+ priv->radio_on = 1;
+ disassociate(dev, 1);
+
+ /* because rndis_command() sleeps we need to use workqueue */
+ priv->workqueue = create_singlethread_workqueue("rndis_wlan");
+ INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats);
+ queue_delayed_work(priv->workqueue, &priv->stats_work,
+ round_jiffies_relative(STATS_UPDATE_JIFFIES));
+ INIT_WORK(&priv->work, rndis_wext_worker);
+
+ return 0;
+
+fail:
+ kfree(priv);
+ return retval;
+}
+
+
+static void rndis_wext_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+
+ /* turn radio off */
+ disassociate(dev, 0);
+
+ cancel_delayed_work_sync(&priv->stats_work);
+ cancel_work_sync(&priv->work);
+ flush_workqueue(priv->workqueue);
+ destroy_workqueue(priv->workqueue);
+
+ if (priv && priv->wpa_ie_len)
+ kfree(priv->wpa_ie);
+ kfree(priv);
+
+ rndis_unbind(dev, intf);
+}
+
+
+static int rndis_wext_reset(struct usbnet *dev)
+{
+ return deauthenticate(dev);
+}
+
+
+static const struct driver_info bcm4320b_info = {
+ .description = "Wireless RNDIS device, BCM4320b based",
+ .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
+ .bind = rndis_wext_bind,
+ .unbind = rndis_wext_unbind,
+ .status = rndis_status,
+ .rx_fixup = rndis_rx_fixup,
+ .tx_fixup = rndis_tx_fixup,
+ .reset = rndis_wext_reset,
+ .early_init = bcm4320_early_init,
+ .link_change = rndis_wext_link_change,
+};
+
+static const struct driver_info bcm4320a_info = {
+ .description = "Wireless RNDIS device, BCM4320a based",
+ .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
+ .bind = rndis_wext_bind,
+ .unbind = rndis_wext_unbind,
+ .status = rndis_status,
+ .rx_fixup = rndis_rx_fixup,
+ .tx_fixup = rndis_tx_fixup,
+ .reset = rndis_wext_reset,
+ .early_init = bcm4320_early_init,
+ .link_change = rndis_wext_link_change,
+};
+
+static const struct driver_info rndis_wext_info = {
+ .description = "Wireless RNDIS device",
+ .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
+ .bind = rndis_wext_bind,
+ .unbind = rndis_wext_unbind,
+ .status = rndis_status,
+ .rx_fixup = rndis_rx_fixup,
+ .tx_fixup = rndis_tx_fixup,
+ .reset = rndis_wext_reset,
+ .early_init = bcm4320_early_init,
+ .link_change = rndis_wext_link_change,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static const struct usb_device_id products [] = {
+#define RNDIS_MASTER_INTERFACE \
+ .bInterfaceClass = USB_CLASS_COMM, \
+ .bInterfaceSubClass = 2 /* ACM */, \
+ .bInterfaceProtocol = 0x0ff
+
+/* INF driver for these devices have DriverVer >= 4.xx.xx.xx and many custom
+ * parameters available. Chipset marked as 'BCM4320SKFBG' in NDISwrapper-wiki.
+ */
+{
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x0411,
+ .idProduct = 0x00bc, /* Buffalo WLI-U2-KG125S */
+ RNDIS_MASTER_INTERFACE,
+ .driver_info = (unsigned long) &bcm4320b_info,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x0baf,
+ .idProduct = 0x011b, /* U.S. Robotics USR5421 */
+ RNDIS_MASTER_INTERFACE,
+ .driver_info = (unsigned long) &bcm4320b_info,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x050d,
+ .idProduct = 0x011b, /* Belkin F5D7051 */
+ RNDIS_MASTER_INTERFACE,
+ .driver_info = (unsigned long) &bcm4320b_info,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x1799, /* Belkin has two vendor ids */
+ .idProduct = 0x011b, /* Belkin F5D7051 */
+ RNDIS_MASTER_INTERFACE,
+ .driver_info = (unsigned long) &bcm4320b_info,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x13b1,
+ .idProduct = 0x0014, /* Linksys WUSB54GSv2 */
+ RNDIS_MASTER_INTERFACE,
+ .driver_info = (unsigned long) &bcm4320b_info,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x13b1,
+ .idProduct = 0x0026, /* Linksys WUSB54GSC */
+ RNDIS_MASTER_INTERFACE,
+ .driver_info = (unsigned long) &bcm4320b_info,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x0b05,
+ .idProduct = 0x1717, /* Asus WL169gE */
+ RNDIS_MASTER_INTERFACE,
+ .driver_info = (unsigned long) &bcm4320b_info,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x0a5c,
+ .idProduct = 0xd11b, /* Eminent EM4045 */
+ RNDIS_MASTER_INTERFACE,
+ .driver_info = (unsigned long) &bcm4320b_info,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x1690,
+ .idProduct = 0x0715, /* BT Voyager 1055 */
+ RNDIS_MASTER_INTERFACE,
+ .driver_info = (unsigned long) &bcm4320b_info,
+},
+/* These devices have DriverVer < 4.xx.xx.xx and do not have any custom
+ * parameters available, hardware probably contain older firmware version with
+ * no way of updating. Chipset marked as 'BCM4320????' in NDISwrapper-wiki.
+ */
+{
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x13b1,
+ .idProduct = 0x000e, /* Linksys WUSB54GSv1 */
+ RNDIS_MASTER_INTERFACE,
+ .driver_info = (unsigned long) &bcm4320a_info,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x0baf,
+ .idProduct = 0x0111, /* U.S. Robotics USR5420 */
+ RNDIS_MASTER_INTERFACE,
+ .driver_info = (unsigned long) &bcm4320a_info,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x0411,
+ .idProduct = 0x004b, /* BUFFALO WLI-USB-G54 */
+ RNDIS_MASTER_INTERFACE,
+ .driver_info = (unsigned long) &bcm4320a_info,
+},
+/* Generic Wireless RNDIS devices that we don't have exact
+ * idVendor/idProduct/chip yet.
+ */
+{
+ /* RNDIS is MSFT's un-official variant of CDC ACM */
+ USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
+ .driver_info = (unsigned long) &rndis_wext_info,
+}, {
+ /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
+ USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
+ .driver_info = (unsigned long) &rndis_wext_info,
+},
+ { }, // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver rndis_wlan_driver = {
+ .name = "rndis_wlan",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+};
+
+static int __init rndis_wlan_init(void)
+{
+ return usb_register(&rndis_wlan_driver);
+}
+module_init(rndis_wlan_init);
+
+static void __exit rndis_wlan_exit(void)
+{
+ usb_deregister(&rndis_wlan_driver);
+}
+module_exit(rndis_wlan_exit);
+
+MODULE_AUTHOR("Bjorge Dijkstra");
+MODULE_AUTHOR("Jussi Kivilinna");
+MODULE_DESCRIPTION("Driver for RNDIS based USB Wireless adapters");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index ab52f221cd7..b31f0c26c32 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1736,7 +1736,8 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
WARNING(rt2x00dev,
"TX status report missed for entry %p\n",
entry_done);
- rt2x00lib_txdone(entry_done, TX_FAIL_OTHER, 0);
+ rt2x00pci_txdone(rt2x00dev, entry_done, TX_FAIL_OTHER,
+ 0);
entry_done = rt2x00_get_data_entry_done(ring);
}
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index 07f37b0ccf9..27ebd689aa2 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -36,6 +36,7 @@ MODULE_LICENSE("GPL");
static struct pci_device_id rtl8180_table[] __devinitdata = {
/* rtl8185 */
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x700f) },
{ PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x701f) },
/* rtl8180 */
diff --git a/include/asm-alpha/socket.h b/include/asm-alpha/socket.h
index 1fede7f9286..08c97931992 100644
--- a/include/asm-alpha/socket.h
+++ b/include/asm-alpha/socket.h
@@ -60,4 +60,6 @@
#define SO_SECURITY_ENCRYPTION_TRANSPORT 20
#define SO_SECURITY_ENCRYPTION_NETWORK 21
+#define SO_MARK 36
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-arm/socket.h b/include/asm-arm/socket.h
index 65a1a64bf93..6817be9573a 100644
--- a/include/asm-arm/socket.h
+++ b/include/asm-arm/socket.h
@@ -52,4 +52,6 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-avr32/socket.h b/include/asm-avr32/socket.h
index a0d0507a503..35863f26092 100644
--- a/include/asm-avr32/socket.h
+++ b/include/asm-avr32/socket.h
@@ -52,4 +52,6 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* __ASM_AVR32_SOCKET_H */
diff --git a/include/asm-blackfin/socket.h b/include/asm-blackfin/socket.h
index 5213c965218..2ca702e44d4 100644
--- a/include/asm-blackfin/socket.h
+++ b/include/asm-blackfin/socket.h
@@ -50,4 +50,7 @@
#define SO_PASSSEC 34
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+
+#define SO_MARK 36
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-cris/socket.h b/include/asm-cris/socket.h
index 5b18dfdf174..9df0ca82f5d 100644
--- a/include/asm-cris/socket.h
+++ b/include/asm-cris/socket.h
@@ -54,6 +54,8 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-frv/socket.h b/include/asm-frv/socket.h
index a823befd11d..e51ca67b935 100644
--- a/include/asm-frv/socket.h
+++ b/include/asm-frv/socket.h
@@ -52,5 +52,7 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-h8300/socket.h b/include/asm-h8300/socket.h
index 39911d8c968..da2520dbf25 100644
--- a/include/asm-h8300/socket.h
+++ b/include/asm-h8300/socket.h
@@ -52,4 +52,6 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-ia64/socket.h b/include/asm-ia64/socket.h
index 9e42ce43cfb..d5ef0aa3e31 100644
--- a/include/asm-ia64/socket.h
+++ b/include/asm-ia64/socket.h
@@ -61,4 +61,6 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* _ASM_IA64_SOCKET_H */
diff --git a/include/asm-m32r/socket.h b/include/asm-m32r/socket.h
index 793d5d30c85..9a0e2001222 100644
--- a/include/asm-m32r/socket.h
+++ b/include/asm-m32r/socket.h
@@ -52,4 +52,6 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* _ASM_M32R_SOCKET_H */
diff --git a/include/asm-m68k/socket.h b/include/asm-m68k/socket.h
index 6d21b90863a..dbc64e92c41 100644
--- a/include/asm-m68k/socket.h
+++ b/include/asm-m68k/socket.h
@@ -52,4 +52,6 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-mips/socket.h b/include/asm-mips/socket.h
index 95945689b1c..63f60254d30 100644
--- a/include/asm-mips/socket.h
+++ b/include/asm-mips/socket.h
@@ -73,6 +73,8 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#ifdef __KERNEL__
/** sock_type - Socket types
diff --git a/include/asm-parisc/socket.h b/include/asm-parisc/socket.h
index 99e868f6a8f..69a7a0d30b0 100644
--- a/include/asm-parisc/socket.h
+++ b/include/asm-parisc/socket.h
@@ -52,4 +52,6 @@
#define SO_PEERSEC 0x401d
#define SO_PASSSEC 0x401e
+#define SO_MARK 0x401f
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-powerpc/socket.h b/include/asm-powerpc/socket.h
index 403e9fde2eb..f5a4e168e49 100644
--- a/include/asm-powerpc/socket.h
+++ b/include/asm-powerpc/socket.h
@@ -59,4 +59,6 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* _ASM_POWERPC_SOCKET_H */
diff --git a/include/asm-s390/socket.h b/include/asm-s390/socket.h
index 1161ebe3dec..c786ab623b2 100644
--- a/include/asm-s390/socket.h
+++ b/include/asm-s390/socket.h
@@ -60,4 +60,6 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-sh/socket.h b/include/asm-sh/socket.h
index c48d6fc9da3..6d4bf651295 100644
--- a/include/asm-sh/socket.h
+++ b/include/asm-sh/socket.h
@@ -52,4 +52,6 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* __ASM_SH_SOCKET_H */
diff --git a/include/asm-sparc/socket.h b/include/asm-sparc/socket.h
index 7c1423997cf..2e2bd0b7c8e 100644
--- a/include/asm-sparc/socket.h
+++ b/include/asm-sparc/socket.h
@@ -52,6 +52,8 @@
#define SO_TIMESTAMPNS 0x0021
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 0x0022
+
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
diff --git a/include/asm-sparc64/socket.h b/include/asm-sparc64/socket.h
index 986441dcb8f..44a625af6e3 100644
--- a/include/asm-sparc64/socket.h
+++ b/include/asm-sparc64/socket.h
@@ -57,4 +57,5 @@
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
#define SO_SECURITY_ENCRYPTION_NETWORK 0x5004
+#define SO_MARK 0x0022
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-v850/socket.h b/include/asm-v850/socket.h
index a4c2493b025..e199a2bf12a 100644
--- a/include/asm-v850/socket.h
+++ b/include/asm-v850/socket.h
@@ -52,4 +52,6 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* __V850_SOCKET_H__ */
diff --git a/include/asm-x86/socket.h b/include/asm-x86/socket.h
index 99ca648b94c..80af9c4ccad 100644
--- a/include/asm-x86/socket.h
+++ b/include/asm-x86/socket.h
@@ -52,4 +52,6 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-xtensa/socket.h b/include/asm-xtensa/socket.h
index 1f5aeacb9da..6100682b1da 100644
--- a/include/asm-xtensa/socket.h
+++ b/include/asm-xtensa/socket.h
@@ -63,4 +63,6 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* _XTENSA_SOCKET_H */
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index 8d9eaaebded..fc4e3db649e 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -17,8 +17,6 @@ struct ipv4_devconf
DECLARE_BITMAP(state, __NET_IPV4_CONF_MAX - 1);
};
-extern struct ipv4_devconf ipv4_devconf;
-
struct in_device
{
struct net_device *dev;
diff --git a/include/linux/input.h b/include/linux/input.h
index 2075d6da2a3..056a17a4f34 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -371,6 +371,8 @@ struct input_absinfo {
#define KEY_BRIGHTNESS_ZERO 244 /* brightness off, use ambient */
#define KEY_DISPLAY_OFF 245 /* display device to off state */
+#define KEY_WIMAX 246
+
#define BTN_MISC 0x100
#define BTN_0 0x100
#define BTN_1 0x101
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 5d35a4cc3bf..4aaefc349a4 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -457,14 +457,22 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk)
#define inet_v6_ipv6only(__sk) 0
#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-#define INET6_MATCH(__sk, __hash, __saddr, __daddr, __ports, __dif)\
- (((__sk)->sk_hash == (__hash)) && \
+#define INET6_MATCH(__sk, __net, __hash, __saddr, __daddr, __ports, __dif)\
+ (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \
((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \
((__sk)->sk_family == AF_INET6) && \
ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr)) && \
ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
+#define INET6_TW_MATCH(__sk, __net, __hash, __saddr, __daddr, __ports, __dif) \
+ (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \
+ (*((__portpair *)&(inet_twsk(__sk)->tw_dport)) == (__ports)) && \
+ ((__sk)->sk_family == PF_INET6) && \
+ (ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_daddr, (__saddr))) && \
+ (ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_rcv_saddr, (__daddr))) && \
+ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
+
#endif /* __KERNEL__ */
#endif /* _IPV6_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b0813c3286b..047d432bde5 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1414,12 +1414,16 @@ extern void dev_set_rx_mode(struct net_device *dev);
extern void __dev_set_rx_mode(struct net_device *dev);
extern int dev_unicast_delete(struct net_device *dev, void *addr, int alen);
extern int dev_unicast_add(struct net_device *dev, void *addr, int alen);
+extern int dev_unicast_sync(struct net_device *to, struct net_device *from);
+extern void dev_unicast_unsync(struct net_device *to, struct net_device *from);
extern int dev_mc_delete(struct net_device *dev, void *addr, int alen, int all);
extern int dev_mc_add(struct net_device *dev, void *addr, int alen, int newonly);
extern int dev_mc_sync(struct net_device *to, struct net_device *from);
extern void dev_mc_unsync(struct net_device *to, struct net_device *from);
extern int __dev_addr_delete(struct dev_addr_list **list, int *count, void *addr, int alen, int all);
extern int __dev_addr_add(struct dev_addr_list **list, int *count, void *addr, int alen, int newonly);
+extern int __dev_addr_sync(struct dev_addr_list **to, int *to_count, struct dev_addr_list **from, int *from_count);
+extern void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, struct dev_addr_list **from, int *from_count);
extern void dev_set_promiscuity(struct net_device *dev, int inc);
extern void dev_set_allmulti(struct net_device *dev, int inc);
extern void netdev_state_change(struct net_device *dev);
diff --git a/include/linux/netfilter/nf_conntrack_pptp.h b/include/linux/netfilter/nf_conntrack_pptp.h
index 23435496d24..3bbde0c3a8a 100644
--- a/include/linux/netfilter/nf_conntrack_pptp.h
+++ b/include/linux/netfilter/nf_conntrack_pptp.h
@@ -4,7 +4,7 @@
#include <linux/netfilter/nf_conntrack_common.h>
-extern const char *pptp_msg_name[];
+extern const char *const pptp_msg_name[];
/* state of the control session */
enum pptp_ctrlsess_state {
diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h
index 9fff19779bd..8e5ce1ca7bf 100644
--- a/include/linux/netfilter/nf_conntrack_sip.h
+++ b/include/linux/netfilter/nf_conntrack_sip.h
@@ -30,9 +30,9 @@ extern unsigned int (*nf_nat_sdp_hook)(struct sk_buff *skb,
struct nf_conntrack_expect *exp,
const char *dptr);
-extern int ct_sip_get_info(struct nf_conn *ct, const char *dptr, size_t dlen,
- unsigned int *matchoff, unsigned int *matchlen,
- enum sip_header_pos pos);
+extern int ct_sip_get_info(const struct nf_conn *ct, const char *dptr,
+ size_t dlen, unsigned int *matchoff,
+ unsigned int *matchlen, enum sip_header_pos pos);
extern int ct_sip_lnlen(const char *line, const char *limit);
extern const char *ct_sip_search(const char *needle, const char *haystack,
size_t needle_len, size_t haystack_len,
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index b99ede51318..b2c62cc618f 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -214,7 +214,7 @@ struct xt_match
/* Free to use by each match */
unsigned long data;
- char *table;
+ const char *table;
unsigned int matchsize;
unsigned int compatsize;
unsigned int hooks;
@@ -261,7 +261,7 @@ struct xt_target
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;
- char *table;
+ const char *table;
unsigned int targetsize;
unsigned int compatsize;
unsigned int hooks;
@@ -277,7 +277,7 @@ struct xt_table
struct list_head list;
/* A unique name... */
- char name[XT_TABLE_MAXNAMELEN];
+ const char name[XT_TABLE_MAXNAMELEN];
/* What hooks you will enter on */
unsigned int valid_hooks;
@@ -335,9 +335,10 @@ extern int xt_check_target(const struct xt_target *target, unsigned short family
unsigned int size, const char *table, unsigned int hook,
unsigned short proto, int inv_proto);
-extern int xt_register_table(struct xt_table *table,
- struct xt_table_info *bootstrap,
- struct xt_table_info *newinfo);
+extern struct xt_table *xt_register_table(struct net *net,
+ struct xt_table *table,
+ struct xt_table_info *bootstrap,
+ struct xt_table_info *newinfo);
extern void *xt_unregister_table(struct xt_table *table);
extern struct xt_table_info *xt_replace_table(struct xt_table *table,
@@ -352,11 +353,12 @@ extern struct xt_target *xt_request_find_target(int af, const char *name,
extern int xt_find_revision(int af, const char *name, u8 revision, int target,
int *err);
-extern struct xt_table *xt_find_table_lock(int af, const char *name);
+extern struct xt_table *xt_find_table_lock(struct net *net, int af,
+ const char *name);
extern void xt_table_unlock(struct xt_table *t);
-extern int xt_proto_init(int af);
-extern void xt_proto_fini(int af);
+extern int xt_proto_init(struct net *net, int af);
+extern void xt_proto_fini(struct net *net, int af);
extern struct xt_table_info *xt_alloc_table_info(unsigned int size);
extern void xt_free_table_info(struct xt_table_info *info);
@@ -430,15 +432,15 @@ extern short xt_compat_calc_jump(int af, unsigned int offset);
extern int xt_compat_match_offset(struct xt_match *match);
extern int xt_compat_match_from_user(struct xt_entry_match *m,
- void **dstptr, int *size);
+ void **dstptr, unsigned int *size);
extern int xt_compat_match_to_user(struct xt_entry_match *m,
- void __user **dstptr, int *size);
+ void __user **dstptr, unsigned int *size);
extern int xt_compat_target_offset(struct xt_target *target);
extern void xt_compat_target_from_user(struct xt_entry_target *t,
- void **dstptr, int *size);
+ void **dstptr, unsigned int *size);
extern int xt_compat_target_to_user(struct xt_entry_target *t,
- void __user **dstptr, int *size);
+ void __user **dstptr, unsigned int *size);
#endif /* CONFIG_COMPAT */
#endif /* __KERNEL__ */
diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h
index d2492a3329b..f3fd83e46ba 100644
--- a/include/linux/netfilter/xt_conntrack.h
+++ b/include/linux/netfilter/xt_conntrack.h
@@ -6,9 +6,6 @@
#define _XT_CONNTRACK_H
#include <linux/netfilter/nf_conntrack_tuple_common.h>
-#ifdef __KERNEL__
-# include <linux/in.h>
-#endif
#define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
#define XT_CONNTRACK_STATE_INVALID (1 << 0)
@@ -18,14 +15,21 @@
#define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
/* flags, invflags: */
-#define XT_CONNTRACK_STATE 0x01
-#define XT_CONNTRACK_PROTO 0x02
-#define XT_CONNTRACK_ORIGSRC 0x04
-#define XT_CONNTRACK_ORIGDST 0x08
-#define XT_CONNTRACK_REPLSRC 0x10
-#define XT_CONNTRACK_REPLDST 0x20
-#define XT_CONNTRACK_STATUS 0x40
-#define XT_CONNTRACK_EXPIRES 0x80
+enum {
+ XT_CONNTRACK_STATE = 1 << 0,
+ XT_CONNTRACK_PROTO = 1 << 1,
+ XT_CONNTRACK_ORIGSRC = 1 << 2,
+ XT_CONNTRACK_ORIGDST = 1 << 3,
+ XT_CONNTRACK_REPLSRC = 1 << 4,
+ XT_CONNTRACK_REPLDST = 1 << 5,
+ XT_CONNTRACK_STATUS = 1 << 6,
+ XT_CONNTRACK_EXPIRES = 1 << 7,
+ XT_CONNTRACK_ORIGSRC_PORT = 1 << 8,
+ XT_CONNTRACK_ORIGDST_PORT = 1 << 9,
+ XT_CONNTRACK_REPLSRC_PORT = 1 << 10,
+ XT_CONNTRACK_REPLDST_PORT = 1 << 11,
+ XT_CONNTRACK_DIRECTION = 1 << 12,
+};
/* This is exposed to userspace, so remains frozen in time. */
struct ip_conntrack_old_tuple
@@ -70,8 +74,10 @@ struct xt_conntrack_mtinfo1 {
union nf_inet_addr repldst_addr, repldst_mask;
u_int32_t expires_min, expires_max;
u_int16_t l4proto;
+ __be16 origsrc_port, origdst_port;
+ __be16 replsrc_port, repldst_port;
+ u_int16_t match_flags, invert_flags;
u_int8_t state_mask, status_mask;
- u_int8_t match_flags, invert_flags;
};
#endif /*_XT_CONNTRACK_H*/
diff --git a/include/linux/netfilter/xt_hashlimit.h b/include/linux/netfilter/xt_hashlimit.h
index c19972e4564..58b818ee41c 100644
--- a/include/linux/netfilter/xt_hashlimit.h
+++ b/include/linux/netfilter/xt_hashlimit.h
@@ -9,13 +9,16 @@
/* details of this structure hidden by the implementation */
struct xt_hashlimit_htable;
-#define XT_HASHLIMIT_HASH_DIP 0x0001
-#define XT_HASHLIMIT_HASH_DPT 0x0002
-#define XT_HASHLIMIT_HASH_SIP 0x0004
-#define XT_HASHLIMIT_HASH_SPT 0x0008
+enum {
+ XT_HASHLIMIT_HASH_DIP = 1 << 0,
+ XT_HASHLIMIT_HASH_DPT = 1 << 1,
+ XT_HASHLIMIT_HASH_SIP = 1 << 2,
+ XT_HASHLIMIT_HASH_SPT = 1 << 3,
+ XT_HASHLIMIT_INVERT = 1 << 4,
+};
struct hashlimit_cfg {
- u_int32_t mode; /* bitmask of IPT_HASHLIMIT_HASH_* */
+ u_int32_t mode; /* bitmask of XT_HASHLIMIT_HASH_* */
u_int32_t avg; /* Average secs between packets * scale */
u_int32_t burst; /* Period multiplier for upper limit. */
@@ -37,4 +40,28 @@ struct xt_hashlimit_info {
struct xt_hashlimit_info *master;
} u;
};
+
+struct hashlimit_cfg1 {
+ u_int32_t mode; /* bitmask of XT_HASHLIMIT_HASH_* */
+ u_int32_t avg; /* Average secs between packets * scale */
+ u_int32_t burst; /* Period multiplier for upper limit. */
+
+ /* user specified */
+ u_int32_t size; /* how many buckets */
+ u_int32_t max; /* max number of entries */
+ u_int32_t gc_interval; /* gc interval */
+ u_int32_t expire; /* when do entries expire? */
+
+ u_int8_t srcmask, dstmask;
+};
+
+struct xt_hashlimit_mtinfo1 {
+ char name[IFNAMSIZ];
+ struct hashlimit_cfg1 cfg;
+
+ /* Used internally by the kernel */
+ struct xt_hashlimit_htable *hinfo __attribute__((aligned(8)));
+ struct xt_hashlimit_mtinfo1 *master __attribute__((aligned(8)));
+};
+
#endif /*_XT_HASHLIMIT_H*/
diff --git a/include/linux/netfilter/xt_owner.h b/include/linux/netfilter/xt_owner.h
index eacd34efebd..c84e52cfe41 100644
--- a/include/linux/netfilter/xt_owner.h
+++ b/include/linux/netfilter/xt_owner.h
@@ -8,8 +8,8 @@ enum {
};
struct xt_owner_match_info {
- u_int32_t uid;
- u_int32_t gid;
+ u_int32_t uid_min, uid_max;
+ u_int32_t gid_min, gid_max;
u_int8_t match, invert;
};
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
index 53dd4df27aa..db223ca92c8 100644
--- a/include/linux/netfilter_arp/arp_tables.h
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -271,8 +271,9 @@ struct arpt_error
xt_register_target(tgt); })
#define arpt_unregister_target(tgt) xt_unregister_target(tgt)
-extern int arpt_register_table(struct arpt_table *table,
- const struct arpt_replace *repl);
+extern struct arpt_table *arpt_register_table(struct net *net,
+ 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 *skb,
unsigned int hook,
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index 45fcad91e67..bfc889f9027 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -244,8 +244,9 @@ ipt_get_target(struct ipt_entry *e)
#include <linux/init.h>
extern void ipt_init(void) __init;
-extern int ipt_register_table(struct xt_table *table,
- const struct ipt_replace *repl);
+extern struct xt_table *ipt_register_table(struct net *net,
+ struct xt_table *table,
+ const struct ipt_replace *repl);
extern void ipt_unregister_table(struct xt_table *table);
/* Standard entry. */
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 110801d699e..f2507dcc575 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -305,8 +305,9 @@ ip6t_get_target(struct ip6t_entry *e)
#include <linux/init.h>
extern void ip6t_init(void) __init;
-extern int ip6t_register_table(struct xt_table *table,
- const struct ip6t_replace *repl);
+extern struct xt_table *ip6t_register_table(struct net *net,
+ 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 *skb,
unsigned int hook,
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index bd13b6f4a98..fb0713b6ffa 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -219,7 +219,7 @@ struct netlink_callback
int (*dump)(struct sk_buff * skb, struct netlink_callback *cb);
int (*done)(struct netlink_callback *cb);
int family;
- long args[5];
+ long args[6];
};
struct netlink_notify
diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h
index d9db5f62ee4..6db69ff5d83 100644
--- a/include/linux/pfkeyv2.h
+++ b/include/linux/pfkeyv2.h
@@ -298,6 +298,12 @@ struct sadb_x_sec_ctx {
#define SADB_X_EALG_BLOWFISHCBC 7
#define SADB_EALG_NULL 11
#define SADB_X_EALG_AESCBC 12
+#define SADB_X_EALG_AES_CCM_ICV8 14
+#define SADB_X_EALG_AES_CCM_ICV12 15
+#define SADB_X_EALG_AES_CCM_ICV16 16
+#define SADB_X_EALG_AES_GCM_ICV8 18
+#define SADB_X_EALG_AES_GCM_ICV12 19
+#define SADB_X_EALG_AES_GCM_ICV16 20
#define SADB_X_EALG_CAMELLIACBC 22
#define SADB_EALG_MAX 253 /* last EALG */
/* private allocations should use 249-255 (RFC2407) */
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index 30b8571e6b3..1c1dba9ea5f 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -328,6 +328,56 @@ enum
#define TCA_TCINDEX_MAX (__TCA_TCINDEX_MAX - 1)
+/* Flow filter */
+
+enum
+{
+ FLOW_KEY_SRC,
+ FLOW_KEY_DST,
+ FLOW_KEY_PROTO,
+ FLOW_KEY_PROTO_SRC,
+ FLOW_KEY_PROTO_DST,
+ FLOW_KEY_IIF,
+ FLOW_KEY_PRIORITY,
+ FLOW_KEY_MARK,
+ FLOW_KEY_NFCT,
+ FLOW_KEY_NFCT_SRC,
+ FLOW_KEY_NFCT_DST,
+ FLOW_KEY_NFCT_PROTO_SRC,
+ FLOW_KEY_NFCT_PROTO_DST,
+ FLOW_KEY_RTCLASSID,
+ FLOW_KEY_SKUID,
+ FLOW_KEY_SKGID,
+ __FLOW_KEY_MAX,
+};
+
+#define FLOW_KEY_MAX (__FLOW_KEY_MAX - 1)
+
+enum
+{
+ FLOW_MODE_MAP,
+ FLOW_MODE_HASH,
+};
+
+enum
+{
+ TCA_FLOW_UNSPEC,
+ TCA_FLOW_KEYS,
+ TCA_FLOW_MODE,
+ TCA_FLOW_BASECLASS,
+ TCA_FLOW_RSHIFT,
+ TCA_FLOW_ADDEND,
+ TCA_FLOW_MASK,
+ TCA_FLOW_XOR,
+ TCA_FLOW_DIVISOR,
+ TCA_FLOW_ACT,
+ TCA_FLOW_POLICE,
+ TCA_FLOW_EMATCHES,
+ __TCA_FLOW_MAX
+};
+
+#define TCA_FLOW_MAX (__TCA_FLOW_MAX - 1)
+
/* Basic filter */
enum
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index 32761352e85..dbb7ac37960 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -150,6 +150,11 @@ struct tc_sfq_qopt
unsigned flows; /* Maximal number of flows */
};
+struct tc_sfq_xstats
+{
+ __s32 allot;
+};
+
/*
* NOTE: limit, divisor and flows are hardwired to code at the moment.
*
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 0ce5e0b52db..e3ab21d7fc7 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -33,11 +33,13 @@
* RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
* RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
* RFKILL_TYPE_UWB: switch is on a ultra wideband device.
+ * RFKILL_TYPE_WIMAX: switch is on a WiMAX device.
*/
enum rfkill_type {
RFKILL_TYPE_WLAN ,
RFKILL_TYPE_BLUETOOTH,
RFKILL_TYPE_UWB,
+ RFKILL_TYPE_WIMAX,
RFKILL_TYPE_MAX,
};
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c618fbf7d17..dfe975a9967 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -108,9 +108,6 @@ struct nf_bridge_info {
atomic_t use;
struct net_device *physindev;
struct net_device *physoutdev;
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
- struct net_device *netoutdev;
-#endif
unsigned int mask;
unsigned long data[32 / sizeof(unsigned long)];
};
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index 86d3effb283..5df62ef1280 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -227,7 +227,7 @@ enum
LINUX_MIB_XFRMINNOSTATES, /* XfrmInNoStates */
LINUX_MIB_XFRMINSTATEPROTOERROR, /* XfrmInStateProtoError */
LINUX_MIB_XFRMINSTATEMODEERROR, /* XfrmInStateModeError */
- LINUX_MIB_XFRMINSEQOUTOFWINDOW, /* XfrmInSeqOutOfWindow */
+ LINUX_MIB_XFRMINSTATESEQERROR, /* XfrmInStateSeqError */
LINUX_MIB_XFRMINSTATEEXPIRED, /* XfrmInStateExpired */
LINUX_MIB_XFRMINSTATEMISMATCH, /* XfrmInStateMismatch */
LINUX_MIB_XFRMINSTATEINVALID, /* XfrmInStateInvalid */
@@ -241,6 +241,7 @@ enum
LINUX_MIB_XFRMOUTNOSTATES, /* XfrmOutNoStates */
LINUX_MIB_XFRMOUTSTATEPROTOERROR, /* XfrmOutStateProtoError */
LINUX_MIB_XFRMOUTSTATEMODEERROR, /* XfrmOutStateModeError */
+ LINUX_MIB_XFRMOUTSTATESEQERROR, /* XfrmOutStateSeqError */
LINUX_MIB_XFRMOUTSTATEEXPIRED, /* XfrmOutStateExpired */
LINUX_MIB_XFRMOUTPOLBLOCK, /* XfrmOutPolBlock */
LINUX_MIB_XFRMOUTPOLDEAD, /* XfrmOutPolDead */
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 89faebfe48b..bf4ae4e138f 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -440,8 +440,8 @@ enum
enum {
NET_IPV4_ROUTE_FLUSH=1,
- NET_IPV4_ROUTE_MIN_DELAY=2,
- NET_IPV4_ROUTE_MAX_DELAY=3,
+ NET_IPV4_ROUTE_MIN_DELAY=2, /* obsolete since 2.6.25 */
+ NET_IPV4_ROUTE_MAX_DELAY=3, /* obsolete since 2.6.25 */
NET_IPV4_ROUTE_GC_THRESH=4,
NET_IPV4_ROUTE_MAX_SIZE=5,
NET_IPV4_ROUTE_GC_MIN_INTERVAL=6,
diff --git a/include/linux/types.h b/include/linux/types.h
index f4f8d19158e..b94c0e4efe2 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -126,7 +126,7 @@ typedef __s64 int64_t;
#endif
/* this is a special 64bit data type that is 8-byte aligned */
-#define aligned_u64 unsigned long long __attribute__((aligned(8)))
+#define aligned_u64 __u64 __attribute__((aligned(8)))
#define aligned_be64 __be64 __attribute__((aligned(8)))
#define aligned_le64 __le64 __attribute__((aligned(8)))
diff --git a/include/linux/usb/rndis_host.h b/include/linux/usb/rndis_host.h
new file mode 100644
index 00000000000..edc1d4a0e27
--- /dev/null
+++ b/include/linux/usb/rndis_host.h
@@ -0,0 +1,274 @@
+/*
+ * Host Side support for RNDIS Networking Links
+ * Copyright (C) 2005 by David Brownell
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef __RNDIS_HOST_H
+#define __RNDIS_HOST_H
+
+
+/*
+ * CONTROL uses CDC "encapsulated commands" with funky notifications.
+ * - control-out: SEND_ENCAPSULATED
+ * - interrupt-in: RESPONSE_AVAILABLE
+ * - control-in: GET_ENCAPSULATED
+ *
+ * We'll try to ignore the RESPONSE_AVAILABLE notifications.
+ *
+ * REVISIT some RNDIS implementations seem to have curious issues still
+ * to be resolved.
+ */
+struct rndis_msg_hdr {
+ __le32 msg_type; /* RNDIS_MSG_* */
+ __le32 msg_len;
+ // followed by data that varies between messages
+ __le32 request_id;
+ __le32 status;
+ // ... and more
+} __attribute__ ((packed));
+
+/* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */
+#define CONTROL_BUFFER_SIZE 1025
+
+/* RNDIS defines an (absurdly huge) 10 second control timeout,
+ * but ActiveSync seems to use a more usual 5 second timeout
+ * (which matches the USB 2.0 spec).
+ */
+#define RNDIS_CONTROL_TIMEOUT_MS (5 * 1000)
+
+
+#define ccpu2 __constant_cpu_to_le32
+
+#define RNDIS_MSG_COMPLETION ccpu2(0x80000000)
+
+/* codes for "msg_type" field of rndis messages;
+ * only the data channel uses packet messages (maybe batched);
+ * everything else goes on the control channel.
+ */
+#define RNDIS_MSG_PACKET ccpu2(0x00000001) /* 1-N packets */
+#define RNDIS_MSG_INIT ccpu2(0x00000002)
+#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_HALT ccpu2(0x00000003)
+#define RNDIS_MSG_QUERY ccpu2(0x00000004)
+#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_SET ccpu2(0x00000005)
+#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_RESET ccpu2(0x00000006)
+#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_INDICATE ccpu2(0x00000007)
+#define RNDIS_MSG_KEEPALIVE ccpu2(0x00000008)
+#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION)
+
+/* codes for "status" field of completion messages */
+#define RNDIS_STATUS_SUCCESS ccpu2(0x00000000)
+#define RNDIS_STATUS_FAILURE ccpu2(0xc0000001)
+#define RNDIS_STATUS_INVALID_DATA ccpu2(0xc0010015)
+#define RNDIS_STATUS_NOT_SUPPORTED ccpu2(0xc00000bb)
+#define RNDIS_STATUS_MEDIA_CONNECT ccpu2(0x4001000b)
+#define RNDIS_STATUS_MEDIA_DISCONNECT ccpu2(0x4001000c)
+
+/* codes for OID_GEN_PHYSICAL_MEDIUM */
+#define RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED ccpu2(0x00000000)
+#define RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN ccpu2(0x00000001)
+#define RNDIS_PHYSICAL_MEDIUM_CABLE_MODEM ccpu2(0x00000002)
+#define RNDIS_PHYSICAL_MEDIUM_PHONE_LINE ccpu2(0x00000003)
+#define RNDIS_PHYSICAL_MEDIUM_POWER_LINE ccpu2(0x00000004)
+#define RNDIS_PHYSICAL_MEDIUM_DSL ccpu2(0x00000005)
+#define RNDIS_PHYSICAL_MEDIUM_FIBRE_CHANNEL ccpu2(0x00000006)
+#define RNDIS_PHYSICAL_MEDIUM_1394 ccpu2(0x00000007)
+#define RNDIS_PHYSICAL_MEDIUM_WIRELESS_WAN ccpu2(0x00000008)
+#define RNDIS_PHYSICAL_MEDIUM_MAX ccpu2(0x00000009)
+
+struct rndis_data_hdr {
+ __le32 msg_type; /* RNDIS_MSG_PACKET */
+ __le32 msg_len; // rndis_data_hdr + data_len + pad
+ __le32 data_offset; // 36 -- right after header
+ __le32 data_len; // ... real packet size
+
+ __le32 oob_data_offset; // zero
+ __le32 oob_data_len; // zero
+ __le32 num_oob; // zero
+ __le32 packet_data_offset; // zero
+
+ __le32 packet_data_len; // zero
+ __le32 vc_handle; // zero
+ __le32 reserved; // zero
+} __attribute__ ((packed));
+
+struct rndis_init { /* OUT */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_INIT */
+ __le32 msg_len; // 24
+ __le32 request_id;
+ __le32 major_version; // of rndis (1.0)
+ __le32 minor_version;
+ __le32 max_transfer_size;
+} __attribute__ ((packed));
+
+struct rndis_init_c { /* IN */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_INIT_C */
+ __le32 msg_len;
+ __le32 request_id;
+ __le32 status;
+ __le32 major_version; // of rndis (1.0)
+ __le32 minor_version;
+ __le32 device_flags;
+ __le32 medium; // zero == 802.3
+ __le32 max_packets_per_message;
+ __le32 max_transfer_size;
+ __le32 packet_alignment; // max 7; (1<<n) bytes
+ __le32 af_list_offset; // zero
+ __le32 af_list_size; // zero
+} __attribute__ ((packed));
+
+struct rndis_halt { /* OUT (no reply) */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_HALT */
+ __le32 msg_len;
+ __le32 request_id;
+} __attribute__ ((packed));
+
+struct rndis_query { /* OUT */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_QUERY */
+ __le32 msg_len;
+ __le32 request_id;
+ __le32 oid;
+ __le32 len;
+ __le32 offset;
+/*?*/ __le32 handle; // zero
+} __attribute__ ((packed));
+
+struct rndis_query_c { /* IN */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_QUERY_C */
+ __le32 msg_len;
+ __le32 request_id;
+ __le32 status;
+ __le32 len;
+ __le32 offset;
+} __attribute__ ((packed));
+
+struct rndis_set { /* OUT */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_SET */
+ __le32 msg_len;
+ __le32 request_id;
+ __le32 oid;
+ __le32 len;
+ __le32 offset;
+/*?*/ __le32 handle; // zero
+} __attribute__ ((packed));
+
+struct rndis_set_c { /* IN */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_SET_C */
+ __le32 msg_len;
+ __le32 request_id;
+ __le32 status;
+} __attribute__ ((packed));
+
+struct rndis_reset { /* IN */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_RESET */
+ __le32 msg_len;
+ __le32 reserved;
+} __attribute__ ((packed));
+
+struct rndis_reset_c { /* OUT */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_RESET_C */
+ __le32 msg_len;
+ __le32 status;
+ __le32 addressing_lost;
+} __attribute__ ((packed));
+
+struct rndis_indicate { /* IN (unrequested) */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_INDICATE */
+ __le32 msg_len;
+ __le32 status;
+ __le32 length;
+ __le32 offset;
+/**/ __le32 diag_status;
+ __le32 error_offset;
+/**/ __le32 message;
+} __attribute__ ((packed));
+
+struct rndis_keepalive { /* OUT (optionally IN) */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_KEEPALIVE */
+ __le32 msg_len;
+ __le32 request_id;
+} __attribute__ ((packed));
+
+struct rndis_keepalive_c { /* IN (optionally OUT) */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_KEEPALIVE_C */
+ __le32 msg_len;
+ __le32 request_id;
+ __le32 status;
+} __attribute__ ((packed));
+
+/* NOTE: about 30 OIDs are "mandatory" for peripherals to support ... and
+ * there are gobs more that may optionally be supported. We'll avoid as much
+ * of that mess as possible.
+ */
+#define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101)
+#define OID_GEN_MAXIMUM_FRAME_SIZE ccpu2(0x00010106)
+#define OID_GEN_CURRENT_PACKET_FILTER ccpu2(0x0001010e)
+#define OID_GEN_PHYSICAL_MEDIUM ccpu2(0x00010202)
+
+/* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */
+#define RNDIS_PACKET_TYPE_DIRECTED ccpu2(0x00000001)
+#define RNDIS_PACKET_TYPE_MULTICAST ccpu2(0x00000002)
+#define RNDIS_PACKET_TYPE_ALL_MULTICAST ccpu2(0x00000004)
+#define RNDIS_PACKET_TYPE_BROADCAST ccpu2(0x00000008)
+#define RNDIS_PACKET_TYPE_SOURCE_ROUTING ccpu2(0x00000010)
+#define RNDIS_PACKET_TYPE_PROMISCUOUS ccpu2(0x00000020)
+#define RNDIS_PACKET_TYPE_SMT ccpu2(0x00000040)
+#define RNDIS_PACKET_TYPE_ALL_LOCAL ccpu2(0x00000080)
+#define RNDIS_PACKET_TYPE_GROUP ccpu2(0x00001000)
+#define RNDIS_PACKET_TYPE_ALL_FUNCTIONAL ccpu2(0x00002000)
+#define RNDIS_PACKET_TYPE_FUNCTIONAL ccpu2(0x00004000)
+#define RNDIS_PACKET_TYPE_MAC_FRAME ccpu2(0x00008000)
+
+/* default filter used with RNDIS devices */
+#define RNDIS_DEFAULT_FILTER ( \
+ RNDIS_PACKET_TYPE_DIRECTED | \
+ RNDIS_PACKET_TYPE_BROADCAST | \
+ RNDIS_PACKET_TYPE_ALL_MULTICAST | \
+ RNDIS_PACKET_TYPE_PROMISCUOUS)
+
+/* Flags to require specific physical medium type for generic_rndis_bind() */
+#define FLAG_RNDIS_PHYM_NOT_WIRELESS 0x0001
+#define FLAG_RNDIS_PHYM_WIRELESS 0x0002
+
+
+extern void rndis_status(struct usbnet *dev, struct urb *urb);
+extern int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf);
+extern int
+generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags);
+extern void rndis_unbind(struct usbnet *dev, struct usb_interface *intf);
+extern int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb);
+extern struct sk_buff *
+rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags);
+
+#endif /* __RNDIS_HOST_H */
+
diff --git a/drivers/net/usb/usbnet.h b/include/linux/usb/usbnet.h
index 1fae4347e83..e0501da3dd1 100644
--- a/drivers/net/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -31,6 +31,7 @@ struct usbnet {
struct usb_interface *intf;
struct driver_info *driver_info;
const char *driver_name;
+ void *driver_priv;
wait_queue_head_t *wait;
struct mutex phy_mutex;
unsigned char suspend_count;
@@ -87,6 +88,8 @@ struct driver_info {
#define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */
#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
+#define FLAG_WLAN 0x0080 /* use "wlan%d" names */
+
/* init device ... can sleep, or cause probe() failure */
int (*bind)(struct usbnet *, struct usb_interface *);
@@ -113,6 +116,15 @@ struct driver_info {
struct sk_buff *(*tx_fixup)(struct usbnet *dev,
struct sk_buff *skb, gfp_t flags);
+ /* early initialization code, can sleep. This is for minidrivers
+ * having 'subminidrivers' that need to do extra initialization
+ * right after minidriver have initialized hardware. */
+ int (*early_init)(struct usbnet *dev);
+
+ /* called by minidriver when link state changes, state: 0=disconnect,
+ * 1=connect */
+ void (*link_change)(struct usbnet *dev, int state);
+
/* for new devices, use the descriptor-reading code instead */
int in; /* rx endpoint */
int out; /* tx endpoint */
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index 9b5b00c4ef9..e31b8c84f2c 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -96,6 +96,13 @@ struct xfrm_algo {
char alg_key[0];
};
+struct xfrm_algo_aead {
+ char alg_name[64];
+ int alg_key_len; /* in bits */
+ int alg_icv_len; /* in bits */
+ char alg_key[0];
+};
+
struct xfrm_stats {
__u32 replay_window;
__u32 replay;
@@ -270,6 +277,7 @@ enum xfrm_attr_type_t {
XFRMA_LASTUSED,
XFRMA_POLICY_TYPE, /* struct xfrm_userpolicy_type */
XFRMA_MIGRATE,
+ XFRMA_ALG_AEAD, /* struct xfrm_algo_aead */
__XFRMA_MAX
#define XFRMA_MAX (__XFRMA_MAX - 1)
diff --git a/include/net/arp.h b/include/net/arp.h
index 752eb47b267..c236270ec95 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -13,15 +13,17 @@ extern int arp_find(unsigned char *haddr, struct sk_buff *skb);
extern int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg);
extern void arp_send(int type, int ptype, __be32 dest_ip,
struct net_device *dev, __be32 src_ip,
- unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th);
+ const unsigned char *dest_hw,
+ const unsigned char *src_hw, const unsigned char *th);
extern int arp_bind_neighbour(struct dst_entry *dst);
extern int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir);
extern void arp_ifdown(struct net_device *dev);
extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
struct net_device *dev, __be32 src_ip,
- unsigned char *dest_hw, unsigned char *src_hw,
- unsigned char *target_hw);
+ const unsigned char *dest_hw,
+ const unsigned char *src_hw,
+ const unsigned char *target_hw);
extern void arp_xmit(struct sk_buff *skb);
extern struct neigh_ops arp_broken_ops;
diff --git a/include/net/esp.h b/include/net/esp.h
index c05f529bff2..d58451331db 100644
--- a/include/net/esp.h
+++ b/include/net/esp.h
@@ -1,58 +1,20 @@
#ifndef _NET_ESP_H
#define _NET_ESP_H
-#include <linux/crypto.h>
-#include <net/xfrm.h>
-#include <linux/scatterlist.h>
+#include <linux/skbuff.h>
-#define ESP_NUM_FAST_SG 4
+struct crypto_aead;
-struct esp_data
-{
- struct scatterlist sgbuf[ESP_NUM_FAST_SG];
-
- /* Confidentiality */
- struct {
- int padlen; /* 0..255 */
- /* ivlen is offset from enc_data, where encrypted data start.
- * It is logically different of crypto_tfm_alg_ivsize(tfm).
- * We assume that it is either zero (no ivec), or
- * >= crypto_tfm_alg_ivsize(tfm). */
- int ivlen;
- int ivinitted;
- u8 *ivec; /* ivec buffer */
- struct crypto_blkcipher *tfm; /* crypto handle */
- } conf;
-
- /* Integrity. It is active when icv_full_len != 0 */
- struct {
- u8 *work_icv;
- int icv_full_len;
- int icv_trunc_len;
- struct crypto_hash *tfm;
- } auth;
+struct esp_data {
+ /* 0..255 */
+ int padlen;
+
+ /* Confidentiality & Integrity */
+ struct crypto_aead *aead;
};
extern void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len);
-static inline int esp_mac_digest(struct esp_data *esp, struct sk_buff *skb,
- int offset, int len)
-{
- struct hash_desc desc;
- int err;
-
- desc.tfm = esp->auth.tfm;
- desc.flags = 0;
-
- err = crypto_hash_init(&desc);
- if (unlikely(err))
- return err;
- err = skb_icv_walk(skb, &desc, offset, len, crypto_hash_update);
- if (unlikely(err))
- return err;
- return crypto_hash_final(&desc, esp->auth.work_icv);
-}
-
struct ip_esp_hdr;
static inline struct ip_esp_hdr *ip_esp_hdr(const struct sk_buff *skb)
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
index 668056b4bb0..fdff630708c 100644
--- a/include/net/inet6_hashtables.h
+++ b/include/net/inet6_hashtables.h
@@ -57,34 +57,37 @@ extern void __inet6_hash(struct inet_hashinfo *hashinfo, struct sock *sk);
*
* The sockhash lock must be held as a reader here.
*/
-extern struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
+extern struct sock *__inet6_lookup_established(struct net *net,
+ struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr,
const __be16 sport,
const struct in6_addr *daddr,
const u16 hnum,
const int dif);
-extern struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
+extern struct sock *inet6_lookup_listener(struct net *net,
+ struct inet_hashinfo *hashinfo,
const struct in6_addr *daddr,
const unsigned short hnum,
const int dif);
-static inline struct sock *__inet6_lookup(struct inet_hashinfo *hashinfo,
+static inline struct sock *__inet6_lookup(struct net *net,
+ struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr,
const __be16 sport,
const struct in6_addr *daddr,
const u16 hnum,
const int dif)
{
- struct sock *sk = __inet6_lookup_established(hashinfo, saddr, sport,
- daddr, hnum, dif);
+ struct sock *sk = __inet6_lookup_established(net, hashinfo, saddr,
+ sport, daddr, hnum, dif);
if (sk)
return sk;
- return inet6_lookup_listener(hashinfo, daddr, hnum, dif);
+ return inet6_lookup_listener(net, hashinfo, daddr, hnum, dif);
}
-extern struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
+extern struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr, const __be16 sport,
const struct in6_addr *daddr, const __be16 dport,
const int dif);
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 761bdc01425..c23c4ed3072 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -74,6 +74,7 @@ struct inet_ehash_bucket {
* ports are created in O(1) time? I thought so. ;-) -DaveM
*/
struct inet_bind_bucket {
+ struct net *ib_net;
unsigned short port;
signed short fastreuse;
struct hlist_node node;
@@ -194,6 +195,7 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
extern struct inet_bind_bucket *
inet_bind_bucket_create(struct kmem_cache *cachep,
+ struct net *net,
struct inet_bind_hashbucket *head,
const unsigned short snum);
extern void inet_bind_bucket_destroy(struct kmem_cache *cachep,
@@ -300,15 +302,17 @@ out:
wake_up(&hashinfo->lhash_wait);
}
-extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
+extern struct sock *__inet_lookup_listener(struct net *net,
+ struct inet_hashinfo *hashinfo,
const __be32 daddr,
const unsigned short hnum,
const int dif);
-static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo,
- __be32 daddr, __be16 dport, int dif)
+static inline struct sock *inet_lookup_listener(struct net *net,
+ struct inet_hashinfo *hashinfo,
+ __be32 daddr, __be16 dport, int dif)
{
- return __inet_lookup_listener(hashinfo, daddr, ntohs(dport), dif);
+ return __inet_lookup_listener(net, hashinfo, daddr, ntohs(dport), dif);
}
/* Socket demux engine toys. */
@@ -342,26 +346,26 @@ typedef __u64 __bitwise __addrpair;
(((__force __u64)(__be32)(__daddr)) << 32) | \
((__force __u64)(__be32)(__saddr)));
#endif /* __BIG_ENDIAN */
-#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
- (((__sk)->sk_hash == (__hash)) && \
+#define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
+ (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \
((*((__addrpair *)&(inet_sk(__sk)->daddr))) == (__cookie)) && \
((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
-#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
- (((__sk)->sk_hash == (__hash)) && \
+#define INET_TW_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
+ (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \
((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) && \
((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
#else /* 32-bit arch */
#define INET_ADDR_COOKIE(__name, __saddr, __daddr)
-#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif) \
- (((__sk)->sk_hash == (__hash)) && \
+#define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif) \
+ (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \
(inet_sk(__sk)->daddr == (__saddr)) && \
(inet_sk(__sk)->rcv_saddr == (__daddr)) && \
((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
-#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif) \
- (((__sk)->sk_hash == (__hash)) && \
+#define INET_TW_MATCH(__sk, __net, __hash,__cookie, __saddr, __daddr, __ports, __dif) \
+ (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \
(inet_twsk(__sk)->tw_daddr == (__saddr)) && \
(inet_twsk(__sk)->tw_rcv_saddr == (__daddr)) && \
((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
@@ -374,32 +378,36 @@ typedef __u64 __bitwise __addrpair;
*
* Local BH must be disabled here.
*/
-extern struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
+extern struct sock * __inet_lookup_established(struct net *net,
+ struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const u16 hnum, const int dif);
static inline struct sock *
- inet_lookup_established(struct inet_hashinfo *hashinfo,
+ inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const __be16 dport,
const int dif)
{
- return __inet_lookup_established(hashinfo, saddr, sport, daddr,
+ return __inet_lookup_established(net, hashinfo, saddr, sport, daddr,
ntohs(dport), dif);
}
-static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo,
+static inline struct sock *__inet_lookup(struct net *net,
+ struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const __be16 dport,
const int dif)
{
u16 hnum = ntohs(dport);
- struct sock *sk = __inet_lookup_established(hashinfo, saddr, sport, daddr,
- hnum, dif);
- return sk ? : __inet_lookup_listener(hashinfo, daddr, hnum, dif);
+ struct sock *sk = __inet_lookup_established(net, hashinfo,
+ saddr, sport, daddr, hnum, dif);
+
+ return sk ? : __inet_lookup_listener(net, hashinfo, daddr, hnum, dif);
}
-static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
+static inline struct sock *inet_lookup(struct net *net,
+ struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const __be16 dport,
const int dif)
@@ -407,12 +415,17 @@ static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
struct sock *sk;
local_bh_disable();
- sk = __inet_lookup(hashinfo, saddr, sport, daddr, dport, dif);
+ sk = __inet_lookup(net, hashinfo, saddr, sport, daddr, dport, dif);
local_bh_enable();
return sk;
}
+extern int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+ struct sock *sk,
+ int (*check_established)(struct inet_timewait_death_row *,
+ struct sock *, __u16, struct inet_timewait_sock **),
+ void (*hash)(struct inet_hashinfo *, struct sock *));
extern int inet_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk);
#endif /* _INET_HASHTABLES_H */
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 9daa60b544b..90d1175f63d 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -69,6 +69,7 @@ struct fib_nh {
struct fib_info {
struct hlist_node fib_hash;
struct hlist_node fib_lhash;
+ struct net *fib_net;
int fib_treeref;
atomic_t fib_clntref;
int fib_dead;
@@ -218,7 +219,8 @@ extern void fib_select_default(struct net *net, const struct flowi *flp,
/* Exported by fib_semantics.c */
extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
-extern int fib_sync_down(__be32 local, struct net_device *dev, int force);
+extern int fib_sync_down_dev(struct net_device *dev, int force);
+extern int fib_sync_down_addr(struct net *net, __be32 local);
extern int fib_sync_up(struct net_device *dev);
extern __be32 __fib_res_prefsrc(struct fib_result *res);
extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index b8c1d60ba9e..28738b7d53e 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -12,6 +12,7 @@
#include <net/netns/packet.h>
#include <net/netns/ipv4.h>
#include <net/netns/ipv6.h>
+#include <net/netns/x_tables.h>
struct proc_dir_entry;
struct net_device;
@@ -56,6 +57,9 @@ struct net {
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct netns_ipv6 ipv6;
#endif
+#ifdef CONFIG_NETFILTER
+ struct netns_xt xt;
+#endif
};
#ifdef CONFIG_NET
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 857d8995179..90b3e7f5df5 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -129,6 +129,8 @@ struct nf_conn
/* Extensions */
struct nf_ct_ext *ext;
+
+ struct rcu_head rcu;
};
static inline struct nf_conn *
@@ -143,7 +145,7 @@ nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash)
/* Alter reply tuple (maybe alter helper). */
extern void
-nf_conntrack_alter_reply(struct nf_conn *conntrack,
+nf_conntrack_alter_reply(struct nf_conn *ct,
const struct nf_conntrack_tuple *newreply);
/* Is this tuple taken? (ignoring any belonging to the given
@@ -171,13 +173,12 @@ static inline void nf_ct_put(struct nf_conn *ct)
extern int nf_ct_l3proto_try_module_get(unsigned short l3proto);
extern void nf_ct_l3proto_module_put(unsigned short l3proto);
-extern struct hlist_head *nf_ct_alloc_hashtable(int *sizep, int *vmalloced);
+extern struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced);
extern void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced,
- int size);
+ unsigned int size);
extern struct nf_conntrack_tuple_hash *
-__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
- const struct nf_conn *ignored_conntrack);
+__nf_conntrack_find(const struct nf_conntrack_tuple *tuple);
extern void nf_conntrack_hash_insert(struct nf_conn *ct);
@@ -215,9 +216,9 @@ static inline void nf_ct_refresh(struct nf_conn *ct,
/* These are for NAT. Icky. */
/* Update TCP window tracking data when NAT mangles the packet */
-extern void nf_conntrack_tcp_update(struct sk_buff *skb,
+extern void nf_conntrack_tcp_update(const struct sk_buff *skb,
unsigned int dataoff,
- struct nf_conn *conntrack,
+ struct nf_conn *ct,
int dir);
/* Fake conntrack entry for untracked connections */
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index 7ad0828f05c..9ee26469c75 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -68,11 +68,11 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb)
int
print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
- struct nf_conntrack_l3proto *l3proto,
- struct nf_conntrack_l4proto *proto);
+ const struct nf_conntrack_l3proto *l3proto,
+ const struct nf_conntrack_l4proto *proto);
extern struct hlist_head *nf_conntrack_hash;
-extern rwlock_t nf_conntrack_lock ;
+extern spinlock_t nf_conntrack_lock ;
extern struct hlist_head unconfirmed;
#endif /* _NF_CONNTRACK_CORE_H */
diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h
index 6c3fd254c28..cb608a1b44e 100644
--- a/include/net/netfilter/nf_conntrack_expect.h
+++ b/include/net/netfilter/nf_conntrack_expect.h
@@ -49,6 +49,8 @@ struct nf_conntrack_expect
/* Direction relative to the master connection. */
enum ip_conntrack_dir dir;
#endif
+
+ struct rcu_head rcu;
};
#define NF_CT_EXPECT_PERMANENT 0x1
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index 2f3af00643c..4ca125e9b3c 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -43,12 +43,8 @@ extern struct nf_conntrack_helper *
__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple);
extern struct nf_conntrack_helper *
-nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple);
-
-extern struct nf_conntrack_helper *
__nf_conntrack_helper_find_byname(const char *name);
-extern void nf_ct_helper_put(struct nf_conntrack_helper *helper);
extern int nf_conntrack_helper_register(struct nf_conntrack_helper *);
extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index d5526bcce14..b886e3ae6ca 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -43,7 +43,7 @@ struct nf_conntrack_l3proto
const struct nf_conntrack_tuple *);
/* Returns verdict for packet, or -1 for invalid. */
- int (*packet)(struct nf_conn *conntrack,
+ int (*packet)(struct nf_conn *ct,
const struct sk_buff *skb,
enum ip_conntrack_info ctinfo);
@@ -51,7 +51,7 @@ struct nf_conntrack_l3proto
* Called when a new connection for this protocol found;
* returns TRUE if it's OK. If so, packet() called next.
*/
- int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb);
+ int (*new)(struct nf_conn *ct, const struct sk_buff *skb);
/*
* Called before tracking.
diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
index fb50c217ba0..efc16eccddb 100644
--- a/include/net/netfilter/nf_conntrack_l4proto.h
+++ b/include/net/netfilter/nf_conntrack_l4proto.h
@@ -23,9 +23,6 @@ struct nf_conntrack_l4proto
/* L4 Protocol number. */
u_int8_t l4proto;
- /* Protocol name */
- const char *name;
-
/* Try to fill in the third arg: dataoff is offset past network protocol
hdr. Return true if possible. */
int (*pkt_to_tuple)(const struct sk_buff *skb,
@@ -38,15 +35,8 @@ struct nf_conntrack_l4proto
int (*invert_tuple)(struct nf_conntrack_tuple *inverse,
const struct nf_conntrack_tuple *orig);
- /* Print out the per-protocol part of the tuple. Return like seq_* */
- int (*print_tuple)(struct seq_file *s,
- const struct nf_conntrack_tuple *);
-
- /* Print out the private part of the conntrack. */
- int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
-
/* Returns verdict for packet, or -1 for invalid. */
- int (*packet)(struct nf_conn *conntrack,
+ int (*packet)(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
@@ -55,16 +45,23 @@ struct nf_conntrack_l4proto
/* Called when a new connection for this protocol found;
* returns TRUE if it's OK. If so, packet() called next. */
- int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb,
+ int (*new)(struct nf_conn *ct, const struct sk_buff *skb,
unsigned int dataoff);
/* Called when a conntrack entry is destroyed */
- void (*destroy)(struct nf_conn *conntrack);
+ void (*destroy)(struct nf_conn *ct);
int (*error)(struct sk_buff *skb, unsigned int dataoff,
enum ip_conntrack_info *ctinfo,
int pf, unsigned int hooknum);
+ /* Print out the per-protocol part of the tuple. Return like seq_* */
+ int (*print_tuple)(struct seq_file *s,
+ const struct nf_conntrack_tuple *);
+
+ /* Print out the private part of the conntrack. */
+ int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
+
/* convert protoinfo to nfnetink attributes */
int (*to_nlattr)(struct sk_buff *skb, struct nlattr *nla,
const struct nf_conn *ct);
@@ -87,6 +84,8 @@ struct nf_conntrack_l4proto
struct ctl_table *ctl_compat_table;
#endif
#endif
+ /* Protocol name */
+ const char *name;
/* Module (if any) which this is connected to. */
struct module *me;
diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h
index 45cb17cdcfd..e69ab2e8759 100644
--- a/include/net/netfilter/nf_conntrack_tuple.h
+++ b/include/net/netfilter/nf_conntrack_tuple.h
@@ -132,34 +132,33 @@ struct nf_conntrack_tuple_hash
#endif /* __KERNEL__ */
-static inline int nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1,
- const struct nf_conntrack_tuple *t2)
+static inline int __nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1,
+ const struct nf_conntrack_tuple *t2)
{
return (t1->src.u3.all[0] == t2->src.u3.all[0] &&
t1->src.u3.all[1] == t2->src.u3.all[1] &&
t1->src.u3.all[2] == t2->src.u3.all[2] &&
t1->src.u3.all[3] == t2->src.u3.all[3] &&
t1->src.u.all == t2->src.u.all &&
- t1->src.l3num == t2->src.l3num &&
- t1->dst.protonum == t2->dst.protonum);
+ t1->src.l3num == t2->src.l3num);
}
-static inline int nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1,
- const struct nf_conntrack_tuple *t2)
+static inline int __nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1,
+ const struct nf_conntrack_tuple *t2)
{
return (t1->dst.u3.all[0] == t2->dst.u3.all[0] &&
t1->dst.u3.all[1] == t2->dst.u3.all[1] &&
t1->dst.u3.all[2] == t2->dst.u3.all[2] &&
t1->dst.u3.all[3] == t2->dst.u3.all[3] &&
t1->dst.u.all == t2->dst.u.all &&
- t1->src.l3num == t2->src.l3num &&
t1->dst.protonum == t2->dst.protonum);
}
static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1,
const struct nf_conntrack_tuple *t2)
{
- return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2);
+ return __nf_ct_tuple_src_equal(t1, t2) &&
+ __nf_ct_tuple_dst_equal(t1, t2);
}
static inline int nf_ct_tuple_mask_equal(const struct nf_conntrack_tuple_mask *m1,
@@ -199,7 +198,7 @@ static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
const struct nf_conntrack_tuple_mask *mask)
{
return nf_ct_tuple_src_mask_cmp(t, tuple, mask) &&
- nf_ct_tuple_dst_equal(t, tuple);
+ __nf_ct_tuple_dst_equal(t, tuple);
}
#endif /* _NF_CONNTRACK_TUPLE_H */
diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h
index 037e82403f9..8c6b5ae4553 100644
--- a/include/net/netfilter/nf_log.h
+++ b/include/net/netfilter/nf_log.h
@@ -54,6 +54,6 @@ void nf_log_packet(int pf,
const struct net_device *in,
const struct net_device *out,
const struct nf_loginfo *li,
- const char *fmt, ...);
+ const char *fmt, ...) __attribute__ ((format(printf,7,8)));
#endif /* _NF_LOG_H */
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 15a0b052df2..a9b4f608629 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -27,5 +27,11 @@ struct netns_ipv4 {
struct sock *fibnl;
struct netns_frags frags;
+#ifdef CONFIG_NETFILTER
+ struct xt_table *iptable_filter;
+ struct xt_table *iptable_mangle;
+ struct xt_table *iptable_raw;
+ struct xt_table *arptable_filter;
+#endif
};
#endif
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 187c4248df2..1dd7de4e419 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -31,5 +31,10 @@ struct netns_ipv6 {
struct ipv6_devconf *devconf_all;
struct ipv6_devconf *devconf_dflt;
struct netns_frags frags;
+#ifdef CONFIG_NETFILTER
+ struct xt_table *ip6table_filter;
+ struct xt_table *ip6table_mangle;
+ struct xt_table *ip6table_raw;
+#endif
};
#endif
diff --git a/include/net/netns/x_tables.h b/include/net/netns/x_tables.h
new file mode 100644
index 00000000000..0cb63ed2c1f
--- /dev/null
+++ b/include/net/netns/x_tables.h
@@ -0,0 +1,10 @@
+#ifndef __NETNS_X_TABLES_H
+#define __NETNS_X_TABLES_H
+
+#include <linux/list.h>
+#include <linux/net.h>
+
+struct netns_xt {
+ struct list_head tables[NPROTO];
+};
+#endif
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 8716eb757d5..d349c66ef82 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -131,14 +131,14 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
extern int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
struct nlattr *rate_tlv, struct tcf_exts *exts,
- struct tcf_ext_map *map);
+ const struct tcf_ext_map *map);
extern void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts);
extern void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
struct tcf_exts *src);
extern int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
- struct tcf_ext_map *map);
+ const struct tcf_ext_map *map);
extern int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
- struct tcf_ext_map *map);
+ const struct tcf_ext_map *map);
/**
* struct tcf_pkt_info - packet information
diff --git a/include/net/raw.h b/include/net/raw.h
index cca81d8b2d8..1828f81fe37 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -41,7 +41,6 @@ extern void raw_proc_exit(void);
struct raw_iter_state {
struct seq_net_private p;
int bucket;
- unsigned short family;
struct raw_hashinfo *h;
};
@@ -49,8 +48,8 @@ struct raw_iter_state {
void *raw_seq_start(struct seq_file *seq, loff_t *pos);
void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos);
void raw_seq_stop(struct seq_file *seq, void *v);
-int raw_seq_open(struct inode *ino, struct file *file, struct raw_hashinfo *h,
- unsigned short family);
+int raw_seq_open(struct inode *ino, struct file *file,
+ struct raw_hashinfo *h, const struct seq_operations *ops);
#endif
diff --git a/include/net/route.h b/include/net/route.h
index 4eabf008413..eadad590142 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -27,6 +27,7 @@
#include <net/dst.h>
#include <net/inetpeer.h>
#include <net/flow.h>
+#include <net/sock.h>
#include <linux/in_route.h>
#include <linux/rtnetlink.h>
#include <linux/route.h>
@@ -61,6 +62,7 @@ struct rtable
struct in_device *idev;
+ int rt_genid;
unsigned rt_flags;
__u16 rt_type;
@@ -149,6 +151,7 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
int flags)
{
struct flowi fl = { .oif = oif,
+ .mark = sk->sk_mark,
.nl_u = { .ip4_u = { .daddr = dst,
.saddr = src,
.tos = tos } },
diff --git a/include/net/sock.h b/include/net/sock.h
index 902324488d0..e3fb4c047f4 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -262,6 +262,8 @@ struct sock {
__u32 sk_sndmsg_off;
int sk_write_pending;
void *sk_security;
+ __u32 sk_mark;
+ /* XXX 4 bytes hole on 64 bit */
void (*sk_state_change)(struct sock *sk);
void (*sk_data_ready)(struct sock *sk, int bytes);
void (*sk_write_space)(struct sock *sk);
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 5ebb9ba479b..ac72116636c 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -159,6 +159,7 @@ struct xfrm_state
struct xfrm_algo *aalg;
struct xfrm_algo *ealg;
struct xfrm_algo *calg;
+ struct xfrm_algo_aead *aead;
/* Data for encapsulator */
struct xfrm_encap_tmpl *encap;
@@ -201,7 +202,7 @@ struct xfrm_state
/* Reference to data common to all the instances of this
* transformer. */
- struct xfrm_type *type;
+ const struct xfrm_type *type;
struct xfrm_mode *inner_mode;
struct xfrm_mode *outer_mode;
@@ -278,7 +279,7 @@ struct xfrm_state_afinfo {
unsigned int proto;
unsigned int eth_proto;
struct module *owner;
- struct xfrm_type *type_map[IPPROTO_MAX];
+ const struct xfrm_type *type_map[IPPROTO_MAX];
struct xfrm_mode *mode_map[XFRM_MODE_MAX];
int (*init_flags)(struct xfrm_state *x);
void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
@@ -321,8 +322,8 @@ struct xfrm_type
u32 (*get_mtu)(struct xfrm_state *, int size);
};
-extern int xfrm_register_type(struct xfrm_type *type, unsigned short family);
-extern int xfrm_unregister_type(struct xfrm_type *type, unsigned short family);
+extern int xfrm_register_type(const struct xfrm_type *type, unsigned short family);
+extern int xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);
struct xfrm_mode {
/*
@@ -1108,6 +1109,10 @@ static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
/*
* xfrm algorithm information
*/
+struct xfrm_algo_aead_info {
+ u16 icv_truncbits;
+};
+
struct xfrm_algo_auth_info {
u16 icv_truncbits;
u16 icv_fullbits;
@@ -1127,6 +1132,7 @@ struct xfrm_algo_desc {
char *compat;
u8 available:1;
union {
+ struct xfrm_algo_aead_info aead;
struct xfrm_algo_auth_info auth;
struct xfrm_algo_encr_info encr;
struct xfrm_algo_comp_info comp;
@@ -1343,6 +1349,8 @@ extern struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
extern struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe);
extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe);
extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe);
+extern struct xfrm_algo_desc *xfrm_aead_get_byname(char *name, int icv_len,
+ int probe);
struct hash_desc;
struct scatterlist;
diff --git a/kernel/audit.c b/kernel/audit.c
index f93c2713017..801c946dd24 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1200,13 +1200,17 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
static inline int audit_expand(struct audit_buffer *ab, int extra)
{
struct sk_buff *skb = ab->skb;
- int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
- ab->gfp_mask);
+ int oldtail = skb_tailroom(skb);
+ int ret = pskb_expand_head(skb, 0, extra, ab->gfp_mask);
+ int newtail = skb_tailroom(skb);
+
if (ret < 0) {
audit_log_lost("out of memory in audit_expand");
return 0;
}
- return skb_tailroom(skb);
+
+ skb->truesize += newtail - oldtail;
+ return newtail;
}
/*
diff --git a/net/802/tr.c b/net/802/tr.c
index 3f16b172055..18c66475d8c 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -76,7 +76,7 @@ static DEFINE_SPINLOCK(rif_lock);
static struct timer_list rif_timer;
-int sysctl_tr_rif_timeout = 60*10*HZ;
+static int sysctl_tr_rif_timeout = 60*10*HZ;
static inline unsigned long rif_hash(const unsigned char *addr)
{
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 8059fa42b08..77f04e49a1a 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -563,6 +563,7 @@ static int vlan_dev_stop(struct net_device *dev)
struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
dev_mc_unsync(real_dev, dev);
+ dev_unicast_unsync(real_dev, dev);
if (dev->flags & IFF_ALLMULTI)
dev_set_allmulti(real_dev, -1);
if (dev->flags & IFF_PROMISC)
@@ -634,9 +635,10 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
dev_set_promiscuity(real_dev, dev->flags & IFF_PROMISC ? 1 : -1);
}
-static void vlan_dev_set_multicast_list(struct net_device *vlan_dev)
+static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
{
dev_mc_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev);
+ dev_unicast_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev);
}
/*
@@ -702,7 +704,8 @@ void vlan_setup(struct net_device *dev)
dev->open = vlan_dev_open;
dev->stop = vlan_dev_stop;
dev->set_mac_address = vlan_dev_set_mac_address;
- dev->set_multicast_list = vlan_dev_set_multicast_list;
+ dev->set_rx_mode = vlan_dev_set_rx_mode;
+ dev->set_multicast_list = vlan_dev_set_rx_mode;
dev->change_rx_flags = vlan_dev_change_rx_flags;
dev->do_ioctl = vlan_dev_ioctl;
dev->destructor = free_netdev;
diff --git a/net/9p/conv.c b/net/9p/conv.c
index aa2aa9884f9..3fe35d532c8 100644
--- a/net/9p/conv.c
+++ b/net/9p/conv.c
@@ -128,11 +128,6 @@ static char *buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
return ret;
}
-static inline void buf_put_string(struct cbuf *buf, const char *s)
-{
- buf_put_stringn(buf, s, strlen(s));
-}
-
static u8 buf_get_int8(struct cbuf *buf)
{
u8 ret = 0;
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 1bc0e85f04a..8fc64e3150a 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1037,16 +1037,13 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
int err = 0;
if (addr_len != sizeof(struct sockaddr_ax25) &&
- addr_len != sizeof(struct full_sockaddr_ax25)) {
- /* support for old structure may go away some time */
+ addr_len != sizeof(struct full_sockaddr_ax25))
+ /* support for old structure may go away some time
+ * ax25_bind(): uses old (6 digipeater) socket structure.
+ */
if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
- (addr_len > sizeof(struct full_sockaddr_ax25))) {
+ (addr_len > sizeof(struct full_sockaddr_ax25)))
return -EINVAL;
- }
-
- printk(KERN_WARNING "ax25_bind(): %s uses old (6 digipeater) socket structure.\n",
- current->comm);
- }
if (addr->fsa_ax25.sax25_family != AF_AX25)
return -EINVAL;
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 17f7fb72055..e13cf5ef144 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -12,6 +12,8 @@
#undef BT_DBG
#define BT_DBG(D...)
#endif
+static struct workqueue_struct *btaddconn;
+static struct workqueue_struct *btdelconn;
static inline char *typetostr(int type)
{
@@ -279,6 +281,8 @@ static void add_conn(struct work_struct *work)
struct hci_conn *conn = container_of(work, struct hci_conn, work);
int i;
+ flush_workqueue(btdelconn);
+
if (device_add(&conn->dev) < 0) {
BT_ERR("Failed to register connection device");
return;
@@ -313,7 +317,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
INIT_WORK(&conn->work, add_conn);
- schedule_work(&conn->work);
+ queue_work(btaddconn, &conn->work);
}
static int __match_tty(struct device *dev, void *data)
@@ -349,7 +353,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
INIT_WORK(&conn->work, del_conn);
- schedule_work(&conn->work);
+ queue_work(btdelconn, &conn->work);
}
int hci_register_sysfs(struct hci_dev *hdev)
@@ -398,28 +402,54 @@ int __init bt_sysfs_init(void)
{
int err;
+ btaddconn = create_singlethread_workqueue("btaddconn");
+ if (!btaddconn) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ btdelconn = create_singlethread_workqueue("btdelconn");
+ if (!btdelconn) {
+ err = -ENOMEM;
+ goto out_del;
+ }
+
bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0);
- if (IS_ERR(bt_platform))
- return PTR_ERR(bt_platform);
+ if (IS_ERR(bt_platform)) {
+ err = PTR_ERR(bt_platform);
+ goto out_platform;
+ }
err = bus_register(&bt_bus);
- if (err < 0) {
- platform_device_unregister(bt_platform);
- return err;
- }
+ if (err < 0)
+ goto out_bus;
bt_class = class_create(THIS_MODULE, "bluetooth");
if (IS_ERR(bt_class)) {
- bus_unregister(&bt_bus);
- platform_device_unregister(bt_platform);
- return PTR_ERR(bt_class);
+ err = PTR_ERR(bt_class);
+ goto out_class;
}
return 0;
+
+out_class:
+ bus_unregister(&bt_bus);
+out_bus:
+ platform_device_unregister(bt_platform);
+out_platform:
+ destroy_workqueue(btdelconn);
+out_del:
+ destroy_workqueue(btaddconn);
+out:
+ return err;
}
void bt_sysfs_cleanup(void)
{
+ destroy_workqueue(btaddconn);
+
+ destroy_workqueue(btdelconn);
+
class_destroy(bt_class);
bus_unregister(&bt_bus);
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 80014bab81b..1c0efd8ad9f 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -828,10 +828,6 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
nf_bridge_pull_encap_header(skb);
nf_bridge_save_header(skb);
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
- if (nf_bridge->netoutdev)
- realoutdev = nf_bridge->netoutdev;
-#endif
NF_HOOK(pf, NF_INET_POST_ROUTING, skb, NULL, realoutdev,
br_nf_dev_queue_xmit);
diff --git a/net/bridge/netfilter/ebt_802_3.c b/net/bridge/netfilter/ebt_802_3.c
index 41a78072cd0..98534025360 100644
--- a/net/bridge/netfilter/ebt_802_3.c
+++ b/net/bridge/netfilter/ebt_802_3.c
@@ -15,8 +15,8 @@
static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *data, unsigned int datalen)
{
- struct ebt_802_3_info *info = (struct ebt_802_3_info *)data;
- struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb);
+ const struct ebt_802_3_info *info = data;
+ const struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb);
__be16 type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type;
if (info->bitmask & EBT_802_3_SAP) {
@@ -40,7 +40,7 @@ static struct ebt_match filter_802_3;
static int ebt_802_3_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_802_3_info *info = (struct ebt_802_3_info *)data;
+ const struct ebt_802_3_info *info = data;
if (datalen < sizeof(struct ebt_802_3_info))
return -EINVAL;
@@ -50,8 +50,7 @@ static int ebt_802_3_check(const char *tablename, unsigned int hookmask,
return 0;
}
-static struct ebt_match filter_802_3 =
-{
+static struct ebt_match filter_802_3 __read_mostly = {
.name = EBT_802_3_MATCH,
.match = ebt_filter_802_3,
.check = ebt_802_3_check,
@@ -70,4 +69,5 @@ static void __exit ebt_802_3_fini(void)
module_init(ebt_802_3_init);
module_exit(ebt_802_3_fini);
+MODULE_DESCRIPTION("Ebtables: DSAP/SSAP field and SNAP type matching");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_among.c b/net/bridge/netfilter/ebt_among.c
index 6436d30a550..70b6dca5ea7 100644
--- a/net/bridge/netfilter/ebt_among.c
+++ b/net/bridge/netfilter/ebt_among.c
@@ -25,7 +25,7 @@ static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
const struct ebt_mac_wormhash_tuple *p;
int start, limit, i;
uint32_t cmp[2] = { 0, 0 };
- int key = (const unsigned char) mac[5];
+ int key = ((const unsigned char *)mac)[5];
memcpy(((char *) cmp) + 2, mac, 6);
start = wh->table[key];
@@ -73,15 +73,18 @@ static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash
static int get_ip_dst(const struct sk_buff *skb, __be32 *addr)
{
if (eth_hdr(skb)->h_proto == htons(ETH_P_IP)) {
- struct iphdr _iph, *ih;
+ const struct iphdr *ih;
+ struct iphdr _iph;
ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
if (ih == NULL)
return -1;
*addr = ih->daddr;
} else if (eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
- struct arphdr _arph, *ah;
- __be32 buf, *bp;
+ const struct arphdr *ah;
+ struct arphdr _arph;
+ const __be32 *bp;
+ __be32 buf;
ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
if (ah == NULL ||
@@ -101,15 +104,18 @@ static int get_ip_dst(const struct sk_buff *skb, __be32 *addr)
static int get_ip_src(const struct sk_buff *skb, __be32 *addr)
{
if (eth_hdr(skb)->h_proto == htons(ETH_P_IP)) {
- struct iphdr _iph, *ih;
+ const struct iphdr *ih;
+ struct iphdr _iph;
ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
if (ih == NULL)
return -1;
*addr = ih->saddr;
} else if (eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
- struct arphdr _arph, *ah;
- __be32 buf, *bp;
+ const struct arphdr *ah;
+ struct arphdr _arph;
+ const __be32 *bp;
+ __be32 buf;
ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
if (ah == NULL ||
@@ -130,7 +136,7 @@ static int ebt_filter_among(const struct sk_buff *skb,
const struct net_device *out, const void *data,
unsigned int datalen)
{
- struct ebt_among_info *info = (struct ebt_among_info *) data;
+ const struct ebt_among_info *info = data;
const char *dmac, *smac;
const struct ebt_mac_wormhash *wh_dst, *wh_src;
__be32 dip = 0, sip = 0;
@@ -175,7 +181,7 @@ static int ebt_among_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data,
unsigned int datalen)
{
- struct ebt_among_info *info = (struct ebt_among_info *) data;
+ const struct ebt_among_info *info = data;
int expected_length = sizeof(struct ebt_among_info);
const struct ebt_mac_wormhash *wh_dst, *wh_src;
int err;
@@ -206,7 +212,7 @@ static int ebt_among_check(const char *tablename, unsigned int hookmask,
return 0;
}
-static struct ebt_match filter_among = {
+static struct ebt_match filter_among __read_mostly = {
.name = EBT_AMONG_MATCH,
.match = ebt_filter_among,
.check = ebt_among_check,
@@ -225,4 +231,5 @@ static void __exit ebt_among_fini(void)
module_init(ebt_among_init);
module_exit(ebt_among_fini);
+MODULE_DESCRIPTION("Ebtables: Combined MAC/IP address list matching");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_arp.c b/net/bridge/netfilter/ebt_arp.c
index 18141392a9b..7c535be7566 100644
--- a/net/bridge/netfilter/ebt_arp.c
+++ b/net/bridge/netfilter/ebt_arp.c
@@ -18,8 +18,9 @@
static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *data, unsigned int datalen)
{
- struct ebt_arp_info *info = (struct ebt_arp_info *)data;
- struct arphdr _arph, *ah;
+ const struct ebt_arp_info *info = data;
+ const struct arphdr *ah;
+ struct arphdr _arph;
ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
if (ah == NULL)
@@ -35,7 +36,8 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
return EBT_NOMATCH;
if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) {
- __be32 saddr, daddr, *sap, *dap;
+ const __be32 *sap, *dap;
+ __be32 saddr, daddr;
if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP))
return EBT_NOMATCH;
@@ -61,7 +63,8 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
}
if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) {
- unsigned char _mac[ETH_ALEN], *mp;
+ const unsigned char *mp;
+ unsigned char _mac[ETH_ALEN];
uint8_t verdict, i;
if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER))
@@ -100,7 +103,7 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
static int ebt_arp_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_arp_info *info = (struct ebt_arp_info *)data;
+ const struct ebt_arp_info *info = data;
if (datalen != EBT_ALIGN(sizeof(struct ebt_arp_info)))
return -EINVAL;
@@ -113,8 +116,7 @@ static int ebt_arp_check(const char *tablename, unsigned int hookmask,
return 0;
}
-static struct ebt_match filter_arp =
-{
+static struct ebt_match filter_arp __read_mostly = {
.name = EBT_ARP_MATCH,
.match = ebt_filter_arp,
.check = ebt_arp_check,
@@ -133,4 +135,5 @@ static void __exit ebt_arp_fini(void)
module_init(ebt_arp_init);
module_exit(ebt_arp_fini);
+MODULE_DESCRIPTION("Ebtables: ARP protocol packet match");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_arpreply.c b/net/bridge/netfilter/ebt_arpreply.c
index 48a80e42328..0c4279590fc 100644
--- a/net/bridge/netfilter/ebt_arpreply.c
+++ b/net/bridge/netfilter/ebt_arpreply.c
@@ -19,10 +19,13 @@ 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)
{
- struct ebt_arpreply_info *info = (struct ebt_arpreply_info *)data;
- __be32 _sip, *siptr, _dip, *diptr;
- struct arphdr _ah, *ap;
- unsigned char _sha[ETH_ALEN], *shp;
+ struct ebt_arpreply_info *info = (void *)data;
+ const __be32 *siptr, *diptr;
+ __be32 _sip, _dip;
+ const struct arphdr *ap;
+ struct arphdr _ah;
+ const unsigned char *shp;
+ unsigned char _sha[ETH_ALEN];
ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
if (ap == NULL)
@@ -58,7 +61,7 @@ static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr,
static int ebt_target_reply_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_arpreply_info *info = (struct ebt_arpreply_info *)data;
+ const struct ebt_arpreply_info *info = data;
if (datalen != EBT_ALIGN(sizeof(struct ebt_arpreply_info)))
return -EINVAL;
@@ -73,8 +76,7 @@ static int ebt_target_reply_check(const char *tablename, unsigned int hookmask,
return 0;
}
-static struct ebt_target reply_target =
-{
+static struct ebt_target reply_target __read_mostly = {
.name = EBT_ARPREPLY_TARGET,
.target = ebt_target_reply,
.check = ebt_target_reply_check,
@@ -93,4 +95,5 @@ static void __exit ebt_arpreply_fini(void)
module_init(ebt_arpreply_init);
module_exit(ebt_arpreply_fini);
+MODULE_DESCRIPTION("Ebtables: ARP reply target");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c
index 74262e9a566..e700cbf634c 100644
--- a/net/bridge/netfilter/ebt_dnat.c
+++ b/net/bridge/netfilter/ebt_dnat.c
@@ -18,7 +18,7 @@ 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;
+ const struct ebt_nat_info *info = data;
if (skb_make_writable(skb, 0))
return NF_DROP;
@@ -30,7 +30,7 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_nat_info *info = (struct ebt_nat_info *)data;
+ const struct ebt_nat_info *info = data;
if (BASE_CHAIN && info->target == EBT_RETURN)
return -EINVAL;
@@ -46,8 +46,7 @@ static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask,
return 0;
}
-static struct ebt_target dnat =
-{
+static struct ebt_target dnat __read_mostly = {
.name = EBT_DNAT_TARGET,
.target = ebt_target_dnat,
.check = ebt_target_dnat_check,
@@ -66,4 +65,5 @@ static void __exit ebt_dnat_fini(void)
module_init(ebt_dnat_init);
module_exit(ebt_dnat_fini);
+MODULE_DESCRIPTION("Ebtables: Destination MAC address translation");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c
index 69f7f0ab9c7..65caa00dcf2 100644
--- a/net/bridge/netfilter/ebt_ip.c
+++ b/net/bridge/netfilter/ebt_ip.c
@@ -28,9 +28,11 @@ static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *data,
unsigned int datalen)
{
- struct ebt_ip_info *info = (struct ebt_ip_info *)data;
- struct iphdr _iph, *ih;
- struct tcpudphdr _ports, *pptr;
+ const struct ebt_ip_info *info = data;
+ const struct iphdr *ih;
+ struct iphdr _iph;
+ const struct tcpudphdr *pptr;
+ struct tcpudphdr _ports;
ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
if (ih == NULL)
@@ -79,7 +81,7 @@ static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
static int ebt_ip_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_ip_info *info = (struct ebt_ip_info *)data;
+ const struct ebt_ip_info *info = data;
if (datalen != EBT_ALIGN(sizeof(struct ebt_ip_info)))
return -EINVAL;
@@ -105,8 +107,7 @@ static int ebt_ip_check(const char *tablename, unsigned int hookmask,
return 0;
}
-static struct ebt_match filter_ip =
-{
+static struct ebt_match filter_ip __read_mostly = {
.name = EBT_IP_MATCH,
.match = ebt_filter_ip,
.check = ebt_ip_check,
@@ -125,4 +126,5 @@ static void __exit ebt_ip_fini(void)
module_init(ebt_ip_init);
module_exit(ebt_ip_fini);
+MODULE_DESCRIPTION("Ebtables: IPv4 protocol packet match");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c
index d48fa5cb26c..8cbdc01c253 100644
--- a/net/bridge/netfilter/ebt_limit.c
+++ b/net/bridge/netfilter/ebt_limit.c
@@ -69,7 +69,7 @@ user2credits(u_int32_t user)
static int ebt_limit_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_limit_info *info = (struct ebt_limit_info *)data;
+ struct ebt_limit_info *info = data;
if (datalen != EBT_ALIGN(sizeof(struct ebt_limit_info)))
return -EINVAL;
@@ -90,8 +90,7 @@ static int ebt_limit_check(const char *tablename, unsigned int hookmask,
return 0;
}
-static struct ebt_match ebt_limit_reg =
-{
+static struct ebt_match ebt_limit_reg __read_mostly = {
.name = EBT_LIMIT_MATCH,
.match = ebt_limit_match,
.check = ebt_limit_check,
@@ -110,4 +109,5 @@ static void __exit ebt_limit_fini(void)
module_init(ebt_limit_init);
module_exit(ebt_limit_fini);
+MODULE_DESCRIPTION("Ebtables: Rate-limit match");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 3be9e989855..0b209e4aad0 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -24,7 +24,7 @@ static DEFINE_SPINLOCK(ebt_log_lock);
static int ebt_log_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_log_info *info = (struct ebt_log_info *)data;
+ struct ebt_log_info *info = data;
if (datalen != EBT_ALIGN(sizeof(struct ebt_log_info)))
return -EINVAL;
@@ -50,7 +50,7 @@ struct arppayload
unsigned char ip_dst[4];
};
-static void print_MAC(unsigned char *p)
+static void print_MAC(const unsigned char *p)
{
int i;
@@ -84,7 +84,8 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
if ((bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto ==
htons(ETH_P_IP)){
- struct iphdr _iph, *ih;
+ const struct iphdr *ih;
+ struct iphdr _iph;
ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
if (ih == NULL) {
@@ -99,7 +100,8 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
ih->protocol == IPPROTO_UDPLITE ||
ih->protocol == IPPROTO_SCTP ||
ih->protocol == IPPROTO_DCCP) {
- struct tcpudphdr _ports, *pptr;
+ const struct tcpudphdr *pptr;
+ struct tcpudphdr _ports;
pptr = skb_header_pointer(skb, ih->ihl*4,
sizeof(_ports), &_ports);
@@ -116,7 +118,8 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
if ((bitmask & EBT_LOG_ARP) &&
((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) ||
(eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) {
- struct arphdr _arph, *ah;
+ const struct arphdr *ah;
+ struct arphdr _arph;
ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
if (ah == NULL) {
@@ -132,7 +135,8 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
if (ah->ar_hrd == htons(1) &&
ah->ar_hln == ETH_ALEN &&
ah->ar_pln == sizeof(__be32)) {
- struct arppayload _arpp, *ap;
+ const struct arppayload *ap;
+ struct arppayload _arpp;
ap = skb_header_pointer(skb, sizeof(_arph),
sizeof(_arpp), &_arpp);
@@ -160,7 +164,7 @@ static void ebt_log(const 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_log_info *info = (struct ebt_log_info *)data;
+ const struct ebt_log_info *info = data;
struct nf_loginfo li;
li.type = NF_LOG_TYPE_LOG;
@@ -208,4 +212,5 @@ static void __exit ebt_log_fini(void)
module_init(ebt_log_init);
module_exit(ebt_log_fini);
+MODULE_DESCRIPTION("Ebtables: Packet logging to syslog");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_mark.c b/net/bridge/netfilter/ebt_mark.c
index 6cba54309c0..36723f47db0 100644
--- a/net/bridge/netfilter/ebt_mark.c
+++ b/net/bridge/netfilter/ebt_mark.c
@@ -21,7 +21,7 @@ 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)
{
- struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+ const struct ebt_mark_t_info *info = data;
int action = info->target & -16;
if (action == MARK_SET_VALUE)
@@ -39,7 +39,7 @@ static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr,
static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+ const struct ebt_mark_t_info *info = data;
int tmp;
if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
@@ -57,8 +57,7 @@ static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
return 0;
}
-static struct ebt_target mark_target =
-{
+static struct ebt_target mark_target __read_mostly = {
.name = EBT_MARK_TARGET,
.target = ebt_target_mark,
.check = ebt_target_mark_check,
@@ -77,4 +76,5 @@ static void __exit ebt_mark_fini(void)
module_init(ebt_mark_init);
module_exit(ebt_mark_fini);
+MODULE_DESCRIPTION("Ebtables: Packet mark modification");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_mark_m.c b/net/bridge/netfilter/ebt_mark_m.c
index 6b0d2169af7..9b0a4543861 100644
--- a/net/bridge/netfilter/ebt_mark_m.c
+++ b/net/bridge/netfilter/ebt_mark_m.c
@@ -16,7 +16,7 @@ static int ebt_filter_mark(const struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const void *data,
unsigned int datalen)
{
- struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data;
+ const struct ebt_mark_m_info *info = data;
if (info->bitmask & EBT_MARK_OR)
return !(!!(skb->mark & info->mask) ^ info->invert);
@@ -26,7 +26,7 @@ static int ebt_filter_mark(const struct sk_buff *skb,
static int ebt_mark_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data;
+ const struct ebt_mark_m_info *info = data;
if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_m_info)))
return -EINVAL;
@@ -39,8 +39,7 @@ static int ebt_mark_check(const char *tablename, unsigned int hookmask,
return 0;
}
-static struct ebt_match filter_mark =
-{
+static struct ebt_match filter_mark __read_mostly = {
.name = EBT_MARK_MATCH,
.match = ebt_filter_mark,
.check = ebt_mark_check,
@@ -59,4 +58,5 @@ static void __exit ebt_mark_m_fini(void)
module_init(ebt_mark_m_init);
module_exit(ebt_mark_m_fini);
+MODULE_DESCRIPTION("Ebtables: Packet mark match");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_pkttype.c b/net/bridge/netfilter/ebt_pkttype.c
index 4fffd70e4da..676db32df3d 100644
--- a/net/bridge/netfilter/ebt_pkttype.c
+++ b/net/bridge/netfilter/ebt_pkttype.c
@@ -18,7 +18,7 @@ static int ebt_filter_pkttype(const struct sk_buff *skb,
const void *data,
unsigned int datalen)
{
- struct ebt_pkttype_info *info = (struct ebt_pkttype_info *)data;
+ const struct ebt_pkttype_info *info = data;
return (skb->pkt_type != info->pkt_type) ^ info->invert;
}
@@ -26,7 +26,7 @@ static int ebt_filter_pkttype(const struct sk_buff *skb,
static int ebt_pkttype_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_pkttype_info *info = (struct ebt_pkttype_info *)data;
+ const struct ebt_pkttype_info *info = data;
if (datalen != EBT_ALIGN(sizeof(struct ebt_pkttype_info)))
return -EINVAL;
@@ -36,8 +36,7 @@ static int ebt_pkttype_check(const char *tablename, unsigned int hookmask,
return 0;
}
-static struct ebt_match filter_pkttype =
-{
+static struct ebt_match filter_pkttype __read_mostly = {
.name = EBT_PKTTYPE_MATCH,
.match = ebt_filter_pkttype,
.check = ebt_pkttype_check,
@@ -56,4 +55,5 @@ static void __exit ebt_pkttype_fini(void)
module_init(ebt_pkttype_init);
module_exit(ebt_pkttype_fini);
+MODULE_DESCRIPTION("Ebtables: Link layer packet type match");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c
index 422cb834cff..bfdf2fb60b1 100644
--- a/net/bridge/netfilter/ebt_redirect.c
+++ b/net/bridge/netfilter/ebt_redirect.c
@@ -19,7 +19,7 @@ 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;
+ const struct ebt_redirect_info *info = data;
if (skb_make_writable(skb, 0))
return NF_DROP;
@@ -36,7 +36,7 @@ static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr,
static int ebt_target_redirect_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_redirect_info *info = (struct ebt_redirect_info *)data;
+ const struct ebt_redirect_info *info = data;
if (datalen != EBT_ALIGN(sizeof(struct ebt_redirect_info)))
return -EINVAL;
@@ -51,8 +51,7 @@ static int ebt_target_redirect_check(const char *tablename, unsigned int hookmas
return 0;
}
-static struct ebt_target redirect_target =
-{
+static struct ebt_target redirect_target __read_mostly = {
.name = EBT_REDIRECT_TARGET,
.target = ebt_target_redirect,
.check = ebt_target_redirect_check,
@@ -71,4 +70,5 @@ static void __exit ebt_redirect_fini(void)
module_init(ebt_redirect_init);
module_exit(ebt_redirect_fini);
+MODULE_DESCRIPTION("Ebtables: Packet redirection to localhost");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c
index 425ac920904..e252dabbb14 100644
--- a/net/bridge/netfilter/ebt_snat.c
+++ b/net/bridge/netfilter/ebt_snat.c
@@ -20,7 +20,7 @@ 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;
+ const struct ebt_nat_info *info = data;
if (skb_make_writable(skb, 0))
return NF_DROP;
@@ -28,7 +28,8 @@ static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr,
memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN);
if (!(info->target & NAT_ARP_BIT) &&
eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
- struct arphdr _ah, *ap;
+ const struct arphdr *ap;
+ struct arphdr _ah;
ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
if (ap == NULL)
@@ -45,7 +46,7 @@ out:
static int ebt_target_snat_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_nat_info *info = (struct ebt_nat_info *) data;
+ const struct ebt_nat_info *info = data;
int tmp;
if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info)))
@@ -67,8 +68,7 @@ static int ebt_target_snat_check(const char *tablename, unsigned int hookmask,
return 0;
}
-static struct ebt_target snat =
-{
+static struct ebt_target snat __read_mostly = {
.name = EBT_SNAT_TARGET,
.target = ebt_target_snat,
.check = ebt_target_snat_check,
@@ -87,4 +87,5 @@ static void __exit ebt_snat_fini(void)
module_init(ebt_snat_init);
module_exit(ebt_snat_fini);
+MODULE_DESCRIPTION("Ebtables: Source MAC address translation");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_stp.c b/net/bridge/netfilter/ebt_stp.c
index 31b77367319..40f36d37607 100644
--- a/net/bridge/netfilter/ebt_stp.c
+++ b/net/bridge/netfilter/ebt_stp.c
@@ -40,10 +40,10 @@ struct stp_config_pdu {
#define NR16(p) (p[0] << 8 | p[1])
#define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3])
-static int ebt_filter_config(struct ebt_stp_info *info,
- struct stp_config_pdu *stpc)
+static int ebt_filter_config(const struct ebt_stp_info *info,
+ const struct stp_config_pdu *stpc)
{
- struct ebt_stp_config_info *c;
+ const struct ebt_stp_config_info *c;
uint16_t v16;
uint32_t v32;
int verdict, i;
@@ -122,9 +122,10 @@ static int ebt_filter_config(struct ebt_stp_info *info,
static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *data, unsigned int datalen)
{
- struct ebt_stp_info *info = (struct ebt_stp_info *)data;
- struct stp_header _stph, *sp;
- uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
+ const struct ebt_stp_info *info = data;
+ const struct stp_header *sp;
+ struct stp_header _stph;
+ const uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph);
if (sp == NULL)
@@ -140,7 +141,8 @@ static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in
if (sp->type == BPDU_TYPE_CONFIG &&
info->bitmask & EBT_STP_CONFIG_MASK) {
- struct stp_config_pdu _stpc, *st;
+ const struct stp_config_pdu *st;
+ struct stp_config_pdu _stpc;
st = skb_header_pointer(skb, sizeof(_stph),
sizeof(_stpc), &_stpc);
@@ -154,10 +156,10 @@ static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in
static int ebt_stp_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_stp_info *info = (struct ebt_stp_info *)data;
- int len = EBT_ALIGN(sizeof(struct ebt_stp_info));
- uint8_t bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
- uint8_t msk[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ const struct ebt_stp_info *info = data;
+ const unsigned int len = EBT_ALIGN(sizeof(struct ebt_stp_info));
+ const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00};
+ const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK ||
!(info->bitmask & EBT_STP_MASK))
@@ -172,8 +174,7 @@ static int ebt_stp_check(const char *tablename, unsigned int hookmask,
return 0;
}
-static struct ebt_match filter_stp =
-{
+static struct ebt_match filter_stp __read_mostly = {
.name = EBT_STP_MATCH,
.match = ebt_filter_stp,
.check = ebt_stp_check,
@@ -192,4 +193,5 @@ static void __exit ebt_stp_fini(void)
module_init(ebt_stp_init);
module_exit(ebt_stp_fini);
+MODULE_DESCRIPTION("Ebtables: Spanning Tree Protocol packet match");
MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index 8e7b00b68d3..2d4c9ef909f 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -249,7 +249,7 @@ static void ebt_ulog(const 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_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
+ const struct ebt_ulog_info *uloginfo = data;
ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL);
}
@@ -258,7 +258,7 @@ static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
+ struct ebt_ulog_info *uloginfo = data;
if (datalen != EBT_ALIGN(sizeof(struct ebt_ulog_info)) ||
uloginfo->nlgroup > 31)
@@ -272,7 +272,7 @@ static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
return 0;
}
-static struct ebt_watcher ulog = {
+static struct ebt_watcher ulog __read_mostly = {
.name = EBT_ULOG_WATCHER,
.watcher = ebt_ulog,
.check = ebt_ulog_check,
@@ -340,5 +340,4 @@ module_init(ebt_ulog_init);
module_exit(ebt_ulog_fini);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
-MODULE_DESCRIPTION("ebtables userspace logging module for bridged Ethernet"
- " frames");
+MODULE_DESCRIPTION("Ebtables: Packet logging to netlink using ULOG");
diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c
index 0ddf7499d49..ab60b0dade8 100644
--- a/net/bridge/netfilter/ebt_vlan.c
+++ b/net/bridge/netfilter/ebt_vlan.c
@@ -31,8 +31,7 @@ static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "debug=1 is turn on debug messages");
MODULE_AUTHOR("Nick Fedchik <nick@fedchik.org.ua>");
-MODULE_DESCRIPTION("802.1Q match module (ebtables extension), v"
- MODULE_VERS);
+MODULE_DESCRIPTION("Ebtables: 802.1Q VLAN tag match");
MODULE_LICENSE("GPL");
@@ -46,8 +45,9 @@ ebt_filter_vlan(const struct sk_buff *skb,
const struct net_device *out,
const void *data, unsigned int datalen)
{
- struct ebt_vlan_info *info = (struct ebt_vlan_info *) data;
- struct vlan_hdr _frame, *fp;
+ const struct ebt_vlan_info *info = data;
+ const struct vlan_hdr *fp;
+ struct vlan_hdr _frame;
unsigned short TCI; /* Whole TCI, given from parsed frame */
unsigned short id; /* VLAN ID, given from frame TCI */
@@ -91,7 +91,7 @@ ebt_check_vlan(const char *tablename,
unsigned int hooknr,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
- struct ebt_vlan_info *info = (struct ebt_vlan_info *) data;
+ struct ebt_vlan_info *info = data;
/* Parameters buffer overflow check */
if (datalen != EBT_ALIGN(sizeof(struct ebt_vlan_info))) {
@@ -169,7 +169,7 @@ ebt_check_vlan(const char *tablename,
return 0;
}
-static struct ebt_match filter_vlan = {
+static struct ebt_match filter_vlan __read_mostly = {
.name = EBT_VLAN_MATCH,
.match = ebt_filter_vlan,
.check = ebt_check_vlan,
diff --git a/net/core/dev.c b/net/core/dev.c
index c9c593e1ba6..edaff2720e1 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2962,6 +2962,102 @@ int dev_unicast_add(struct net_device *dev, void *addr, int alen)
}
EXPORT_SYMBOL(dev_unicast_add);
+int __dev_addr_sync(struct dev_addr_list **to, int *to_count,
+ struct dev_addr_list **from, int *from_count)
+{
+ struct dev_addr_list *da, *next;
+ int err = 0;
+
+ da = *from;
+ while (da != NULL) {
+ next = da->next;
+ if (!da->da_synced) {
+ err = __dev_addr_add(to, to_count,
+ da->da_addr, da->da_addrlen, 0);
+ if (err < 0)
+ break;
+ da->da_synced = 1;
+ da->da_users++;
+ } else if (da->da_users == 1) {
+ __dev_addr_delete(to, to_count,
+ da->da_addr, da->da_addrlen, 0);
+ __dev_addr_delete(from, from_count,
+ da->da_addr, da->da_addrlen, 0);
+ }
+ da = next;
+ }
+ return err;
+}
+
+void __dev_addr_unsync(struct dev_addr_list **to, int *to_count,
+ struct dev_addr_list **from, int *from_count)
+{
+ struct dev_addr_list *da, *next;
+
+ da = *from;
+ while (da != NULL) {
+ next = da->next;
+ if (da->da_synced) {
+ __dev_addr_delete(to, to_count,
+ da->da_addr, da->da_addrlen, 0);
+ da->da_synced = 0;
+ __dev_addr_delete(from, from_count,
+ da->da_addr, da->da_addrlen, 0);
+ }
+ da = next;
+ }
+}
+
+/**
+ * dev_unicast_sync - Synchronize device's unicast list to another device
+ * @to: destination device
+ * @from: source device
+ *
+ * Add newly added addresses to the destination device and release
+ * addresses that have no users left. The source device must be
+ * locked by netif_tx_lock_bh.
+ *
+ * This function is intended to be called from the dev->set_rx_mode
+ * function of layered software devices.
+ */
+int dev_unicast_sync(struct net_device *to, struct net_device *from)
+{
+ int err = 0;
+
+ netif_tx_lock_bh(to);
+ err = __dev_addr_sync(&to->uc_list, &to->uc_count,
+ &from->uc_list, &from->uc_count);
+ if (!err)
+ __dev_set_rx_mode(to);
+ netif_tx_unlock_bh(to);
+ return err;
+}
+EXPORT_SYMBOL(dev_unicast_sync);
+
+/**
+ * dev_unicast_unsync - Remove synchronized addresses from the destination
+ * device
+ * @to: destination device
+ * @from: source device
+ *
+ * Remove all addresses that were added to the destination device by
+ * dev_unicast_sync(). This function is intended to be called from the
+ * dev->stop function of layered software devices.
+ */
+void dev_unicast_unsync(struct net_device *to, struct net_device *from)
+{
+ netif_tx_lock_bh(from);
+ netif_tx_lock_bh(to);
+
+ __dev_addr_unsync(&to->uc_list, &to->uc_count,
+ &from->uc_list, &from->uc_count);
+ __dev_set_rx_mode(to);
+
+ netif_tx_unlock_bh(to);
+ netif_tx_unlock_bh(from);
+}
+EXPORT_SYMBOL(dev_unicast_unsync);
+
static void __dev_addr_discard(struct dev_addr_list **list)
{
struct dev_addr_list *tmp;
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index cadbfbf7e7f..cec582563e0 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -113,32 +113,15 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
* locked by netif_tx_lock_bh.
*
* This function is intended to be called from the dev->set_multicast_list
- * function of layered software devices.
+ * or dev->set_rx_mode function of layered software devices.
*/
int dev_mc_sync(struct net_device *to, struct net_device *from)
{
- struct dev_addr_list *da, *next;
int err = 0;
netif_tx_lock_bh(to);
- da = from->mc_list;
- while (da != NULL) {
- next = da->next;
- if (!da->da_synced) {
- err = __dev_addr_add(&to->mc_list, &to->mc_count,
- da->da_addr, da->da_addrlen, 0);
- if (err < 0)
- break;
- da->da_synced = 1;
- da->da_users++;
- } else if (da->da_users == 1) {
- __dev_addr_delete(&to->mc_list, &to->mc_count,
- da->da_addr, da->da_addrlen, 0);
- __dev_addr_delete(&from->mc_list, &from->mc_count,
- da->da_addr, da->da_addrlen, 0);
- }
- da = next;
- }
+ err = __dev_addr_sync(&to->mc_list, &to->mc_count,
+ &from->mc_list, &from->mc_count);
if (!err)
__dev_set_rx_mode(to);
netif_tx_unlock_bh(to);
@@ -160,23 +143,11 @@ EXPORT_SYMBOL(dev_mc_sync);
*/
void dev_mc_unsync(struct net_device *to, struct net_device *from)
{
- struct dev_addr_list *da, *next;
-
netif_tx_lock_bh(from);
netif_tx_lock_bh(to);
- da = from->mc_list;
- while (da != NULL) {
- next = da->next;
- if (da->da_synced) {
- __dev_addr_delete(&to->mc_list, &to->mc_count,
- da->da_addr, da->da_addrlen, 0);
- da->da_synced = 0;
- __dev_addr_delete(&from->mc_list, &from->mc_count,
- da->da_addr, da->da_addrlen, 0);
- }
- da = next;
- }
+ __dev_addr_unsync(&to->mc_list, &to->mc_count,
+ &from->mc_list, &from->mc_count);
__dev_set_rx_mode(to);
netif_tx_unlock_bh(to);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index eebccdbdbac..bfcdfaebca5 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -170,8 +170,6 @@
#define VERSION "pktgen v2.69: Packet Generator for packet performance testing.\n"
-/* The buckets are exponential in 'width' */
-#define LAT_BUCKETS_MAX 32
#define IP_NAME_SZ 32
#define MAX_MPLS_LABELS 16 /* This is the max label stack depth */
#define MPLS_STACK_BOTTOM htonl(0x00000100)
@@ -2044,7 +2042,6 @@ static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us)
__u64 now;
start = now = getCurUs();
- printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now));
while (now < spin_until_us) {
/* TODO: optimize sleeping behavior */
if (spin_until_us - now > jiffies_to_usecs(1) + 1)
diff --git a/net/core/sock.c b/net/core/sock.c
index 1c4b1cd16d6..433715fb141 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -667,6 +667,13 @@ set_rcvbuf:
else
clear_bit(SOCK_PASSSEC, &sock->flags);
break;
+ case SO_MARK:
+ if (!capable(CAP_NET_ADMIN))
+ ret = -EPERM;
+ else {
+ sk->sk_mark = val;
+ }
+ break;
/* We implement the SO_SNDLOWAT etc to
not be settable (1003.1g 5.3) */
@@ -836,6 +843,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
case SO_PEERSEC:
return security_socket_getpeersec_stream(sock, optval, optlen, len);
+ case SO_MARK:
+ v.val = sk->sk_mark;
+ break;
+
default:
return -ENOPROTOOPT;
}
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 9e38b0d6195..c982ad88223 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -218,7 +218,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
return;
}
- sk = inet_lookup(&dccp_hashinfo, iph->daddr, dh->dccph_dport,
+ sk = inet_lookup(&init_net, &dccp_hashinfo, iph->daddr, dh->dccph_dport,
iph->saddr, dh->dccph_sport, inet_iif(skb));
if (sk == NULL) {
ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
@@ -436,7 +436,7 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
if (req != NULL)
return dccp_check_req(sk, skb, req, prev);
- nsk = inet_lookup_established(&dccp_hashinfo,
+ nsk = inet_lookup_established(&init_net, &dccp_hashinfo,
iph->saddr, dh->dccph_sport,
iph->daddr, dh->dccph_dport,
inet_iif(skb));
@@ -817,7 +817,7 @@ static int dccp_v4_rcv(struct sk_buff *skb)
/* Step 2:
* Look up flow ID in table and get corresponding socket */
- sk = __inet_lookup(&dccp_hashinfo,
+ sk = __inet_lookup(&init_net, &dccp_hashinfo,
iph->saddr, dh->dccph_sport,
iph->daddr, dh->dccph_dport, inet_iif(skb));
/*
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index f42b75ce7f5..ed0a0053a79 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -101,8 +101,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
int err;
__u64 seq;
- sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
- &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
+ sk = inet6_lookup(&init_net, &dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
+ &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
if (sk == NULL) {
ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
@@ -366,7 +366,7 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
if (req != NULL)
return dccp_check_req(sk, skb, req, prev);
- nsk = __inet6_lookup_established(&dccp_hashinfo,
+ nsk = __inet6_lookup_established(&init_net, &dccp_hashinfo,
&iph->saddr, dh->dccph_sport,
&iph->daddr, ntohs(dh->dccph_dport),
inet6_iif(skb));
@@ -797,7 +797,7 @@ static int dccp_v6_rcv(struct sk_buff *skb)
/* Step 2:
* Look up flow ID in table and get corresponding socket */
- sk = __inet6_lookup(&dccp_hashinfo, &ipv6_hdr(skb)->saddr,
+ sk = __inet6_lookup(&init_net, &dccp_hashinfo, &ipv6_hdr(skb)->saddr,
dh->dccph_sport,
&ipv6_hdr(skb)->daddr, ntohs(dh->dccph_dport),
inet6_iif(skb));
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 24e2b7294bf..19880b086e7 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -343,6 +343,7 @@ config INET_ESP
tristate "IP: ESP transformation"
select XFRM
select CRYPTO
+ select CRYPTO_AEAD
select CRYPTO_HMAC
select CRYPTO_MD5
select CRYPTO_CBC
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index d76803a3dca..9d4555ec0b5 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -300,7 +300,7 @@ static void ah_destroy(struct xfrm_state *x)
}
-static struct xfrm_type ah_type =
+static const struct xfrm_type ah_type =
{
.description = "AH4",
.owner = THIS_MODULE,
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 5976c598cc4..8e17f65f400 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -558,8 +558,9 @@ static inline int arp_fwd_proxy(struct in_device *in_dev, struct rtable *rt)
*/
struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
struct net_device *dev, __be32 src_ip,
- unsigned char *dest_hw, unsigned char *src_hw,
- unsigned char *target_hw)
+ const unsigned char *dest_hw,
+ const unsigned char *src_hw,
+ const unsigned char *target_hw)
{
struct sk_buff *skb;
struct arphdr *arp;
@@ -672,8 +673,8 @@ void arp_xmit(struct sk_buff *skb)
*/
void arp_send(int type, int ptype, __be32 dest_ip,
struct net_device *dev, __be32 src_ip,
- unsigned char *dest_hw, unsigned char *src_hw,
- unsigned char *target_hw)
+ const unsigned char *dest_hw, const unsigned char *src_hw,
+ const unsigned char *target_hw)
{
struct sk_buff *skb;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 21f71bf912d..f282b26f63e 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -64,7 +64,7 @@
#include <net/rtnetlink.h>
#include <net/net_namespace.h>
-struct ipv4_devconf ipv4_devconf = {
+static struct ipv4_devconf ipv4_devconf = {
.data = {
[NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
[NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
@@ -485,46 +485,41 @@ errout:
return err;
}
-static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
+static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh)
{
struct nlattr *tb[IFA_MAX+1];
struct in_ifaddr *ifa;
struct ifaddrmsg *ifm;
struct net_device *dev;
struct in_device *in_dev;
- int err = -EINVAL;
+ int err;
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy);
if (err < 0)
goto errout;
ifm = nlmsg_data(nlh);
- if (ifm->ifa_prefixlen > 32 || tb[IFA_LOCAL] == NULL) {
- err = -EINVAL;
+ err = -EINVAL;
+ if (ifm->ifa_prefixlen > 32 || tb[IFA_LOCAL] == NULL)
goto errout;
- }
- dev = __dev_get_by_index(&init_net, ifm->ifa_index);
- if (dev == NULL) {
- err = -ENODEV;
+ dev = __dev_get_by_index(net, ifm->ifa_index);
+ err = -ENODEV;
+ if (dev == NULL)
goto errout;
- }
in_dev = __in_dev_get_rtnl(dev);
- if (in_dev == NULL) {
- err = -ENOBUFS;
+ err = -ENOBUFS;
+ if (in_dev == NULL)
goto errout;
- }
ifa = inet_alloc_ifa();
- if (ifa == NULL) {
+ if (ifa == NULL)
/*
* A potential indev allocation can be left alive, it stays
* assigned to its device and is destroy with it.
*/
- err = -ENOBUFS;
goto errout;
- }
ipv4_devconf_setall(in_dev);
in_dev_hold(in_dev);
@@ -568,7 +563,7 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
if (net != &init_net)
return -EINVAL;
- ifa = rtm_to_ifaddr(nlh);
+ ifa = rtm_to_ifaddr(net, nlh);
if (IS_ERR(ifa))
return PTR_ERR(ifa);
@@ -1182,7 +1177,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
s_ip_idx = ip_idx = cb->args[1];
idx = 0;
- for_each_netdev(&init_net, dev) {
+ for_each_netdev(net, dev) {
if (idx < s_idx)
goto cont;
if (idx > s_idx)
@@ -1216,7 +1211,9 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh,
struct sk_buff *skb;
u32 seq = nlh ? nlh->nlmsg_seq : 0;
int err = -ENOBUFS;
+ struct net *net;
+ net = ifa->ifa_dev->dev->nd_net;
skb = nlmsg_new(inet_nlmsg_size(), GFP_KERNEL);
if (skb == NULL)
goto errout;
@@ -1228,10 +1225,10 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh,
kfree_skb(skb);
goto errout;
}
- err = rtnl_notify(skb, &init_net, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
+ err = rtnl_notify(skb, net, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
errout:
if (err < 0)
- rtnl_set_sk_err(&init_net, RTNLGRP_IPV4_IFADDR, err);
+ rtnl_set_sk_err(net, RTNLGRP_IPV4_IFADDR, err);
}
#ifdef CONFIG_SYSCTL
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 28ea5c77ca2..258d17631b4 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -1,27 +1,118 @@
+#include <crypto/aead.h>
+#include <crypto/authenc.h>
#include <linux/err.h>
#include <linux/module.h>
#include <net/ip.h>
#include <net/xfrm.h>
#include <net/esp.h>
#include <linux/scatterlist.h>
-#include <linux/crypto.h>
#include <linux/kernel.h>
#include <linux/pfkeyv2.h>
-#include <linux/random.h>
+#include <linux/rtnetlink.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/in6.h>
#include <net/icmp.h>
#include <net/protocol.h>
#include <net/udp.h>
+struct esp_skb_cb {
+ struct xfrm_skb_cb xfrm;
+ void *tmp;
+};
+
+#define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
+
+/*
+ * Allocate an AEAD request structure with extra space for SG and IV.
+ *
+ * For alignment considerations the IV is placed at the front, followed
+ * by the request and finally the SG list.
+ *
+ * TODO: Use spare space in skb for this where possible.
+ */
+static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags)
+{
+ unsigned int len;
+
+ len = crypto_aead_ivsize(aead);
+ if (len) {
+ len += crypto_aead_alignmask(aead) &
+ ~(crypto_tfm_ctx_alignment() - 1);
+ len = ALIGN(len, crypto_tfm_ctx_alignment());
+ }
+
+ len += sizeof(struct aead_givcrypt_request) + crypto_aead_reqsize(aead);
+ len = ALIGN(len, __alignof__(struct scatterlist));
+
+ len += sizeof(struct scatterlist) * nfrags;
+
+ return kmalloc(len, GFP_ATOMIC);
+}
+
+static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp)
+{
+ return crypto_aead_ivsize(aead) ?
+ PTR_ALIGN((u8 *)tmp, crypto_aead_alignmask(aead) + 1) : tmp;
+}
+
+static inline struct aead_givcrypt_request *esp_tmp_givreq(
+ struct crypto_aead *aead, u8 *iv)
+{
+ struct aead_givcrypt_request *req;
+
+ req = (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead),
+ crypto_tfm_ctx_alignment());
+ aead_givcrypt_set_tfm(req, aead);
+ return req;
+}
+
+static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv)
+{
+ struct aead_request *req;
+
+ req = (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead),
+ crypto_tfm_ctx_alignment());
+ aead_request_set_tfm(req, aead);
+ return req;
+}
+
+static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
+ struct aead_request *req)
+{
+ return (void *)ALIGN((unsigned long)(req + 1) +
+ crypto_aead_reqsize(aead),
+ __alignof__(struct scatterlist));
+}
+
+static inline struct scatterlist *esp_givreq_sg(
+ struct crypto_aead *aead, struct aead_givcrypt_request *req)
+{
+ return (void *)ALIGN((unsigned long)(req + 1) +
+ crypto_aead_reqsize(aead),
+ __alignof__(struct scatterlist));
+}
+
+static void esp_output_done(struct crypto_async_request *base, int err)
+{
+ struct sk_buff *skb = base->data;
+
+ kfree(ESP_SKB_CB(skb)->tmp);
+ xfrm_output_resume(skb, err);
+}
+
static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
{
int err;
struct ip_esp_hdr *esph;
- struct crypto_blkcipher *tfm;
- struct blkcipher_desc desc;
+ struct crypto_aead *aead;
+ struct aead_givcrypt_request *req;
+ struct scatterlist *sg;
+ struct scatterlist *asg;
struct esp_data *esp;
struct sk_buff *trailer;
+ void *tmp;
+ u8 *iv;
u8 *tail;
int blksize;
int clen;
@@ -36,18 +127,27 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
clen = skb->len;
esp = x->data;
- alen = esp->auth.icv_trunc_len;
- tfm = esp->conf.tfm;
- desc.tfm = tfm;
- desc.flags = 0;
- blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
+ aead = esp->aead;
+ alen = crypto_aead_authsize(aead);
+
+ blksize = ALIGN(crypto_aead_blocksize(aead), 4);
clen = ALIGN(clen + 2, blksize);
- if (esp->conf.padlen)
- clen = ALIGN(clen, esp->conf.padlen);
+ if (esp->padlen)
+ clen = ALIGN(clen, esp->padlen);
+
+ if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0)
+ goto error;
+ nfrags = err;
- if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0)
+ tmp = esp_alloc_tmp(aead, nfrags + 1);
+ if (!tmp)
goto error;
+ iv = esp_tmp_iv(aead, tmp);
+ req = esp_tmp_givreq(aead, iv);
+ asg = esp_givreq_sg(aead, req);
+ sg = asg + 1;
+
/* Fill padding... */
tail = skb_tail_pointer(trailer);
do {
@@ -56,28 +156,34 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
tail[i] = i + 1;
} while (0);
tail[clen - skb->len - 2] = (clen - skb->len) - 2;
- pskb_put(skb, trailer, clen - skb->len);
+ tail[clen - skb->len - 1] = *skb_mac_header(skb);
+ pskb_put(skb, trailer, clen - skb->len + alen);
skb_push(skb, -skb_network_offset(skb));
esph = ip_esp_hdr(skb);
- *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb);
*skb_mac_header(skb) = IPPROTO_ESP;
- spin_lock_bh(&x->lock);
-
/* this is non-NULL only with UDP Encapsulation */
if (x->encap) {
struct xfrm_encap_tmpl *encap = x->encap;
struct udphdr *uh;
__be32 *udpdata32;
+ unsigned int sport, dport;
+ int encap_type;
+
+ spin_lock_bh(&x->lock);
+ sport = encap->encap_sport;
+ dport = encap->encap_dport;
+ encap_type = encap->encap_type;
+ spin_unlock_bh(&x->lock);
uh = (struct udphdr *)esph;
- uh->source = encap->encap_sport;
- uh->dest = encap->encap_dport;
- uh->len = htons(skb->len + alen - skb_transport_offset(skb));
+ uh->source = sport;
+ uh->dest = dport;
+ uh->len = htons(skb->len - skb_transport_offset(skb));
uh->check = 0;
- switch (encap->encap_type) {
+ switch (encap_type) {
default:
case UDP_ENCAP_ESPINUDP:
esph = (struct ip_esp_hdr *)(uh + 1);
@@ -95,131 +201,45 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
esph->spi = x->id.spi;
esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
- if (esp->conf.ivlen) {
- if (unlikely(!esp->conf.ivinitted)) {
- get_random_bytes(esp->conf.ivec, esp->conf.ivlen);
- esp->conf.ivinitted = 1;
- }
- crypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
- }
-
- do {
- struct scatterlist *sg = &esp->sgbuf[0];
-
- if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
- sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
- if (!sg)
- goto unlock;
- }
- sg_init_table(sg, nfrags);
- skb_to_sgvec(skb, sg,
- esph->enc_data +
- esp->conf.ivlen -
- skb->data, clen);
- err = crypto_blkcipher_encrypt(&desc, sg, sg, clen);
- if (unlikely(sg != &esp->sgbuf[0]))
- kfree(sg);
- } while (0);
-
- if (unlikely(err))
- goto unlock;
-
- if (esp->conf.ivlen) {
- memcpy(esph->enc_data, esp->conf.ivec, esp->conf.ivlen);
- crypto_blkcipher_get_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
- }
+ sg_init_table(sg, nfrags);
+ skb_to_sgvec(skb, sg,
+ esph->enc_data + crypto_aead_ivsize(aead) - skb->data,
+ clen + alen);
+ sg_init_one(asg, esph, sizeof(*esph));
+
+ aead_givcrypt_set_callback(req, 0, esp_output_done, skb);
+ aead_givcrypt_set_crypt(req, sg, sg, clen, iv);
+ aead_givcrypt_set_assoc(req, asg, sizeof(*esph));
+ aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq);
+
+ ESP_SKB_CB(skb)->tmp = tmp;
+ err = crypto_aead_givencrypt(req);
+ if (err == -EINPROGRESS)
+ goto error;
- if (esp->auth.icv_full_len) {
- err = esp_mac_digest(esp, skb, (u8 *)esph - skb->data,
- sizeof(*esph) + esp->conf.ivlen + clen);
- memcpy(pskb_put(skb, trailer, alen), esp->auth.work_icv, alen);
- }
+ if (err == -EBUSY)
+ err = NET_XMIT_DROP;
-unlock:
- spin_unlock_bh(&x->lock);
+ kfree(tmp);
error:
return err;
}
-/*
- * Note: detecting truncated vs. non-truncated authentication data is very
- * expensive, so we only support truncated data, which is the recommended
- * and common case.
- */
-static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
+static int esp_input_done2(struct sk_buff *skb, int err)
{
struct iphdr *iph;
- struct ip_esp_hdr *esph;
+ struct xfrm_state *x = xfrm_input_state(skb);
struct esp_data *esp = x->data;
- struct crypto_blkcipher *tfm = esp->conf.tfm;
- struct blkcipher_desc desc = { .tfm = tfm };
- struct sk_buff *trailer;
- int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
- int alen = esp->auth.icv_trunc_len;
- int elen = skb->len - sizeof(*esph) - esp->conf.ivlen - alen;
- int nfrags;
+ struct crypto_aead *aead = esp->aead;
+ int alen = crypto_aead_authsize(aead);
+ int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead);
+ int elen = skb->len - hlen;
int ihl;
u8 nexthdr[2];
- struct scatterlist *sg;
int padlen;
- int err = -EINVAL;
-
- if (!pskb_may_pull(skb, sizeof(*esph)))
- goto out;
-
- if (elen <= 0 || (elen & (blksize-1)))
- goto out;
-
- if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
- goto out;
- nfrags = err;
-
- skb->ip_summed = CHECKSUM_NONE;
-
- spin_lock(&x->lock);
-
- /* If integrity check is required, do this. */
- if (esp->auth.icv_full_len) {
- u8 sum[alen];
- err = esp_mac_digest(esp, skb, 0, skb->len - alen);
- if (err)
- goto unlock;
-
- if (skb_copy_bits(skb, skb->len - alen, sum, alen))
- BUG();
-
- if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
- err = -EBADMSG;
- goto unlock;
- }
- }
-
- esph = (struct ip_esp_hdr *)skb->data;
-
- /* Get ivec. This can be wrong, check against another impls. */
- if (esp->conf.ivlen)
- crypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen);
-
- sg = &esp->sgbuf[0];
-
- if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
- err = -ENOMEM;
- sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
- if (!sg)
- goto unlock;
- }
- sg_init_table(sg, nfrags);
- skb_to_sgvec(skb, sg,
- sizeof(*esph) + esp->conf.ivlen,
- elen);
- err = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
- if (unlikely(sg != &esp->sgbuf[0]))
- kfree(sg);
-
-unlock:
- spin_unlock(&x->lock);
+ kfree(ESP_SKB_CB(skb)->tmp);
if (unlikely(err))
goto out;
@@ -229,15 +249,11 @@ unlock:
err = -EINVAL;
padlen = nexthdr[0];
- if (padlen+2 >= elen)
+ if (padlen + 2 + alen >= elen)
goto out;
/* ... check padding bits here. Silly. :-) */
- /* RFC4303: Drop dummy packets without any error */
- if (nexthdr[1] == IPPROTO_NONE)
- goto out;
-
iph = ip_hdr(skb);
ihl = iph->ihl * 4;
@@ -279,10 +295,87 @@ unlock:
}
pskb_trim(skb, skb->len - alen - padlen - 2);
- __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen);
+ __skb_pull(skb, hlen);
skb_set_transport_header(skb, -ihl);
- return nexthdr[1];
+ err = nexthdr[1];
+
+ /* RFC4303: Drop dummy packets without any error */
+ if (err == IPPROTO_NONE)
+ err = -EINVAL;
+
+out:
+ return err;
+}
+
+static void esp_input_done(struct crypto_async_request *base, int err)
+{
+ struct sk_buff *skb = base->data;
+
+ xfrm_input_resume(skb, esp_input_done2(skb, err));
+}
+
+/*
+ * Note: detecting truncated vs. non-truncated authentication data is very
+ * expensive, so we only support truncated data, which is the recommended
+ * and common case.
+ */
+static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+ struct ip_esp_hdr *esph;
+ struct esp_data *esp = x->data;
+ struct crypto_aead *aead = esp->aead;
+ struct aead_request *req;
+ struct sk_buff *trailer;
+ int elen = skb->len - sizeof(*esph) - crypto_aead_ivsize(aead);
+ int nfrags;
+ void *tmp;
+ u8 *iv;
+ struct scatterlist *sg;
+ struct scatterlist *asg;
+ int err = -EINVAL;
+
+ if (!pskb_may_pull(skb, sizeof(*esph)))
+ goto out;
+
+ if (elen <= 0)
+ goto out;
+
+ if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
+ goto out;
+ nfrags = err;
+
+ err = -ENOMEM;
+ tmp = esp_alloc_tmp(aead, nfrags + 1);
+ if (!tmp)
+ goto out;
+
+ ESP_SKB_CB(skb)->tmp = tmp;
+ iv = esp_tmp_iv(aead, tmp);
+ req = esp_tmp_req(aead, iv);
+ asg = esp_req_sg(aead, req);
+ sg = asg + 1;
+
+ skb->ip_summed = CHECKSUM_NONE;
+
+ esph = (struct ip_esp_hdr *)skb->data;
+
+ /* Get ivec. This can be wrong, check against another impls. */
+ iv = esph->enc_data;
+
+ sg_init_table(sg, nfrags);
+ skb_to_sgvec(skb, sg, sizeof(*esph) + crypto_aead_ivsize(aead), elen);
+ sg_init_one(asg, esph, sizeof(*esph));
+
+ aead_request_set_callback(req, 0, esp_input_done, skb);
+ aead_request_set_crypt(req, sg, sg, elen, iv);
+ aead_request_set_assoc(req, asg, sizeof(*esph));
+
+ err = crypto_aead_decrypt(req);
+ if (err == -EINPROGRESS)
+ goto out;
+
+ err = esp_input_done2(skb, err);
out:
return err;
@@ -291,11 +384,11 @@ out:
static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
{
struct esp_data *esp = x->data;
- u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
- u32 align = max_t(u32, blksize, esp->conf.padlen);
+ u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4);
+ u32 align = max_t(u32, blksize, esp->padlen);
u32 rem;
- mtu -= x->props.header_len + esp->auth.icv_trunc_len;
+ mtu -= x->props.header_len + crypto_aead_authsize(esp->aead);
rem = mtu & (align - 1);
mtu &= ~(align - 1);
@@ -342,80 +435,143 @@ static void esp_destroy(struct xfrm_state *x)
if (!esp)
return;
- crypto_free_blkcipher(esp->conf.tfm);
- esp->conf.tfm = NULL;
- kfree(esp->conf.ivec);
- esp->conf.ivec = NULL;
- crypto_free_hash(esp->auth.tfm);
- esp->auth.tfm = NULL;
- kfree(esp->auth.work_icv);
- esp->auth.work_icv = NULL;
+ crypto_free_aead(esp->aead);
kfree(esp);
}
-static int esp_init_state(struct xfrm_state *x)
+static int esp_init_aead(struct xfrm_state *x)
{
- struct esp_data *esp = NULL;
- struct crypto_blkcipher *tfm;
- u32 align;
+ struct esp_data *esp = x->data;
+ struct crypto_aead *aead;
+ int err;
+
+ aead = crypto_alloc_aead(x->aead->alg_name, 0, 0);
+ err = PTR_ERR(aead);
+ if (IS_ERR(aead))
+ goto error;
+
+ esp->aead = aead;
+
+ err = crypto_aead_setkey(aead, x->aead->alg_key,
+ (x->aead->alg_key_len + 7) / 8);
+ if (err)
+ goto error;
+
+ err = crypto_aead_setauthsize(aead, x->aead->alg_icv_len / 8);
+ if (err)
+ goto error;
+
+error:
+ return err;
+}
+static int esp_init_authenc(struct xfrm_state *x)
+{
+ struct esp_data *esp = x->data;
+ struct crypto_aead *aead;
+ struct crypto_authenc_key_param *param;
+ struct rtattr *rta;
+ char *key;
+ char *p;
+ char authenc_name[CRYPTO_MAX_ALG_NAME];
+ unsigned int keylen;
+ int err;
+
+ err = -EINVAL;
if (x->ealg == NULL)
goto error;
- esp = kzalloc(sizeof(*esp), GFP_KERNEL);
- if (esp == NULL)
- return -ENOMEM;
+ err = -ENAMETOOLONG;
+ if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME, "authenc(%s,%s)",
+ x->aalg ? x->aalg->alg_name : "digest_null",
+ x->ealg->alg_name) >= CRYPTO_MAX_ALG_NAME)
+ goto error;
+
+ aead = crypto_alloc_aead(authenc_name, 0, 0);
+ err = PTR_ERR(aead);
+ if (IS_ERR(aead))
+ goto error;
+
+ esp->aead = aead;
+
+ keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) +
+ (x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param));
+ err = -ENOMEM;
+ key = kmalloc(keylen, GFP_KERNEL);
+ if (!key)
+ goto error;
+
+ p = key;
+ rta = (void *)p;
+ rta->rta_type = CRYPTO_AUTHENC_KEYA_PARAM;
+ rta->rta_len = RTA_LENGTH(sizeof(*param));
+ param = RTA_DATA(rta);
+ p += RTA_SPACE(sizeof(*param));
if (x->aalg) {
struct xfrm_algo_desc *aalg_desc;
- struct crypto_hash *hash;
- hash = crypto_alloc_hash(x->aalg->alg_name, 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(hash))
- goto error;
-
- esp->auth.tfm = hash;
- if (crypto_hash_setkey(hash, x->aalg->alg_key,
- (x->aalg->alg_key_len + 7) / 8))
- goto error;
+ memcpy(p, x->aalg->alg_key, (x->aalg->alg_key_len + 7) / 8);
+ p += (x->aalg->alg_key_len + 7) / 8;
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
BUG_ON(!aalg_desc);
+ err = -EINVAL;
if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
- crypto_hash_digestsize(hash)) {
+ crypto_aead_authsize(aead)) {
NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n",
x->aalg->alg_name,
- crypto_hash_digestsize(hash),
+ crypto_aead_authsize(aead),
aalg_desc->uinfo.auth.icv_fullbits/8);
- goto error;
+ goto free_key;
}
- esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
- esp->auth.icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8;
-
- esp->auth.work_icv = kmalloc(esp->auth.icv_full_len, GFP_KERNEL);
- if (!esp->auth.work_icv)
- goto error;
+ err = crypto_aead_setauthsize(
+ aead, aalg_desc->uinfo.auth.icv_truncbits / 8);
+ if (err)
+ goto free_key;
}
- tfm = crypto_alloc_blkcipher(x->ealg->alg_name, 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(tfm))
- goto error;
- esp->conf.tfm = tfm;
- esp->conf.ivlen = crypto_blkcipher_ivsize(tfm);
- esp->conf.padlen = 0;
- if (esp->conf.ivlen) {
- esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL);
- if (unlikely(esp->conf.ivec == NULL))
- goto error;
- esp->conf.ivinitted = 0;
- }
- if (crypto_blkcipher_setkey(tfm, x->ealg->alg_key,
- (x->ealg->alg_key_len + 7) / 8))
+ param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8);
+ memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8);
+
+ err = crypto_aead_setkey(aead, key, keylen);
+
+free_key:
+ kfree(key);
+
+error:
+ return err;
+}
+
+static int esp_init_state(struct xfrm_state *x)
+{
+ struct esp_data *esp;
+ struct crypto_aead *aead;
+ u32 align;
+ int err;
+
+ esp = kzalloc(sizeof(*esp), GFP_KERNEL);
+ if (esp == NULL)
+ return -ENOMEM;
+
+ x->data = esp;
+
+ if (x->aead)
+ err = esp_init_aead(x);
+ else
+ err = esp_init_authenc(x);
+
+ if (err)
goto error;
- x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
+
+ aead = esp->aead;
+
+ esp->padlen = 0;
+
+ x->props.header_len = sizeof(struct ip_esp_hdr) +
+ crypto_aead_ivsize(aead);
if (x->props.mode == XFRM_MODE_TUNNEL)
x->props.header_len += sizeof(struct iphdr);
else if (x->props.mode == XFRM_MODE_BEET)
@@ -434,21 +590,17 @@ static int esp_init_state(struct xfrm_state *x)
break;
}
}
- x->data = esp;
- align = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
- if (esp->conf.padlen)
- align = max_t(u32, align, esp->conf.padlen);
- x->props.trailer_len = align + 1 + esp->auth.icv_trunc_len;
- return 0;
+
+ align = ALIGN(crypto_aead_blocksize(aead), 4);
+ if (esp->padlen)
+ align = max_t(u32, align, esp->padlen);
+ x->props.trailer_len = align + 1 + crypto_aead_authsize(esp->aead);
error:
- x->data = esp;
- esp_destroy(x);
- x->data = NULL;
- return -EINVAL;
+ return err;
}
-static struct xfrm_type esp_type =
+static const struct xfrm_type esp_type =
{
.description = "ESP4",
.owner = THIS_MODULE,
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index d28261826bc..86ff2711fc9 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -808,7 +808,7 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
First of all, we scan fib_info list searching
for stray nexthop entries, then ignite fib_flush.
*/
- if (fib_sync_down(ifa->ifa_local, NULL, 0))
+ if (fib_sync_down_addr(dev->nd_net, ifa->ifa_local))
fib_flush(dev->nd_net);
}
}
@@ -898,7 +898,7 @@ static void nl_fib_lookup_exit(struct net *net)
static void fib_disable_ip(struct net_device *dev, int force)
{
- if (fib_sync_down(0, dev, force))
+ if (fib_sync_down_dev(dev, force))
fib_flush(dev->nd_net);
rt_cache_flush(0);
arp_ifdown(dev);
@@ -975,6 +975,7 @@ static struct notifier_block fib_netdev_notifier = {
static int __net_init ip_fib_net_init(struct net *net)
{
+ int err;
unsigned int i;
net->ipv4.fib_table_hash = kzalloc(
@@ -985,7 +986,14 @@ static int __net_init ip_fib_net_init(struct net *net)
for (i = 0; i < FIB_TABLE_HASHSZ; i++)
INIT_HLIST_HEAD(&net->ipv4.fib_table_hash[i]);
- return fib4_rules_init(net);
+ err = fib4_rules_init(net);
+ if (err < 0)
+ goto fail;
+ return 0;
+
+fail:
+ kfree(net->ipv4.fib_table_hash);
+ return err;
}
static void __net_exit ip_fib_net_exit(struct net *net)
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index a15b2f1b272..76b9c684ccc 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -424,19 +424,43 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
if (fa && fa->fa_tos == tos &&
fa->fa_info->fib_priority == fi->fib_priority) {
- struct fib_alias *fa_orig;
+ struct fib_alias *fa_first, *fa_match;
err = -EEXIST;
if (cfg->fc_nlflags & NLM_F_EXCL)
goto out;
+ /* We have 2 goals:
+ * 1. Find exact match for type, scope, fib_info to avoid
+ * duplicate routes
+ * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it
+ */
+ fa_match = NULL;
+ fa_first = fa;
+ fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
+ list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
+ if (fa->fa_tos != tos)
+ break;
+ if (fa->fa_info->fib_priority != fi->fib_priority)
+ break;
+ if (fa->fa_type == cfg->fc_type &&
+ fa->fa_scope == cfg->fc_scope &&
+ fa->fa_info == fi) {
+ fa_match = fa;
+ break;
+ }
+ }
+
if (cfg->fc_nlflags & NLM_F_REPLACE) {
struct fib_info *fi_drop;
u8 state;
- if (fi->fib_treeref > 1)
+ fa = fa_first;
+ if (fa_match) {
+ if (fa == fa_match)
+ err = 0;
goto out;
-
+ }
write_lock_bh(&fib_hash_lock);
fi_drop = fa->fa_info;
fa->fa_info = fi;
@@ -459,20 +483,11 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
* uses the same scope, type, and nexthop
* information.
*/
- fa_orig = fa;
- fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
- list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
- if (fa->fa_tos != tos)
- break;
- if (fa->fa_info->fib_priority != fi->fib_priority)
- break;
- if (fa->fa_type == cfg->fc_type &&
- fa->fa_scope == cfg->fc_scope &&
- fa->fa_info == fi)
- goto out;
- }
+ if (fa_match)
+ goto out;
+
if (!(cfg->fc_nlflags & NLM_F_APPEND))
- fa = fa_orig;
+ fa = fa_first;
}
err = -ENOENT;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index c7912866d98..a13c84763d4 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -229,6 +229,8 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi)
head = &fib_info_hash[hash];
hlist_for_each_entry(fi, node, head, fib_hash) {
+ if (fi->fib_net != nfi->fib_net)
+ continue;
if (fi->fib_nhs != nfi->fib_nhs)
continue;
if (nfi->fib_protocol == fi->fib_protocol &&
@@ -687,6 +689,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
struct fib_info *fi = NULL;
struct fib_info *ofi;
int nhs = 1;
+ struct net *net = cfg->fc_nlinfo.nl_net;
/* Fast check to catch the most weird cases */
if (fib_props[cfg->fc_type].scope > cfg->fc_scope)
@@ -727,6 +730,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
goto failure;
fib_info_cnt++;
+ fi->fib_net = net;
fi->fib_protocol = cfg->fc_protocol;
fi->fib_flags = cfg->fc_flags;
fi->fib_priority = cfg->fc_priority;
@@ -798,8 +802,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
if (nhs != 1 || nh->nh_gw)
goto err_inval;
nh->nh_scope = RT_SCOPE_NOWHERE;
- nh->nh_dev = dev_get_by_index(cfg->fc_nlinfo.nl_net,
- fi->fib_nh->nh_oif);
+ nh->nh_dev = dev_get_by_index(net, fi->fib_nh->nh_oif);
err = -ENODEV;
if (nh->nh_dev == NULL)
goto failure;
@@ -813,8 +816,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
if (fi->fib_prefsrc) {
if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
fi->fib_prefsrc != cfg->fc_dst)
- if (inet_addr_type(cfg->fc_nlinfo.nl_net,
- fi->fib_prefsrc) != RTN_LOCAL)
+ if (inet_addr_type(net, fi->fib_prefsrc) != RTN_LOCAL)
goto err_inval;
}
@@ -1031,70 +1033,74 @@ nla_put_failure:
referring to it.
- device went down -> we must shutdown all nexthops going via it.
*/
-
-int fib_sync_down(__be32 local, struct net_device *dev, int force)
+int fib_sync_down_addr(struct net *net, __be32 local)
{
int ret = 0;
- int scope = RT_SCOPE_NOWHERE;
-
- if (force)
- scope = -1;
+ unsigned int hash = fib_laddr_hashfn(local);
+ struct hlist_head *head = &fib_info_laddrhash[hash];
+ struct hlist_node *node;
+ struct fib_info *fi;
- if (local && fib_info_laddrhash) {
- unsigned int hash = fib_laddr_hashfn(local);
- struct hlist_head *head = &fib_info_laddrhash[hash];
- struct hlist_node *node;
- struct fib_info *fi;
+ if (fib_info_laddrhash == NULL || local == 0)
+ return 0;
- hlist_for_each_entry(fi, node, head, fib_lhash) {
- if (fi->fib_prefsrc == local) {
- fi->fib_flags |= RTNH_F_DEAD;
- ret++;
- }
+ hlist_for_each_entry(fi, node, head, fib_lhash) {
+ if (fi->fib_net != net)
+ continue;
+ if (fi->fib_prefsrc == local) {
+ fi->fib_flags |= RTNH_F_DEAD;
+ ret++;
}
}
+ return ret;
+}
- if (dev) {
- struct fib_info *prev_fi = NULL;
- unsigned int hash = fib_devindex_hashfn(dev->ifindex);
- struct hlist_head *head = &fib_info_devhash[hash];
- struct hlist_node *node;
- struct fib_nh *nh;
+int fib_sync_down_dev(struct net_device *dev, int force)
+{
+ int ret = 0;
+ int scope = RT_SCOPE_NOWHERE;
+ struct fib_info *prev_fi = NULL;
+ unsigned int hash = fib_devindex_hashfn(dev->ifindex);
+ struct hlist_head *head = &fib_info_devhash[hash];
+ struct hlist_node *node;
+ struct fib_nh *nh;
- hlist_for_each_entry(nh, node, head, nh_hash) {
- struct fib_info *fi = nh->nh_parent;
- int dead;
+ if (force)
+ scope = -1;
- BUG_ON(!fi->fib_nhs);
- if (nh->nh_dev != dev || fi == prev_fi)
- continue;
- prev_fi = fi;
- dead = 0;
- change_nexthops(fi) {
- if (nh->nh_flags&RTNH_F_DEAD)
- dead++;
- else if (nh->nh_dev == dev &&
- nh->nh_scope != scope) {
- nh->nh_flags |= RTNH_F_DEAD;
+ hlist_for_each_entry(nh, node, head, nh_hash) {
+ struct fib_info *fi = nh->nh_parent;
+ int dead;
+
+ BUG_ON(!fi->fib_nhs);
+ if (nh->nh_dev != dev || fi == prev_fi)
+ continue;
+ prev_fi = fi;
+ dead = 0;
+ change_nexthops(fi) {
+ if (nh->nh_flags&RTNH_F_DEAD)
+ dead++;
+ else if (nh->nh_dev == dev &&
+ nh->nh_scope != scope) {
+ nh->nh_flags |= RTNH_F_DEAD;
#ifdef CONFIG_IP_ROUTE_MULTIPATH
- spin_lock_bh(&fib_multipath_lock);
- fi->fib_power -= nh->nh_power;
- nh->nh_power = 0;
- spin_unlock_bh(&fib_multipath_lock);
+ spin_lock_bh(&fib_multipath_lock);
+ fi->fib_power -= nh->nh_power;
+ nh->nh_power = 0;
+ spin_unlock_bh(&fib_multipath_lock);
#endif
- dead++;
- }
+ dead++;
+ }
#ifdef CONFIG_IP_ROUTE_MULTIPATH
- if (force > 1 && nh->nh_dev == dev) {
- dead = fi->fib_nhs;
- break;
- }
-#endif
- } endfor_nexthops(fi)
- if (dead == fi->fib_nhs) {
- fi->fib_flags |= RTNH_F_DEAD;
- ret++;
+ if (force > 1 && nh->nh_dev == dev) {
+ dead = fi->fib_nhs;
+ break;
}
+#endif
+ } endfor_nexthops(fi)
+ if (dead == fi->fib_nhs) {
+ fi->fib_flags |= RTNH_F_DEAD;
+ ret++;
}
}
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index f2f47033f31..35851c96bdf 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1205,20 +1205,45 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
* and we need to allocate a new one of those as well.
*/
- if (fa && fa->fa_info->fib_priority == fi->fib_priority) {
- struct fib_alias *fa_orig;
+ if (fa && fa->fa_tos == tos &&
+ fa->fa_info->fib_priority == fi->fib_priority) {
+ struct fib_alias *fa_first, *fa_match;
err = -EEXIST;
if (cfg->fc_nlflags & NLM_F_EXCL)
goto out;
+ /* We have 2 goals:
+ * 1. Find exact match for type, scope, fib_info to avoid
+ * duplicate routes
+ * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it
+ */
+ fa_match = NULL;
+ fa_first = fa;
+ fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
+ list_for_each_entry_continue(fa, fa_head, fa_list) {
+ if (fa->fa_tos != tos)
+ break;
+ if (fa->fa_info->fib_priority != fi->fib_priority)
+ break;
+ if (fa->fa_type == cfg->fc_type &&
+ fa->fa_scope == cfg->fc_scope &&
+ fa->fa_info == fi) {
+ fa_match = fa;
+ break;
+ }
+ }
+
if (cfg->fc_nlflags & NLM_F_REPLACE) {
struct fib_info *fi_drop;
u8 state;
- if (fi->fib_treeref > 1)
+ fa = fa_first;
+ if (fa_match) {
+ if (fa == fa_match)
+ err = 0;
goto out;
-
+ }
err = -ENOBUFS;
new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
if (new_fa == NULL)
@@ -1230,7 +1255,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
new_fa->fa_type = cfg->fc_type;
new_fa->fa_scope = cfg->fc_scope;
state = fa->fa_state;
- new_fa->fa_state &= ~FA_S_ACCESSED;
+ new_fa->fa_state = state & ~FA_S_ACCESSED;
list_replace_rcu(&fa->fa_list, &new_fa->fa_list);
alias_free_mem_rcu(fa);
@@ -1247,20 +1272,11 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
* uses the same scope, type, and nexthop
* information.
*/
- fa_orig = fa;
- list_for_each_entry(fa, fa_orig->fa_list.prev, fa_list) {
- if (fa->fa_tos != tos)
- break;
- if (fa->fa_info->fib_priority != fi->fib_priority)
- break;
- if (fa->fa_type == cfg->fc_type &&
- fa->fa_scope == cfg->fc_scope &&
- fa->fa_info == fi)
- goto out;
- }
+ if (fa_match)
+ goto out;
if (!(cfg->fc_nlflags & NLM_F_APPEND))
- fa = fa_orig;
+ fa = fa_first;
}
err = -ENOENT;
if (!(cfg->fc_nlflags & NLM_F_CREATE))
@@ -1600,9 +1616,8 @@ static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg)
pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t);
fa_to_delete = NULL;
- fa_head = fa->fa_list.prev;
-
- list_for_each_entry(fa, fa_head, fa_list) {
+ fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
+ list_for_each_entry_continue(fa, fa_head, fa_list) {
struct fib_info *fi = fa->fa_info;
if (fa->fa_tos != tos)
@@ -1743,6 +1758,19 @@ static struct leaf *trie_nextleaf(struct leaf *l)
return leaf_walk_rcu(p, c);
}
+static struct leaf *trie_leafindex(struct trie *t, int index)
+{
+ struct leaf *l = trie_firstleaf(t);
+
+ while (index-- > 0) {
+ l = trie_nextleaf(l);
+ if (!l)
+ break;
+ }
+ return l;
+}
+
+
/*
* Caller must hold RTNL.
*/
@@ -1848,7 +1876,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah,
struct fib_alias *fa;
__be32 xkey = htonl(key);
- s_i = cb->args[4];
+ s_i = cb->args[5];
i = 0;
/* rcu_read_lock is hold by caller */
@@ -1869,12 +1897,12 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah,
plen,
fa->fa_tos,
fa->fa_info, NLM_F_MULTI) < 0) {
- cb->args[4] = i;
+ cb->args[5] = i;
return -1;
}
i++;
}
- cb->args[4] = i;
+ cb->args[5] = i;
return skb->len;
}
@@ -1885,7 +1913,7 @@ static int fn_trie_dump_leaf(struct leaf *l, struct fib_table *tb,
struct hlist_node *node;
int i, s_i;
- s_i = cb->args[3];
+ s_i = cb->args[4];
i = 0;
/* rcu_read_lock is hold by caller */
@@ -1896,19 +1924,19 @@ static int fn_trie_dump_leaf(struct leaf *l, struct fib_table *tb,
}
if (i > s_i)
- cb->args[4] = 0;
+ cb->args[5] = 0;
if (list_empty(&li->falh))
continue;
if (fn_trie_dump_fa(l->key, li->plen, &li->falh, tb, skb, cb) < 0) {
- cb->args[3] = i;
+ cb->args[4] = i;
return -1;
}
i++;
}
- cb->args[3] = i;
+ cb->args[4] = i;
return skb->len;
}
@@ -1918,35 +1946,37 @@ static int fn_trie_dump(struct fib_table *tb, struct sk_buff *skb,
struct leaf *l;
struct trie *t = (struct trie *) tb->tb_data;
t_key key = cb->args[2];
+ int count = cb->args[3];
rcu_read_lock();
/* Dump starting at last key.
* Note: 0.0.0.0/0 (ie default) is first key.
*/
- if (!key)
+ if (count == 0)
l = trie_firstleaf(t);
else {
+ /* Normally, continue from last key, but if that is missing
+ * fallback to using slow rescan
+ */
l = fib_find_node(t, key);
- if (!l) {
- /* The table changed during the dump, rather than
- * giving partial data, just make application retry.
- */
- rcu_read_unlock();
- return -EBUSY;
- }
+ if (!l)
+ l = trie_leafindex(t, count);
}
while (l) {
cb->args[2] = l->key;
if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) {
+ cb->args[3] = count;
rcu_read_unlock();
return -1;
}
+ ++count;
l = trie_nextleaf(l);
- memset(&cb->args[3], 0,
- sizeof(cb->args) - 3*sizeof(cb->args[0]));
+ memset(&cb->args[4], 0,
+ sizeof(cb->args) - 4*sizeof(cb->args[0]));
}
+ cb->args[3] = count;
rcu_read_unlock();
return skb->len;
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 7801cceb2d1..de5a41de191 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -87,6 +87,7 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo,
struct hlist_node *node;
struct inet_bind_bucket *tb;
int ret;
+ struct net *net = sk->sk_net;
local_bh_disable();
if (!snum) {
@@ -100,7 +101,7 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo,
head = &hashinfo->bhash[inet_bhashfn(rover, hashinfo->bhash_size)];
spin_lock(&head->lock);
inet_bind_bucket_for_each(tb, node, &head->chain)
- if (tb->port == rover)
+ if (tb->ib_net == net && tb->port == rover)
goto next;
break;
next:
@@ -127,7 +128,7 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo,
head = &hashinfo->bhash[inet_bhashfn(snum, hashinfo->bhash_size)];
spin_lock(&head->lock);
inet_bind_bucket_for_each(tb, node, &head->chain)
- if (tb->port == snum)
+ if (tb->ib_net == net && tb->port == snum)
goto tb_found;
}
tb = NULL;
@@ -147,7 +148,8 @@ tb_found:
}
tb_not_found:
ret = 1;
- if (!tb && (tb = inet_bind_bucket_create(hashinfo->bind_bucket_cachep, head, snum)) == NULL)
+ if (!tb && (tb = inet_bind_bucket_create(hashinfo->bind_bucket_cachep,
+ net, head, snum)) == NULL)
goto fail_unlock;
if (hlist_empty(&tb->owners)) {
if (sk->sk_reuse && sk->sk_state != TCP_LISTEN)
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 605ed2cd797..da97695e709 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -259,20 +259,22 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
const struct inet_diag_handler *handler;
handler = inet_diag_lock_handler(nlh->nlmsg_type);
- if (!handler)
- return -ENOENT;
+ if (IS_ERR(handler)) {
+ err = PTR_ERR(handler);
+ goto unlock;
+ }
hashinfo = handler->idiag_hashinfo;
err = -EINVAL;
if (req->idiag_family == AF_INET) {
- sk = inet_lookup(hashinfo, req->id.idiag_dst[0],
+ sk = inet_lookup(&init_net, hashinfo, req->id.idiag_dst[0],
req->id.idiag_dport, req->id.idiag_src[0],
req->id.idiag_sport, req->id.idiag_if);
}
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
else if (req->idiag_family == AF_INET6) {
- sk = inet6_lookup(hashinfo,
+ sk = inet6_lookup(&init_net, hashinfo,
(struct in6_addr *)req->id.idiag_dst,
req->id.idiag_dport,
(struct in6_addr *)req->id.idiag_src,
@@ -708,8 +710,8 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
struct inet_hashinfo *hashinfo;
handler = inet_diag_lock_handler(cb->nlh->nlmsg_type);
- if (!handler)
- goto no_handler;
+ if (IS_ERR(handler))
+ goto unlock;
hashinfo = handler->idiag_hashinfo;
@@ -838,7 +840,6 @@ done:
cb->args[2] = num;
unlock:
inet_diag_unlock_handler(handler);
-no_handler:
return skb->len;
}
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 619c63c6948..48d45008f74 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -28,12 +28,14 @@
* The bindhash mutex for snum's hash chain must be held here.
*/
struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
+ struct net *net,
struct inet_bind_hashbucket *head,
const unsigned short snum)
{
struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC);
if (tb != NULL) {
+ tb->ib_net = net;
tb->port = snum;
tb->fastreuse = 0;
INIT_HLIST_HEAD(&tb->owners);
@@ -125,7 +127,8 @@ EXPORT_SYMBOL(inet_listen_wlock);
* remote address for the connection. So always assume those are both
* wildcarded during the search since they can never be otherwise.
*/
-static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
+static struct sock *inet_lookup_listener_slow(struct net *net,
+ const struct hlist_head *head,
const __be32 daddr,
const unsigned short hnum,
const int dif)
@@ -137,7 +140,8 @@ static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
sk_for_each(sk, node, head) {
const struct inet_sock *inet = inet_sk(sk);
- if (inet->num == hnum && !ipv6_only_sock(sk)) {
+ if (sk->sk_net == net && inet->num == hnum &&
+ !ipv6_only_sock(sk)) {
const __be32 rcv_saddr = inet->rcv_saddr;
int score = sk->sk_family == PF_INET ? 1 : 0;
@@ -163,7 +167,8 @@ static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
}
/* Optimize the common listener case. */
-struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
+struct sock *__inet_lookup_listener(struct net *net,
+ struct inet_hashinfo *hashinfo,
const __be32 daddr, const unsigned short hnum,
const int dif)
{
@@ -178,9 +183,9 @@ struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
if (inet->num == hnum && !sk->sk_node.next &&
(!inet->rcv_saddr || inet->rcv_saddr == daddr) &&
(sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
- !sk->sk_bound_dev_if)
+ !sk->sk_bound_dev_if && sk->sk_net == net)
goto sherry_cache;
- sk = inet_lookup_listener_slow(head, daddr, hnum, dif);
+ sk = inet_lookup_listener_slow(net, head, daddr, hnum, dif);
}
if (sk) {
sherry_cache:
@@ -191,7 +196,8 @@ sherry_cache:
}
EXPORT_SYMBOL_GPL(__inet_lookup_listener);
-struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
+struct sock * __inet_lookup_established(struct net *net,
+ struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const u16 hnum,
const int dif)
@@ -210,13 +216,15 @@ struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
prefetch(head->chain.first);
read_lock(lock);
sk_for_each(sk, node, &head->chain) {
- if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
+ if (INET_MATCH(sk, net, hash, acookie,
+ saddr, daddr, ports, dif))
goto hit; /* You sunk my battleship! */
}
/* Must check for a TIME_WAIT'er before going to listener hash. */
sk_for_each(sk, node, &head->twchain) {
- if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
+ if (INET_TW_MATCH(sk, net, hash, acookie,
+ saddr, daddr, ports, dif))
goto hit;
}
sk = NULL;
@@ -247,6 +255,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
struct sock *sk2;
const struct hlist_node *node;
struct inet_timewait_sock *tw;
+ struct net *net = sk->sk_net;
prefetch(head->chain.first);
write_lock(lock);
@@ -255,7 +264,8 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
sk_for_each(sk2, node, &head->twchain) {
tw = inet_twsk(sk2);
- if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {
+ if (INET_TW_MATCH(sk2, net, hash, acookie,
+ saddr, daddr, ports, dif)) {
if (twsk_unique(sk, sk2, twp))
goto unique;
else
@@ -266,7 +276,8 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
/* And established part... */
sk_for_each(sk2, node, &head->chain) {
- if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
+ if (INET_MATCH(sk2, net, hash, acookie,
+ saddr, daddr, ports, dif))
goto not_unique;
}
@@ -348,17 +359,18 @@ void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk)
}
EXPORT_SYMBOL_GPL(__inet_hash);
-/*
- * Bind a port for a connect operation and hash it.
- */
-int inet_hash_connect(struct inet_timewait_death_row *death_row,
- struct sock *sk)
+int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+ struct sock *sk,
+ int (*check_established)(struct inet_timewait_death_row *,
+ struct sock *, __u16, struct inet_timewait_sock **),
+ void (*hash)(struct inet_hashinfo *, struct sock *))
{
struct inet_hashinfo *hinfo = death_row->hashinfo;
const unsigned short snum = inet_sk(sk)->num;
struct inet_bind_hashbucket *head;
struct inet_bind_bucket *tb;
int ret;
+ struct net *net = sk->sk_net;
if (!snum) {
int i, remaining, low, high, port;
@@ -381,19 +393,19 @@ int inet_hash_connect(struct inet_timewait_death_row *death_row,
* unique enough.
*/
inet_bind_bucket_for_each(tb, node, &head->chain) {
- if (tb->port == port) {
+ if (tb->ib_net == net && tb->port == port) {
BUG_TRAP(!hlist_empty(&tb->owners));
if (tb->fastreuse >= 0)
goto next_port;
- if (!__inet_check_established(death_row,
- sk, port,
- &tw))
+ if (!check_established(death_row, sk,
+ port, &tw))
goto ok;
goto next_port;
}
}
- tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep, head, port);
+ tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
+ net, head, port);
if (!tb) {
spin_unlock(&head->lock);
break;
@@ -415,7 +427,7 @@ ok:
inet_bind_hash(sk, tb, port);
if (sk_unhashed(sk)) {
inet_sk(sk)->sport = htons(port);
- __inet_hash_nolisten(hinfo, sk);
+ hash(hinfo, sk);
}
spin_unlock(&head->lock);
@@ -432,17 +444,28 @@ ok:
tb = inet_csk(sk)->icsk_bind_hash;
spin_lock_bh(&head->lock);
if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
- __inet_hash_nolisten(hinfo, sk);
+ hash(hinfo, sk);
spin_unlock_bh(&head->lock);
return 0;
} else {
spin_unlock(&head->lock);
/* No definite answer... Walk to established hash table */
- ret = __inet_check_established(death_row, sk, snum, NULL);
+ ret = check_established(death_row, sk, snum, NULL);
out:
local_bh_enable();
return ret;
}
}
+EXPORT_SYMBOL_GPL(__inet_hash_connect);
+
+/*
+ * Bind a port for a connect operation and hash it.
+ */
+int inet_hash_connect(struct inet_timewait_death_row *death_row,
+ struct sock *sk)
+{
+ return __inet_hash_connect(death_row, sk,
+ __inet_check_established, __inet_hash_nolisten);
+}
EXPORT_SYMBOL_GPL(inet_hash_connect);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 18070ca6577..341779e685d 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -168,6 +168,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
}
skb->priority = sk->sk_priority;
+ skb->mark = sk->sk_mark;
/* Send it out. */
return ip_local_out(skb);
@@ -385,6 +386,7 @@ packet_routed:
(skb_shinfo(skb)->gso_segs ?: 1) - 1);
skb->priority = sk->sk_priority;
+ skb->mark = sk->sk_mark;
return ip_local_out(skb);
@@ -476,6 +478,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
if (skb_shinfo(skb)->frag_list) {
struct sk_buff *frag;
int first_len = skb_pagelen(skb);
+ int truesizes = 0;
if (first_len - hlen > mtu ||
((first_len - hlen) & 7) ||
@@ -499,7 +502,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
sock_hold(skb->sk);
frag->sk = skb->sk;
frag->destructor = sock_wfree;
- skb->truesize -= frag->truesize;
+ truesizes += frag->truesize;
}
}
@@ -510,6 +513,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
frag = skb_shinfo(skb)->frag_list;
skb_shinfo(skb)->frag_list = NULL;
skb->data_len = first_len - skb_headlen(skb);
+ skb->truesize -= truesizes;
skb->len = first_len;
iph->tot_len = htons(first_len);
iph->frag_off = htons(IP_MF);
@@ -1284,6 +1288,7 @@ int ip_push_pending_frames(struct sock *sk)
iph->daddr = rt->rt_dst;
skb->priority = sk->sk_priority;
+ skb->mark = sk->sk_mark;
skb->dst = dst_clone(&rt->u.dst);
if (iph->protocol == IPPROTO_ICMP)
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index f4af99ad8fd..ae1f45fc23b 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -74,6 +74,7 @@ out:
static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
{
+ int nexthdr;
int err = -ENOMEM;
struct ip_comp_hdr *ipch;
@@ -84,13 +85,15 @@ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
/* Remove ipcomp header and decompress original payload */
ipch = (void *)skb->data;
+ nexthdr = ipch->nexthdr;
+
skb->transport_header = skb->network_header + sizeof(*ipch);
__skb_pull(skb, sizeof(*ipch));
err = ipcomp_decompress(x, skb);
if (err)
goto out;
- err = ipch->nexthdr;
+ err = nexthdr;
out:
return err;
@@ -434,7 +437,7 @@ error:
goto out;
}
-static struct xfrm_type ipcomp_type = {
+static const struct xfrm_type ipcomp_type = {
.description = "IPCOMP4",
.owner = THIS_MODULE,
.proto = IPPROTO_COMP,
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index b4a810c28ac..a7591ce344d 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -22,6 +22,7 @@
#include <linux/mutex.h>
#include <linux/err.h>
#include <net/compat.h>
+#include <net/sock.h>
#include <asm/uaccess.h>
#include <linux/netfilter/x_tables.h>
@@ -850,7 +851,7 @@ static int compat_table_info(const struct xt_table_info *info,
}
#endif
-static int get_info(void __user *user, int *len, int compat)
+static int get_info(struct net *net, void __user *user, int *len, int compat)
{
char name[ARPT_TABLE_MAXNAMELEN];
struct arpt_table *t;
@@ -870,7 +871,7 @@ static int get_info(void __user *user, int *len, int compat)
if (compat)
xt_compat_lock(NF_ARP);
#endif
- t = try_then_request_module(xt_find_table_lock(NF_ARP, name),
+ t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name),
"arptable_%s", name);
if (t && !IS_ERR(t)) {
struct arpt_getinfo info;
@@ -908,7 +909,8 @@ static int get_info(void __user *user, int *len, int compat)
return ret;
}
-static int get_entries(struct arpt_get_entries __user *uptr, int *len)
+static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
+ int *len)
{
int ret;
struct arpt_get_entries get;
@@ -926,7 +928,7 @@ static int get_entries(struct arpt_get_entries __user *uptr, int *len)
return -EINVAL;
}
- t = xt_find_table_lock(NF_ARP, get.name);
+ t = xt_find_table_lock(net, NF_ARP, get.name);
if (t && !IS_ERR(t)) {
struct xt_table_info *private = t->private;
duprintf("t->private->number = %u\n",
@@ -947,7 +949,8 @@ static int get_entries(struct arpt_get_entries __user *uptr, int *len)
return ret;
}
-static int __do_replace(const char *name, unsigned int valid_hooks,
+static int __do_replace(struct net *net, const char *name,
+ unsigned int valid_hooks,
struct xt_table_info *newinfo,
unsigned int num_counters,
void __user *counters_ptr)
@@ -966,7 +969,7 @@ static int __do_replace(const char *name, unsigned int valid_hooks,
goto out;
}
- t = try_then_request_module(xt_find_table_lock(NF_ARP, name),
+ t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name),
"arptable_%s", name);
if (!t || IS_ERR(t)) {
ret = t ? PTR_ERR(t) : -ENOENT;
@@ -1019,7 +1022,7 @@ static int __do_replace(const char *name, unsigned int valid_hooks,
return ret;
}
-static int do_replace(void __user *user, unsigned int len)
+static int do_replace(struct net *net, void __user *user, unsigned int len)
{
int ret;
struct arpt_replace tmp;
@@ -1053,7 +1056,7 @@ static int do_replace(void __user *user, unsigned int len)
duprintf("arp_tables: Translated table\n");
- ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+ ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
tmp.num_counters, tmp.counters);
if (ret)
goto free_newinfo_untrans;
@@ -1080,7 +1083,8 @@ static inline int add_counter_to_entry(struct arpt_entry *e,
return 0;
}
-static int do_add_counters(void __user *user, unsigned int len, int compat)
+static int do_add_counters(struct net *net, void __user *user, unsigned int len,
+ int compat)
{
unsigned int i;
struct xt_counters_info tmp;
@@ -1132,7 +1136,7 @@ static int do_add_counters(void __user *user, unsigned int len, int compat)
goto free;
}
- t = xt_find_table_lock(NF_ARP, name);
+ t = xt_find_table_lock(net, NF_ARP, name);
if (!t || IS_ERR(t)) {
ret = t ? PTR_ERR(t) : -ENOENT;
goto free;
@@ -1435,7 +1439,8 @@ struct compat_arpt_replace {
struct compat_arpt_entry entries[0];
};
-static int compat_do_replace(void __user *user, unsigned int len)
+static int compat_do_replace(struct net *net, void __user *user,
+ unsigned int len)
{
int ret;
struct compat_arpt_replace tmp;
@@ -1471,7 +1476,7 @@ static int compat_do_replace(void __user *user, unsigned int len)
duprintf("compat_do_replace: Translated table\n");
- ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+ ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
tmp.num_counters, compat_ptr(tmp.counters));
if (ret)
goto free_newinfo_untrans;
@@ -1494,11 +1499,11 @@ static int compat_do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user,
switch (cmd) {
case ARPT_SO_SET_REPLACE:
- ret = compat_do_replace(user, len);
+ ret = compat_do_replace(sk->sk_net, user, len);
break;
case ARPT_SO_SET_ADD_COUNTERS:
- ret = do_add_counters(user, len, 1);
+ ret = do_add_counters(sk->sk_net, user, len, 1);
break;
default:
@@ -1584,7 +1589,8 @@ struct compat_arpt_get_entries {
struct compat_arpt_entry entrytable[0];
};
-static int compat_get_entries(struct compat_arpt_get_entries __user *uptr,
+static int compat_get_entries(struct net *net,
+ struct compat_arpt_get_entries __user *uptr,
int *len)
{
int ret;
@@ -1604,7 +1610,7 @@ static int compat_get_entries(struct compat_arpt_get_entries __user *uptr,
}
xt_compat_lock(NF_ARP);
- t = xt_find_table_lock(NF_ARP, get.name);
+ t = xt_find_table_lock(net, NF_ARP, get.name);
if (t && !IS_ERR(t)) {
struct xt_table_info *private = t->private;
struct xt_table_info info;
@@ -1641,10 +1647,10 @@ static int compat_do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user,
switch (cmd) {
case ARPT_SO_GET_INFO:
- ret = get_info(user, len, 1);
+ ret = get_info(sk->sk_net, user, len, 1);
break;
case ARPT_SO_GET_ENTRIES:
- ret = compat_get_entries(user, len);
+ ret = compat_get_entries(sk->sk_net, user, len);
break;
default:
ret = do_arpt_get_ctl(sk, cmd, user, len);
@@ -1662,11 +1668,11 @@ static int do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned
switch (cmd) {
case ARPT_SO_SET_REPLACE:
- ret = do_replace(user, len);
+ ret = do_replace(sk->sk_net, user, len);
break;
case ARPT_SO_SET_ADD_COUNTERS:
- ret = do_add_counters(user, len, 0);
+ ret = do_add_counters(sk->sk_net, user, len, 0);
break;
default:
@@ -1686,11 +1692,11 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
switch (cmd) {
case ARPT_SO_GET_INFO:
- ret = get_info(user, len, 0);
+ ret = get_info(sk->sk_net, user, len, 0);
break;
case ARPT_SO_GET_ENTRIES:
- ret = get_entries(user, len);
+ ret = get_entries(sk->sk_net, user, len);
break;
case ARPT_SO_GET_REVISION_TARGET: {
@@ -1719,19 +1725,21 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
return ret;
}
-int arpt_register_table(struct arpt_table *table,
- const struct arpt_replace *repl)
+struct arpt_table *arpt_register_table(struct net *net,
+ struct arpt_table *table,
+ const struct arpt_replace *repl)
{
int ret;
struct xt_table_info *newinfo;
struct xt_table_info bootstrap
= { 0, 0, 0, { 0 }, { 0 }, { } };
void *loc_cpu_entry;
+ struct xt_table *new_table;
newinfo = xt_alloc_table_info(repl->size);
if (!newinfo) {
ret = -ENOMEM;
- return ret;
+ goto out;
}
/* choose the copy on our node/cpu */
@@ -1745,24 +1753,27 @@ int arpt_register_table(struct arpt_table *table,
repl->underflow);
duprintf("arpt_register_table: translate table gives %d\n", ret);
- if (ret != 0) {
- xt_free_table_info(newinfo);
- return ret;
- }
+ if (ret != 0)
+ goto out_free;
- ret = xt_register_table(table, &bootstrap, newinfo);
- if (ret != 0) {
- xt_free_table_info(newinfo);
- return ret;
+ new_table = xt_register_table(net, table, &bootstrap, newinfo);
+ if (IS_ERR(new_table)) {
+ ret = PTR_ERR(new_table);
+ goto out_free;
}
+ return new_table;
- return 0;
+out_free:
+ xt_free_table_info(newinfo);
+out:
+ return ERR_PTR(ret);
}
void arpt_unregister_table(struct arpt_table *table)
{
struct xt_table_info *private;
void *loc_cpu_entry;
+ struct module *table_owner = table->me;
private = xt_unregister_table(table);
@@ -1770,6 +1781,8 @@ void arpt_unregister_table(struct arpt_table *table)
loc_cpu_entry = private->entries[raw_smp_processor_id()];
ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size,
cleanup_entry, NULL);
+ if (private->number > private->initial_entries)
+ module_put(table_owner);
xt_free_table_info(private);
}
@@ -1809,11 +1822,26 @@ static struct nf_sockopt_ops arpt_sockopts = {
.owner = THIS_MODULE,
};
+static int __net_init arp_tables_net_init(struct net *net)
+{
+ return xt_proto_init(net, NF_ARP);
+}
+
+static void __net_exit arp_tables_net_exit(struct net *net)
+{
+ xt_proto_fini(net, NF_ARP);
+}
+
+static struct pernet_operations arp_tables_net_ops = {
+ .init = arp_tables_net_init,
+ .exit = arp_tables_net_exit,
+};
+
static int __init arp_tables_init(void)
{
int ret;
- ret = xt_proto_init(NF_ARP);
+ ret = register_pernet_subsys(&arp_tables_net_ops);
if (ret < 0)
goto err1;
@@ -1838,7 +1866,7 @@ err4:
err3:
xt_unregister_target(&arpt_standard_target);
err2:
- xt_proto_fini(NF_ARP);
+ unregister_pernet_subsys(&arp_tables_net_ops);
err1:
return ret;
}
@@ -1848,7 +1876,7 @@ static void __exit arp_tables_fini(void)
nf_unregister_sockopt(&arpt_sockopts);
xt_unregister_target(&arpt_error_target);
xt_unregister_target(&arpt_standard_target);
- xt_proto_fini(NF_ARP);
+ unregister_pernet_subsys(&arp_tables_net_ops);
}
EXPORT_SYMBOL(arpt_register_table);
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
index 7201511d54d..4e9c496a30c 100644
--- a/net/ipv4/netfilter/arptable_filter.c
+++ b/net/ipv4/netfilter/arptable_filter.c
@@ -20,7 +20,7 @@ static struct
struct arpt_replace repl;
struct arpt_standard entries[3];
struct arpt_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
.repl = {
.name = "filter",
.valid_hooks = FILTER_VALID_HOOKS,
@@ -61,7 +61,7 @@ static unsigned int arpt_hook(unsigned int hook,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return arpt_do_table(skb, hook, in, out, &packet_filter);
+ return arpt_do_table(skb, hook, in, out, init_net.ipv4.arptable_filter);
}
static struct nf_hook_ops arpt_ops[] __read_mostly = {
@@ -85,12 +85,31 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = {
},
};
+static int __net_init arptable_filter_net_init(struct net *net)
+{
+ /* Register table */
+ net->ipv4.arptable_filter =
+ arpt_register_table(net, &packet_filter, &initial_table.repl);
+ if (IS_ERR(net->ipv4.arptable_filter))
+ return PTR_ERR(net->ipv4.arptable_filter);
+ return 0;
+}
+
+static void __net_exit arptable_filter_net_exit(struct net *net)
+{
+ arpt_unregister_table(net->ipv4.arptable_filter);
+}
+
+static struct pernet_operations arptable_filter_net_ops = {
+ .init = arptable_filter_net_init,
+ .exit = arptable_filter_net_exit,
+};
+
static int __init arptable_filter_init(void)
{
int ret;
- /* Register table */
- ret = arpt_register_table(&packet_filter, &initial_table.repl);
+ ret = register_pernet_subsys(&arptable_filter_net_ops);
if (ret < 0)
return ret;
@@ -100,14 +119,14 @@ static int __init arptable_filter_init(void)
return ret;
cleanup_table:
- arpt_unregister_table(&packet_filter);
+ unregister_pernet_subsys(&arptable_filter_net_ops);
return ret;
}
static void __exit arptable_filter_fini(void)
{
nf_unregister_hooks(arpt_ops, ARRAY_SIZE(arpt_ops));
- arpt_unregister_table(&packet_filter);
+ unregister_pernet_subsys(&arptable_filter_net_ops);
}
module_init(arptable_filter_init);
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 5109839da22..6bda1102851 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -512,6 +512,7 @@ static struct notifier_block ipq_nl_notifier = {
.notifier_call = ipq_rcv_nl_event,
};
+#ifdef CONFIG_SYSCTL
static struct ctl_table_header *ipq_sysctl_header;
static ctl_table ipq_table[] = {
@@ -525,7 +526,9 @@ static ctl_table ipq_table[] = {
},
{ .ctl_name = 0 }
};
+#endif
+#ifdef CONFIG_PROC_FS
static int ip_queue_show(struct seq_file *m, void *v)
{
read_lock_bh(&queue_lock);
@@ -562,6 +565,7 @@ static const struct file_operations ip_queue_proc_fops = {
.release = single_release,
.owner = THIS_MODULE,
};
+#endif
static const struct nf_queue_handler nfqh = {
.name = "ip_queue",
@@ -571,7 +575,7 @@ static const struct nf_queue_handler nfqh = {
static int __init ip_queue_init(void)
{
int status = -ENOMEM;
- struct proc_dir_entry *proc;
+ struct proc_dir_entry *proc __maybe_unused;
netlink_register_notifier(&ipq_nl_notifier);
ipqnl = netlink_kernel_create(&init_net, NETLINK_FIREWALL, 0,
@@ -581,6 +585,7 @@ static int __init ip_queue_init(void)
goto cleanup_netlink_notifier;
}
+#ifdef CONFIG_PROC_FS
proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net);
if (proc) {
proc->owner = THIS_MODULE;
@@ -589,10 +594,11 @@ static int __init ip_queue_init(void)
printk(KERN_ERR "ip_queue: failed to create proc entry\n");
goto cleanup_ipqnl;
}
-
+#endif
register_netdevice_notifier(&ipq_dev_notifier);
+#ifdef CONFIG_SYSCTL
ipq_sysctl_header = register_sysctl_paths(net_ipv4_ctl_path, ipq_table);
-
+#endif
status = nf_register_queue_handler(PF_INET, &nfqh);
if (status < 0) {
printk(KERN_ERR "ip_queue: failed to register queue handler\n");
@@ -601,10 +607,12 @@ static int __init ip_queue_init(void)
return status;
cleanup_sysctl:
+#ifdef CONFIG_SYSCTL
unregister_sysctl_table(ipq_sysctl_header);
+#endif
unregister_netdevice_notifier(&ipq_dev_notifier);
proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
-cleanup_ipqnl:
+cleanup_ipqnl: __maybe_unused
netlink_kernel_release(ipqnl);
mutex_lock(&ipqnl_mutex);
mutex_unlock(&ipqnl_mutex);
@@ -620,7 +628,9 @@ static void __exit ip_queue_fini(void)
synchronize_net();
ipq_flush(NULL, 0);
+#ifdef CONFIG_SYSCTL
unregister_sysctl_table(ipq_sysctl_header);
+#endif
unregister_netdevice_notifier(&ipq_dev_notifier);
proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 982b7f98629..600737f122d 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -291,7 +291,7 @@ static void trace_packet(struct sk_buff *skb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
- char *tablename,
+ const char *tablename,
struct xt_table_info *private,
struct ipt_entry *e)
{
@@ -1092,7 +1092,7 @@ static int compat_table_info(const struct xt_table_info *info,
}
#endif
-static int get_info(void __user *user, int *len, int compat)
+static int get_info(struct net *net, void __user *user, int *len, int compat)
{
char name[IPT_TABLE_MAXNAMELEN];
struct xt_table *t;
@@ -1112,7 +1112,7 @@ static int get_info(void __user *user, int *len, int compat)
if (compat)
xt_compat_lock(AF_INET);
#endif
- t = try_then_request_module(xt_find_table_lock(AF_INET, name),
+ t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
"iptable_%s", name);
if (t && !IS_ERR(t)) {
struct ipt_getinfo info;
@@ -1152,7 +1152,7 @@ static int get_info(void __user *user, int *len, int compat)
}
static int
-get_entries(struct ipt_get_entries __user *uptr, int *len)
+get_entries(struct net *net, struct ipt_get_entries __user *uptr, int *len)
{
int ret;
struct ipt_get_entries get;
@@ -1170,7 +1170,7 @@ get_entries(struct ipt_get_entries __user *uptr, int *len)
return -EINVAL;
}
- t = xt_find_table_lock(AF_INET, get.name);
+ t = xt_find_table_lock(net, AF_INET, get.name);
if (t && !IS_ERR(t)) {
struct xt_table_info *private = t->private;
duprintf("t->private->number = %u\n", private->number);
@@ -1191,7 +1191,7 @@ get_entries(struct ipt_get_entries __user *uptr, int *len)
}
static int
-__do_replace(const char *name, unsigned int valid_hooks,
+__do_replace(struct net *net, const char *name, unsigned int valid_hooks,
struct xt_table_info *newinfo, unsigned int num_counters,
void __user *counters_ptr)
{
@@ -1208,7 +1208,7 @@ __do_replace(const char *name, unsigned int valid_hooks,
goto out;
}
- t = try_then_request_module(xt_find_table_lock(AF_INET, name),
+ t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
"iptable_%s", name);
if (!t || IS_ERR(t)) {
ret = t ? PTR_ERR(t) : -ENOENT;
@@ -1261,7 +1261,7 @@ __do_replace(const char *name, unsigned int valid_hooks,
}
static int
-do_replace(void __user *user, unsigned int len)
+do_replace(struct net *net, void __user *user, unsigned int len)
{
int ret;
struct ipt_replace tmp;
@@ -1295,7 +1295,7 @@ do_replace(void __user *user, unsigned int len)
duprintf("ip_tables: Translated table\n");
- ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+ ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
tmp.num_counters, tmp.counters);
if (ret)
goto free_newinfo_untrans;
@@ -1331,7 +1331,7 @@ add_counter_to_entry(struct ipt_entry *e,
}
static int
-do_add_counters(void __user *user, unsigned int len, int compat)
+do_add_counters(struct net *net, void __user *user, unsigned int len, int compat)
{
unsigned int i;
struct xt_counters_info tmp;
@@ -1383,7 +1383,7 @@ do_add_counters(void __user *user, unsigned int len, int compat)
goto free;
}
- t = xt_find_table_lock(AF_INET, name);
+ t = xt_find_table_lock(net, AF_INET, name);
if (!t || IS_ERR(t)) {
ret = t ? PTR_ERR(t) : -ENOENT;
goto free;
@@ -1429,7 +1429,7 @@ struct compat_ipt_replace {
static int
compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
- compat_uint_t *size, struct xt_counters *counters,
+ unsigned int *size, struct xt_counters *counters,
unsigned int *i)
{
struct ipt_entry_target *t;
@@ -1476,7 +1476,7 @@ compat_find_calc_match(struct ipt_entry_match *m,
const char *name,
const struct ipt_ip *ip,
unsigned int hookmask,
- int *size, int *i)
+ int *size, unsigned int *i)
{
struct xt_match *match;
@@ -1534,7 +1534,8 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
struct ipt_entry_target *t;
struct xt_target *target;
unsigned int entry_offset;
- int ret, off, h, j;
+ unsigned int j;
+ int ret, off, h;
duprintf("check_compat_entry_size_and_hooks %p\n", e);
if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0
@@ -1647,7 +1648,8 @@ static int
compat_check_entry(struct ipt_entry *e, const char *name,
unsigned int *i)
{
- int j, ret;
+ unsigned int j;
+ int ret;
j = 0;
ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip,
@@ -1789,7 +1791,7 @@ out_unlock:
}
static int
-compat_do_replace(void __user *user, unsigned int len)
+compat_do_replace(struct net *net, void __user *user, unsigned int len)
{
int ret;
struct compat_ipt_replace tmp;
@@ -1826,7 +1828,7 @@ compat_do_replace(void __user *user, unsigned int len)
duprintf("compat_do_replace: Translated table\n");
- ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+ ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
tmp.num_counters, compat_ptr(tmp.counters));
if (ret)
goto free_newinfo_untrans;
@@ -1850,11 +1852,11 @@ compat_do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user,
switch (cmd) {
case IPT_SO_SET_REPLACE:
- ret = compat_do_replace(user, len);
+ ret = compat_do_replace(sk->sk_net, user, len);
break;
case IPT_SO_SET_ADD_COUNTERS:
- ret = do_add_counters(user, len, 1);
+ ret = do_add_counters(sk->sk_net, user, len, 1);
break;
default:
@@ -1903,7 +1905,8 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
}
static int
-compat_get_entries(struct compat_ipt_get_entries __user *uptr, int *len)
+compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
+ int *len)
{
int ret;
struct compat_ipt_get_entries get;
@@ -1924,7 +1927,7 @@ compat_get_entries(struct compat_ipt_get_entries __user *uptr, int *len)
}
xt_compat_lock(AF_INET);
- t = xt_find_table_lock(AF_INET, get.name);
+ t = xt_find_table_lock(net, AF_INET, get.name);
if (t && !IS_ERR(t)) {
struct xt_table_info *private = t->private;
struct xt_table_info info;
@@ -1960,10 +1963,10 @@ compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
switch (cmd) {
case IPT_SO_GET_INFO:
- ret = get_info(user, len, 1);
+ ret = get_info(sk->sk_net, user, len, 1);
break;
case IPT_SO_GET_ENTRIES:
- ret = compat_get_entries(user, len);
+ ret = compat_get_entries(sk->sk_net, user, len);
break;
default:
ret = do_ipt_get_ctl(sk, cmd, user, len);
@@ -1982,11 +1985,11 @@ do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
switch (cmd) {
case IPT_SO_SET_REPLACE:
- ret = do_replace(user, len);
+ ret = do_replace(sk->sk_net, user, len);
break;
case IPT_SO_SET_ADD_COUNTERS:
- ret = do_add_counters(user, len, 0);
+ ret = do_add_counters(sk->sk_net, user, len, 0);
break;
default:
@@ -2007,11 +2010,11 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
switch (cmd) {
case IPT_SO_GET_INFO:
- ret = get_info(user, len, 0);
+ ret = get_info(sk->sk_net, user, len, 0);
break;
case IPT_SO_GET_ENTRIES:
- ret = get_entries(user, len);
+ ret = get_entries(sk->sk_net, user, len);
break;
case IPT_SO_GET_REVISION_MATCH:
@@ -2048,17 +2051,21 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
return ret;
}
-int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl)
+struct xt_table *ipt_register_table(struct net *net, struct xt_table *table,
+ const struct ipt_replace *repl)
{
int ret;
struct xt_table_info *newinfo;
struct xt_table_info bootstrap
= { 0, 0, 0, { 0 }, { 0 }, { } };
void *loc_cpu_entry;
+ struct xt_table *new_table;
newinfo = xt_alloc_table_info(repl->size);
- if (!newinfo)
- return -ENOMEM;
+ if (!newinfo) {
+ ret = -ENOMEM;
+ goto out;
+ }
/* choose the copy on our node/cpu, but dont care about preemption */
loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
@@ -2069,30 +2076,36 @@ int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl)
repl->num_entries,
repl->hook_entry,
repl->underflow);
- if (ret != 0) {
- xt_free_table_info(newinfo);
- return ret;
- }
+ if (ret != 0)
+ goto out_free;
- ret = xt_register_table(table, &bootstrap, newinfo);
- if (ret != 0) {
- xt_free_table_info(newinfo);
- return ret;
+ new_table = xt_register_table(net, table, &bootstrap, newinfo);
+ if (IS_ERR(new_table)) {
+ ret = PTR_ERR(new_table);
+ goto out_free;
}
- return 0;
+ return new_table;
+
+out_free:
+ xt_free_table_info(newinfo);
+out:
+ return ERR_PTR(ret);
}
void ipt_unregister_table(struct xt_table *table)
{
struct xt_table_info *private;
void *loc_cpu_entry;
+ struct module *table_owner = table->me;
private = xt_unregister_table(table);
/* Decrease module usage counts and free resources */
loc_cpu_entry = private->entries[raw_smp_processor_id()];
IPT_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL);
+ if (private->number > private->initial_entries)
+ module_put(table_owner);
xt_free_table_info(private);
}
@@ -2200,11 +2213,26 @@ static struct xt_match icmp_matchstruct __read_mostly = {
.family = AF_INET,
};
+static int __net_init ip_tables_net_init(struct net *net)
+{
+ return xt_proto_init(net, AF_INET);
+}
+
+static void __net_exit ip_tables_net_exit(struct net *net)
+{
+ xt_proto_fini(net, AF_INET);
+}
+
+static struct pernet_operations ip_tables_net_ops = {
+ .init = ip_tables_net_init,
+ .exit = ip_tables_net_exit,
+};
+
static int __init ip_tables_init(void)
{
int ret;
- ret = xt_proto_init(AF_INET);
+ ret = register_pernet_subsys(&ip_tables_net_ops);
if (ret < 0)
goto err1;
@@ -2234,7 +2262,7 @@ err4:
err3:
xt_unregister_target(&ipt_standard_target);
err2:
- xt_proto_fini(AF_INET);
+ unregister_pernet_subsys(&ip_tables_net_ops);
err1:
return ret;
}
@@ -2247,7 +2275,7 @@ static void __exit ip_tables_fini(void)
xt_unregister_target(&ipt_error_target);
xt_unregister_target(&ipt_standard_target);
- xt_proto_fini(AF_INET);
+ unregister_pernet_subsys(&ip_tables_net_ops);
}
EXPORT_SYMBOL(ipt_register_table);
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 1b31f7d14d4..c6cf84c7761 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -76,13 +76,6 @@ clusterip_config_put(struct clusterip_config *c)
kfree(c);
}
-/* increase the count of entries(rules) using/referencing this config */
-static inline void
-clusterip_config_entry_get(struct clusterip_config *c)
-{
- atomic_inc(&c->entries);
-}
-
/* decrease the count of entries using/referencing this config. If last
* entry(rule) is removed, remove the config from lists, but don't free it
* yet, since proc-files could still be holding references */
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index e3154a99c08..68cbe3ca01c 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -212,11 +212,11 @@ recent_mt(const struct sk_buff *skb, const struct net_device *in,
recent_entry_remove(t, e);
ret = !ret;
} else if (info->check_set & (IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) {
- unsigned long t = jiffies - info->seconds * HZ;
+ unsigned long time = jiffies - info->seconds * HZ;
unsigned int i, hits = 0;
for (i = 0; i < e->nstamps; i++) {
- if (info->seconds && time_after(t, e->stamps[i]))
+ if (info->seconds && time_after(time, e->stamps[i]))
continue;
if (++hits >= info->hit_count) {
ret = !ret;
@@ -320,6 +320,7 @@ struct recent_iter_state {
};
static void *recent_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(recent_lock)
{
struct recent_iter_state *st = seq->private;
const struct recent_table *t = st->table;
@@ -352,6 +353,7 @@ static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void recent_seq_stop(struct seq_file *s, void *v)
+ __releases(recent_lock)
{
spin_unlock_bh(&recent_lock);
}
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index 29bb4f9fbda..69f3d7e6e96 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -28,7 +28,7 @@ static struct
struct ipt_replace repl;
struct ipt_standard entries[3];
struct ipt_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
.repl = {
.name = "filter",
.valid_hooks = FILTER_VALID_HOOKS,
@@ -69,7 +69,7 @@ ipt_hook(unsigned int hook,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return ipt_do_table(skb, hook, in, out, &packet_filter);
+ return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter);
}
static unsigned int
@@ -88,7 +88,7 @@ ipt_local_out_hook(unsigned int hook,
return NF_ACCEPT;
}
- return ipt_do_table(skb, hook, in, out, &packet_filter);
+ return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter);
}
static struct nf_hook_ops ipt_ops[] __read_mostly = {
@@ -119,6 +119,26 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
static int forward = NF_ACCEPT;
module_param(forward, bool, 0000);
+static int __net_init iptable_filter_net_init(struct net *net)
+{
+ /* Register table */
+ net->ipv4.iptable_filter =
+ ipt_register_table(net, &packet_filter, &initial_table.repl);
+ if (IS_ERR(net->ipv4.iptable_filter))
+ return PTR_ERR(net->ipv4.iptable_filter);
+ return 0;
+}
+
+static void __net_exit iptable_filter_net_exit(struct net *net)
+{
+ ipt_unregister_table(net->ipv4.iptable_filter);
+}
+
+static struct pernet_operations iptable_filter_net_ops = {
+ .init = iptable_filter_net_init,
+ .exit = iptable_filter_net_exit,
+};
+
static int __init iptable_filter_init(void)
{
int ret;
@@ -131,8 +151,7 @@ static int __init iptable_filter_init(void)
/* Entry 1 is the FORWARD hook */
initial_table.entries[1].target.verdict = -forward - 1;
- /* Register table */
- ret = ipt_register_table(&packet_filter, &initial_table.repl);
+ ret = register_pernet_subsys(&iptable_filter_net_ops);
if (ret < 0)
return ret;
@@ -144,14 +163,14 @@ static int __init iptable_filter_init(void)
return ret;
cleanup_table:
- ipt_unregister_table(&packet_filter);
+ unregister_pernet_subsys(&iptable_filter_net_ops);
return ret;
}
static void __exit iptable_filter_fini(void)
{
nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
- ipt_unregister_table(&packet_filter);
+ unregister_pernet_subsys(&iptable_filter_net_ops);
}
module_init(iptable_filter_init);
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index 5c4be202430..c55a210853a 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -33,7 +33,7 @@ static struct
struct ipt_replace repl;
struct ipt_standard entries[5];
struct ipt_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
.repl = {
.name = "mangle",
.valid_hooks = MANGLE_VALID_HOOKS,
@@ -80,7 +80,7 @@ ipt_route_hook(unsigned int hook,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return ipt_do_table(skb, hook, in, out, &packet_mangler);
+ return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle);
}
static unsigned int
@@ -112,7 +112,7 @@ ipt_local_hook(unsigned int hook,
daddr = iph->daddr;
tos = iph->tos;
- ret = ipt_do_table(skb, hook, in, out, &packet_mangler);
+ ret = ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle);
/* Reroute for ANY change. */
if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) {
iph = ip_hdr(skb);
@@ -166,12 +166,31 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
},
};
+static int __net_init iptable_mangle_net_init(struct net *net)
+{
+ /* Register table */
+ net->ipv4.iptable_mangle =
+ ipt_register_table(net, &packet_mangler, &initial_table.repl);
+ if (IS_ERR(net->ipv4.iptable_mangle))
+ return PTR_ERR(net->ipv4.iptable_mangle);
+ return 0;
+}
+
+static void __net_exit iptable_mangle_net_exit(struct net *net)
+{
+ ipt_unregister_table(net->ipv4.iptable_mangle);
+}
+
+static struct pernet_operations iptable_mangle_net_ops = {
+ .init = iptable_mangle_net_init,
+ .exit = iptable_mangle_net_exit,
+};
+
static int __init iptable_mangle_init(void)
{
int ret;
- /* Register table */
- ret = ipt_register_table(&packet_mangler, &initial_table.repl);
+ ret = register_pernet_subsys(&iptable_mangle_net_ops);
if (ret < 0)
return ret;
@@ -183,14 +202,14 @@ static int __init iptable_mangle_init(void)
return ret;
cleanup_table:
- ipt_unregister_table(&packet_mangler);
+ unregister_pernet_subsys(&iptable_mangle_net_ops);
return ret;
}
static void __exit iptable_mangle_fini(void)
{
nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
- ipt_unregister_table(&packet_mangler);
+ unregister_pernet_subsys(&iptable_mangle_net_ops);
}
module_init(iptable_mangle_init);
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index dc34aa27453..e41fe8ca4e1 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -14,7 +14,7 @@ static struct
struct ipt_replace repl;
struct ipt_standard entries[2];
struct ipt_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
.repl = {
.name = "raw",
.valid_hooks = RAW_VALID_HOOKS,
@@ -52,7 +52,7 @@ ipt_hook(unsigned int hook,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return ipt_do_table(skb, hook, in, out, &packet_raw);
+ return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw);
}
static unsigned int
@@ -70,7 +70,7 @@ ipt_local_hook(unsigned int hook,
"packet.\n");
return NF_ACCEPT;
}
- return ipt_do_table(skb, hook, in, out, &packet_raw);
+ return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw);
}
/* 'raw' is the very first table. */
@@ -91,12 +91,31 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
},
};
+static int __net_init iptable_raw_net_init(struct net *net)
+{
+ /* Register table */
+ net->ipv4.iptable_raw =
+ ipt_register_table(net, &packet_raw, &initial_table.repl);
+ if (IS_ERR(net->ipv4.iptable_raw))
+ return PTR_ERR(net->ipv4.iptable_raw);
+ return 0;
+}
+
+static void __net_exit iptable_raw_net_exit(struct net *net)
+{
+ ipt_unregister_table(net->ipv4.iptable_raw);
+}
+
+static struct pernet_operations iptable_raw_net_ops = {
+ .init = iptable_raw_net_init,
+ .exit = iptable_raw_net_exit,
+};
+
static int __init iptable_raw_init(void)
{
int ret;
- /* Register table */
- ret = ipt_register_table(&packet_raw, &initial_table.repl);
+ ret = register_pernet_subsys(&iptable_raw_net_ops);
if (ret < 0)
return ret;
@@ -108,14 +127,14 @@ static int __init iptable_raw_init(void)
return ret;
cleanup_table:
- ipt_unregister_table(&packet_raw);
+ unregister_pernet_subsys(&iptable_raw_net_ops);
return ret;
}
static void __exit iptable_raw_fini(void)
{
nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
- ipt_unregister_table(&packet_raw);
+ unregister_pernet_subsys(&iptable_raw_net_ops);
}
module_init(iptable_raw_init);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index ac3d61d8026..a65b845c5f1 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -27,7 +27,8 @@
static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
struct nf_conntrack_tuple *tuple)
{
- __be32 _addrs[2], *ap;
+ const __be32 *ap;
+ __be32 _addrs[2];
ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr),
sizeof(u_int32_t) * 2, _addrs);
if (ap == NULL)
@@ -76,7 +77,8 @@ static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
unsigned int *dataoff, u_int8_t *protonum)
{
- struct iphdr _iph, *iph;
+ const struct iphdr *iph;
+ struct iphdr _iph;
iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
if (iph == NULL)
@@ -111,8 +113,8 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
{
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
- struct nf_conn_help *help;
- struct nf_conntrack_helper *helper;
+ const struct nf_conn_help *help;
+ const struct nf_conntrack_helper *helper;
/* This is where we call the helper: as the packet goes out. */
ct = nf_ct_get(skb, &ctinfo);
@@ -299,8 +301,8 @@ static ctl_table ip_ct_sysctl_table[] = {
static int
getorigdst(struct sock *sk, int optval, void __user *user, int *len)
{
- struct inet_sock *inet = inet_sk(sk);
- struct nf_conntrack_tuple_hash *h;
+ const struct inet_sock *inet = inet_sk(sk);
+ const struct nf_conntrack_tuple_hash *h;
struct nf_conntrack_tuple tuple;
NF_CT_TUPLE_U_BLANK(&tuple);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index 543c02b74c9..089252e82c0 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -39,12 +39,14 @@ struct ct_iter_state {
static struct hlist_node *ct_get_first(struct seq_file *seq)
{
struct ct_iter_state *st = seq->private;
+ struct hlist_node *n;
for (st->bucket = 0;
st->bucket < nf_conntrack_htable_size;
st->bucket++) {
- if (!hlist_empty(&nf_conntrack_hash[st->bucket]))
- return nf_conntrack_hash[st->bucket].first;
+ n = rcu_dereference(nf_conntrack_hash[st->bucket].first);
+ if (n)
+ return n;
}
return NULL;
}
@@ -54,11 +56,11 @@ static struct hlist_node *ct_get_next(struct seq_file *seq,
{
struct ct_iter_state *st = seq->private;
- head = head->next;
+ head = rcu_dereference(head->next);
while (head == NULL) {
if (++st->bucket >= nf_conntrack_htable_size)
return NULL;
- head = nf_conntrack_hash[st->bucket].first;
+ head = rcu_dereference(nf_conntrack_hash[st->bucket].first);
}
return head;
}
@@ -74,8 +76,9 @@ static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
}
static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
return ct_get_idx(seq, *pos);
}
@@ -86,16 +89,17 @@ static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
}
static void ct_seq_stop(struct seq_file *s, void *v)
+ __releases(RCU)
{
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
}
static int ct_seq_show(struct seq_file *s, void *v)
{
const struct nf_conntrack_tuple_hash *hash = v;
const struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
- struct nf_conntrack_l3proto *l3proto;
- struct nf_conntrack_l4proto *l4proto;
+ const struct nf_conntrack_l3proto *l3proto;
+ const struct nf_conntrack_l4proto *l4proto;
NF_CT_ASSERT(ct);
@@ -191,10 +195,12 @@ struct ct_expect_iter_state {
static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
{
struct ct_expect_iter_state *st = seq->private;
+ struct hlist_node *n;
for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
- if (!hlist_empty(&nf_ct_expect_hash[st->bucket]))
- return nf_ct_expect_hash[st->bucket].first;
+ n = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
+ if (n)
+ return n;
}
return NULL;
}
@@ -204,11 +210,11 @@ static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
{
struct ct_expect_iter_state *st = seq->private;
- head = head->next;
+ head = rcu_dereference(head->next);
while (head == NULL) {
if (++st->bucket >= nf_ct_expect_hsize)
return NULL;
- head = nf_ct_expect_hash[st->bucket].first;
+ head = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
}
return head;
}
@@ -224,8 +230,9 @@ static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
}
static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
return ct_expect_get_idx(seq, *pos);
}
@@ -236,14 +243,15 @@ static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void exp_seq_stop(struct seq_file *seq, void *v)
+ __releases(RCU)
{
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
}
static int exp_seq_show(struct seq_file *s, void *v)
{
struct nf_conntrack_expect *exp;
- struct hlist_node *n = v;
+ const struct hlist_node *n = v;
exp = hlist_entry(n, struct nf_conntrack_expect, hnode);
@@ -324,7 +332,7 @@ static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
static int ct_cpu_seq_show(struct seq_file *seq, void *v)
{
unsigned int nr_conntracks = atomic_read(&nf_conntrack_count);
- struct ip_conntrack_stat *st = v;
+ const struct ip_conntrack_stat *st = v;
if (v == SEQ_START_TOKEN) {
seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete\n");
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 4004a04c551..6873fddb352 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -26,7 +26,8 @@ static int icmp_pkt_to_tuple(const struct sk_buff *skb,
unsigned int dataoff,
struct nf_conntrack_tuple *tuple)
{
- struct icmphdr _hdr, *hp;
+ const struct icmphdr *hp;
+ struct icmphdr _hdr;
hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
if (hp == NULL)
@@ -100,7 +101,7 @@ static int icmp_packet(struct nf_conn *ct,
}
/* Called when a new connection for this protocol found. */
-static int icmp_new(struct nf_conn *conntrack,
+static int icmp_new(struct nf_conn *ct,
const struct sk_buff *skb, unsigned int dataoff)
{
static const u_int8_t valid_new[] = {
@@ -110,15 +111,15 @@ static int icmp_new(struct nf_conn *conntrack,
[ICMP_ADDRESS] = 1
};
- if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
- || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
+ if (ct->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
+ || !valid_new[ct->tuplehash[0].tuple.dst.u.icmp.type]) {
/* Can't create a new ICMP `conn' with this. */
pr_debug("icmp: can't create new conn with type %u\n",
- conntrack->tuplehash[0].tuple.dst.u.icmp.type);
- NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
+ ct->tuplehash[0].tuple.dst.u.icmp.type);
+ NF_CT_DUMP_TUPLE(&ct->tuplehash[0].tuple);
return 0;
}
- atomic_set(&conntrack->proto.icmp.count, 0);
+ atomic_set(&ct->proto.icmp.count, 0);
return 1;
}
@@ -129,8 +130,8 @@ icmp_error_message(struct sk_buff *skb,
unsigned int hooknum)
{
struct nf_conntrack_tuple innertuple, origtuple;
- struct nf_conntrack_l4proto *innerproto;
- struct nf_conntrack_tuple_hash *h;
+ const struct nf_conntrack_l4proto *innerproto;
+ const struct nf_conntrack_tuple_hash *h;
NF_CT_ASSERT(skb->nfct == NULL);
@@ -176,7 +177,8 @@ static int
icmp_error(struct sk_buff *skb, unsigned int dataoff,
enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
{
- struct icmphdr _ih, *icmph;
+ const struct icmphdr *icmph;
+ struct icmphdr _ih;
/* Not enough header? */
icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih);
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index e53ae1ef8f5..dd07362d2b8 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -31,7 +31,7 @@
#include <net/netfilter/nf_conntrack_l3proto.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
-static DEFINE_RWLOCK(nf_nat_lock);
+static DEFINE_SPINLOCK(nf_nat_lock);
static struct nf_conntrack_l3proto *l3proto __read_mostly;
@@ -154,8 +154,8 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple,
struct nf_conn *ct;
struct hlist_node *n;
- read_lock_bh(&nf_nat_lock);
- hlist_for_each_entry(nat, n, &bysource[h], bysource) {
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(nat, n, &bysource[h], bysource) {
ct = nat->ct;
if (same_src(ct, tuple)) {
/* Copy source part from reply tuple. */
@@ -164,12 +164,12 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple,
result->dst = tuple->dst;
if (in_range(result, range)) {
- read_unlock_bh(&nf_nat_lock);
+ rcu_read_unlock();
return 1;
}
}
}
- read_unlock_bh(&nf_nat_lock);
+ rcu_read_unlock();
return 0;
}
@@ -330,12 +330,12 @@ nf_nat_setup_info(struct nf_conn *ct,
unsigned int srchash;
srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
- write_lock_bh(&nf_nat_lock);
+ spin_lock_bh(&nf_nat_lock);
/* nf_conntrack_alter_reply might re-allocate exntension aera */
nat = nfct_nat(ct);
nat->ct = ct;
- hlist_add_head(&nat->bysource, &bysource[srchash]);
- write_unlock_bh(&nf_nat_lock);
+ hlist_add_head_rcu(&nat->bysource, &bysource[srchash]);
+ spin_unlock_bh(&nf_nat_lock);
}
/* It's done. */
@@ -521,14 +521,14 @@ int nf_nat_protocol_register(const struct nf_nat_protocol *proto)
{
int ret = 0;
- write_lock_bh(&nf_nat_lock);
+ spin_lock_bh(&nf_nat_lock);
if (nf_nat_protos[proto->protonum] != &nf_nat_unknown_protocol) {
ret = -EBUSY;
goto out;
}
rcu_assign_pointer(nf_nat_protos[proto->protonum], proto);
out:
- write_unlock_bh(&nf_nat_lock);
+ spin_unlock_bh(&nf_nat_lock);
return ret;
}
EXPORT_SYMBOL(nf_nat_protocol_register);
@@ -536,10 +536,10 @@ EXPORT_SYMBOL(nf_nat_protocol_register);
/* Noone stores the protocol anywhere; simply delete it. */
void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto)
{
- write_lock_bh(&nf_nat_lock);
+ spin_lock_bh(&nf_nat_lock);
rcu_assign_pointer(nf_nat_protos[proto->protonum],
&nf_nat_unknown_protocol);
- write_unlock_bh(&nf_nat_lock);
+ spin_unlock_bh(&nf_nat_lock);
synchronize_rcu();
}
EXPORT_SYMBOL(nf_nat_protocol_unregister);
@@ -594,10 +594,10 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
NF_CT_ASSERT(nat->ct->status & IPS_NAT_DONE_MASK);
- write_lock_bh(&nf_nat_lock);
- hlist_del(&nat->bysource);
+ spin_lock_bh(&nf_nat_lock);
+ hlist_del_rcu(&nat->bysource);
nat->ct = NULL;
- write_unlock_bh(&nf_nat_lock);
+ spin_unlock_bh(&nf_nat_lock);
}
static void nf_nat_move_storage(struct nf_conn *conntrack, void *old)
@@ -609,10 +609,10 @@ static void nf_nat_move_storage(struct nf_conn *conntrack, void *old)
if (!ct || !(ct->status & IPS_NAT_DONE_MASK))
return;
- write_lock_bh(&nf_nat_lock);
+ spin_lock_bh(&nf_nat_lock);
hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource);
new_nat->ct = ct;
- write_unlock_bh(&nf_nat_lock);
+ spin_unlock_bh(&nf_nat_lock);
}
static struct nf_ct_ext_type nat_extend __read_mostly = {
@@ -646,17 +646,13 @@ static int __init nf_nat_init(void)
}
/* Sew in builtin protocols. */
- write_lock_bh(&nf_nat_lock);
+ spin_lock_bh(&nf_nat_lock);
for (i = 0; i < MAX_IP_NAT_PROTO; i++)
rcu_assign_pointer(nf_nat_protos[i], &nf_nat_unknown_protocol);
rcu_assign_pointer(nf_nat_protos[IPPROTO_TCP], &nf_nat_protocol_tcp);
rcu_assign_pointer(nf_nat_protos[IPPROTO_UDP], &nf_nat_protocol_udp);
rcu_assign_pointer(nf_nat_protos[IPPROTO_ICMP], &nf_nat_protocol_icmp);
- write_unlock_bh(&nf_nat_lock);
-
- for (i = 0; i < nf_nat_htable_size; i++) {
- INIT_HLIST_HEAD(&bysource[i]);
- }
+ spin_unlock_bh(&nf_nat_lock);
/* Initialize fake conntrack so that NAT will skip it */
nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK;
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
index a121989fdad..ee47bf28c82 100644
--- a/net/ipv4/netfilter/nf_nat_h323.c
+++ b/net/ipv4/netfilter/nf_nat_h323.c
@@ -32,7 +32,8 @@ static int set_addr(struct sk_buff *skb,
__be32 ip;
__be16 port;
} __attribute__ ((__packed__)) buf;
- struct tcphdr _tcph, *th;
+ const struct tcphdr *th;
+ struct tcphdr _tcph;
buf.ip = ip;
buf.port = port;
@@ -99,7 +100,7 @@ static int set_sig_addr(struct sk_buff *skb, struct nf_conn *ct,
unsigned char **data,
TransportAddress *taddr, int count)
{
- struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
+ const struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
int dir = CTINFO2DIR(ctinfo);
int i;
__be16 port;
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 4c0232842e7..ca57f47bbd2 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -44,8 +44,7 @@ adjust_tcp_sequence(u32 seq,
struct nf_nat_seq *this_way, *other_way;
struct nf_conn_nat *nat = nfct_nat(ct);
- pr_debug("adjust_tcp_sequence: seq = %u, sizediff = %d\n",
- ntohl(seq), seq);
+ pr_debug("adjust_tcp_sequence: seq = %u, sizediff = %d\n", seq, seq);
dir = CTINFO2DIR(ctinfo);
diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c
index e63b944a2eb..3a1e6d6afc0 100644
--- a/net/ipv4/netfilter/nf_nat_pptp.c
+++ b/net/ipv4/netfilter/nf_nat_pptp.c
@@ -40,11 +40,11 @@ MODULE_ALIAS("ip_nat_pptp");
static void pptp_nat_expected(struct nf_conn *ct,
struct nf_conntrack_expect *exp)
{
- struct nf_conn *master = ct->master;
+ const struct nf_conn *master = ct->master;
struct nf_conntrack_expect *other_exp;
struct nf_conntrack_tuple t;
- struct nf_ct_pptp_master *ct_pptp_info;
- struct nf_nat_pptp *nat_pptp_info;
+ const struct nf_ct_pptp_master *ct_pptp_info;
+ const struct nf_nat_pptp *nat_pptp_info;
struct nf_nat_range range;
ct_pptp_info = &nfct_help(master)->help.ct_pptp_info;
@@ -186,7 +186,7 @@ static void
pptp_exp_gre(struct nf_conntrack_expect *expect_orig,
struct nf_conntrack_expect *expect_reply)
{
- struct nf_conn *ct = expect_orig->master;
+ const struct nf_conn *ct = expect_orig->master;
struct nf_ct_pptp_master *ct_pptp_info;
struct nf_nat_pptp *nat_pptp_info;
@@ -217,7 +217,7 @@ pptp_inbound_pkt(struct sk_buff *skb,
struct PptpControlHeader *ctlh,
union pptp_ctrl_union *pptpReq)
{
- struct nf_nat_pptp *nat_pptp_info;
+ const struct nf_nat_pptp *nat_pptp_info;
u_int16_t msg;
__be16 new_pcid;
unsigned int pcid_off;
diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c
index 9fa272e7311..a1e4da16da2 100644
--- a/net/ipv4/netfilter/nf_nat_proto_gre.c
+++ b/net/ipv4/netfilter/nf_nat_proto_gre.c
@@ -59,7 +59,7 @@ static int
gre_unique_tuple(struct nf_conntrack_tuple *tuple,
const struct nf_nat_range *range,
enum nf_nat_manip_type maniptype,
- const struct nf_conn *conntrack)
+ const struct nf_conn *ct)
{
static u_int16_t key;
__be16 *keyptr;
@@ -67,7 +67,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
/* If there is no master conntrack we are not PPTP,
do not change tuples */
- if (!conntrack->master)
+ if (!ct->master)
return 0;
if (maniptype == IP_NAT_MANIP_SRC)
@@ -76,7 +76,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
keyptr = &tuple->dst.u.gre.key;
if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
- pr_debug("%p: NATing GRE PPTP\n", conntrack);
+ pr_debug("%p: NATing GRE PPTP\n", ct);
min = 1;
range_size = 0xffff;
} else {
@@ -88,11 +88,11 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
for (i = 0; i < range_size; i++, key++) {
*keyptr = htons(min + key % range_size);
- if (!nf_nat_used_tuple(tuple, conntrack))
+ if (!nf_nat_used_tuple(tuple, ct))
return 1;
}
- pr_debug("%p: no NAT mapping\n", conntrack);
+ pr_debug("%p: no NAT mapping\n", ct);
return 0;
}
@@ -104,7 +104,7 @@ gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
{
struct gre_hdr *greh;
struct gre_hdr_pptp *pgreh;
- struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
+ const 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
@@ -148,12 +148,12 @@ static const struct nf_nat_protocol gre = {
#endif
};
-int __init nf_nat_proto_gre_init(void)
+static int __init nf_nat_proto_gre_init(void)
{
return nf_nat_protocol_register(&gre);
}
-void __exit nf_nat_proto_gre_fini(void)
+static void __exit nf_nat_proto_gre_fini(void)
{
nf_nat_protocol_unregister(&gre);
}
diff --git a/net/ipv4/netfilter/nf_nat_proto_icmp.c b/net/ipv4/netfilter/nf_nat_proto_icmp.c
index a0e44c953cb..03a02969aa5 100644
--- a/net/ipv4/netfilter/nf_nat_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_icmp.c
@@ -57,7 +57,7 @@ icmp_manip_pkt(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype)
{
- struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
+ const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
struct icmphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c b/net/ipv4/netfilter/nf_nat_proto_tcp.c
index da23e9fbe67..ffd5d1589ec 100644
--- a/net/ipv4/netfilter/nf_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c
@@ -93,7 +93,7 @@ tcp_manip_pkt(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype)
{
- struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
+ const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
struct tcphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
__be32 oldip, newip;
diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c b/net/ipv4/netfilter/nf_nat_proto_udp.c
index 10df4db078a..4b8f49910ff 100644
--- a/net/ipv4/netfilter/nf_nat_proto_udp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_udp.c
@@ -91,7 +91,7 @@ udp_manip_pkt(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype)
{
- struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
+ const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
struct udphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
__be32 oldip, newip;
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index 519182269e7..f8fda57ba20 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -58,13 +58,14 @@ static struct
.term = IPT_ERROR_INIT, /* ERROR */
};
-static struct xt_table nat_table = {
+static struct xt_table __nat_table = {
.name = "nat",
.valid_hooks = NAT_VALID_HOOKS,
.lock = RW_LOCK_UNLOCKED,
.me = THIS_MODULE,
.af = AF_INET,
};
+static struct xt_table *nat_table;
/* Source NAT */
static unsigned int ipt_snat_target(struct sk_buff *skb,
@@ -214,7 +215,7 @@ int nf_nat_rule_find(struct sk_buff *skb,
{
int ret;
- ret = ipt_do_table(skb, 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)))
@@ -248,9 +249,10 @@ int __init nf_nat_rule_init(void)
{
int ret;
- ret = ipt_register_table(&nat_table, &nat_initial_table.repl);
- if (ret != 0)
- return ret;
+ nat_table = ipt_register_table(&init_net, &__nat_table,
+ &nat_initial_table.repl);
+ if (IS_ERR(nat_table))
+ return PTR_ERR(nat_table);
ret = xt_register_target(&ipt_snat_reg);
if (ret != 0)
goto unregister_table;
@@ -264,7 +266,7 @@ int __init nf_nat_rule_init(void)
unregister_snat:
xt_unregister_target(&ipt_snat_reg);
unregister_table:
- ipt_unregister_table(&nat_table);
+ ipt_unregister_table(nat_table);
return ret;
}
@@ -273,5 +275,5 @@ void nf_nat_rule_cleanup(void)
{
xt_unregister_target(&ipt_dnat_reg);
xt_unregister_target(&ipt_snat_reg);
- ipt_unregister_table(&nat_table);
+ ipt_unregister_table(nat_table);
}
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index 606a170bf4c..b4c8d4968bb 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -35,9 +35,9 @@ struct addr_map {
} addr[IP_CT_DIR_MAX];
};
-static void addr_map_init(struct nf_conn *ct, struct addr_map *map)
+static void addr_map_init(const struct nf_conn *ct, struct addr_map *map)
{
- struct nf_conntrack_tuple *t;
+ const struct nf_conntrack_tuple *t;
enum ip_conntrack_dir dir;
unsigned int n;
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index 07f2a49926d..540ce6ae887 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -260,7 +260,7 @@ static unsigned char asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc)
{
unsigned char ch;
- if (eoc == 0) {
+ if (eoc == NULL) {
if (!asn1_octet_decode(ctx, &ch))
return 0;
diff --git a/net/ipv4/netfilter/nf_nat_tftp.c b/net/ipv4/netfilter/nf_nat_tftp.c
index 1360a94766d..b096e81500a 100644
--- a/net/ipv4/netfilter/nf_nat_tftp.c
+++ b/net/ipv4/netfilter/nf_nat_tftp.c
@@ -24,7 +24,7 @@ static unsigned int help(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conntrack_expect *exp)
{
- struct nf_conn *ct = exp->master;
+ const struct nf_conn *ct = exp->master;
exp->saved_proto.udp.port
= ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 85c08696abb..a3002fe65b7 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -352,6 +352,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
skb_reserve(skb, hh_len);
skb->priority = sk->sk_priority;
+ skb->mark = sk->sk_mark;
skb->dst = dst_clone(&rt->u.dst);
skb_reset_network_header(skb);
@@ -544,6 +545,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
{
struct flowi fl = { .oif = ipc.oif,
+ .mark = sk->sk_mark,
.nl_u = { .ip4_u =
{ .daddr = daddr,
.saddr = saddr,
@@ -860,8 +862,7 @@ static struct sock *raw_get_first(struct seq_file *seq)
struct hlist_node *node;
sk_for_each(sk, node, &state->h->ht[state->bucket])
- if (sk->sk_net == state->p.net &&
- sk->sk_family == state->family)
+ if (sk->sk_net == state->p.net)
goto found;
}
sk = NULL;
@@ -877,8 +878,7 @@ static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk)
sk = sk_next(sk);
try_again:
;
- } while (sk && sk->sk_net != state->p.net &&
- sk->sk_family != state->family);
+ } while (sk && sk->sk_net != state->p.net);
if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
sk = sk_head(&state->h->ht[state->bucket]);
@@ -927,7 +927,7 @@ void raw_seq_stop(struct seq_file *seq, void *v)
}
EXPORT_SYMBOL_GPL(raw_seq_stop);
-static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i)
+static void raw_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
{
struct inet_sock *inet = inet_sk(sp);
__be32 dest = inet->daddr,
@@ -935,33 +935,23 @@ static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i)
__u16 destp = 0,
srcp = inet->num;
- sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
+ seq_printf(seq, "%4d: %08X:%04X %08X:%04X"
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d",
i, src, srcp, dest, destp, sp->sk_state,
atomic_read(&sp->sk_wmem_alloc),
atomic_read(&sp->sk_rmem_alloc),
0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
- return tmpbuf;
}
-#define TMPSZ 128
-
static int raw_seq_show(struct seq_file *seq, void *v)
{
- char tmpbuf[TMPSZ+1];
-
if (v == SEQ_START_TOKEN)
- seq_printf(seq, "%-*s\n", TMPSZ-1,
- " sl local_address rem_address st tx_queue "
- "rx_queue tr tm->when retrnsmt uid timeout "
- "inode drops");
- else {
- struct raw_iter_state *state = raw_seq_private(seq);
-
- seq_printf(seq, "%-*s\n", TMPSZ-1,
- get_raw_sock(v, tmpbuf, state->bucket));
- }
+ seq_printf(seq, " sl local_address rem_address st tx_queue "
+ "rx_queue tr tm->when retrnsmt uid timeout "
+ "inode drops\n");
+ else
+ raw_sock_seq_show(seq, v, raw_seq_private(seq)->bucket);
return 0;
}
@@ -972,27 +962,25 @@ static const struct seq_operations raw_seq_ops = {
.show = raw_seq_show,
};
-int raw_seq_open(struct inode *ino, struct file *file, struct raw_hashinfo *h,
- unsigned short family)
+int raw_seq_open(struct inode *ino, struct file *file,
+ struct raw_hashinfo *h, const struct seq_operations *ops)
{
int err;
struct raw_iter_state *i;
- err = seq_open_net(ino, file, &raw_seq_ops,
- sizeof(struct raw_iter_state));
+ err = seq_open_net(ino, file, ops, sizeof(struct raw_iter_state));
if (err < 0)
return err;
i = raw_seq_private((struct seq_file *)file->private_data);
i->h = h;
- i->family = family;
return 0;
}
EXPORT_SYMBOL_GPL(raw_seq_open);
static int raw_v4_seq_open(struct inode *inode, struct file *file)
{
- return raw_seq_open(inode, file, &raw_v4_hashinfo, PF_INET);
+ return raw_seq_open(inode, file, &raw_v4_hashinfo, &raw_seq_ops);
}
static const struct file_operations raw_seq_fops = {
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 896c768e41a..8842ecb9be4 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -117,8 +117,6 @@
#define RT_GC_TIMEOUT (300*HZ)
-static int ip_rt_min_delay = 2 * HZ;
-static int ip_rt_max_delay = 10 * HZ;
static int ip_rt_max_size;
static int ip_rt_gc_timeout = RT_GC_TIMEOUT;
static int ip_rt_gc_interval = 60 * HZ;
@@ -133,12 +131,9 @@ static int ip_rt_mtu_expires = 10 * 60 * HZ;
static int ip_rt_min_pmtu = 512 + 20 + 20;
static int ip_rt_min_advmss = 256;
static int ip_rt_secret_interval = 10 * 60 * HZ;
-static int ip_rt_flush_expected;
-static unsigned long rt_deadline;
#define RTprint(a...) printk(KERN_DEBUG a)
-static struct timer_list rt_flush_timer;
static void rt_worker_func(struct work_struct *work);
static DECLARE_DELAYED_WORK(expires_work, rt_worker_func);
static struct timer_list rt_secret_timer;
@@ -169,6 +164,7 @@ static struct dst_ops ipv4_dst_ops = {
.update_pmtu = ip_rt_update_pmtu,
.local_out = ip_local_out,
.entry_size = sizeof(struct rtable),
+ .entries = ATOMIC_INIT(0),
};
#define ECN_OR_COST(class) TC_PRIO_##class
@@ -259,19 +255,16 @@ static inline void rt_hash_lock_init(void)
static struct rt_hash_bucket *rt_hash_table;
static unsigned rt_hash_mask;
static unsigned int rt_hash_log;
-static unsigned int rt_hash_rnd;
+static atomic_t rt_genid;
static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
#define RT_CACHE_STAT_INC(field) \
(__raw_get_cpu_var(rt_cache_stat).field++)
-static int rt_intern_hash(unsigned hash, struct rtable *rth,
- struct rtable **res);
-
static unsigned int rt_hash_code(u32 daddr, u32 saddr)
{
- return (jhash_2words(daddr, saddr, rt_hash_rnd)
- & rt_hash_mask);
+ return jhash_2words(daddr, saddr, atomic_read(&rt_genid))
+ & rt_hash_mask;
}
#define rt_hash(daddr, saddr, idx) \
@@ -281,27 +274,28 @@ static unsigned int rt_hash_code(u32 daddr, u32 saddr)
#ifdef CONFIG_PROC_FS
struct rt_cache_iter_state {
int bucket;
+ int genid;
};
-static struct rtable *rt_cache_get_first(struct seq_file *seq)
+static struct rtable *rt_cache_get_first(struct rt_cache_iter_state *st)
{
struct rtable *r = NULL;
- struct rt_cache_iter_state *st = seq->private;
for (st->bucket = rt_hash_mask; st->bucket >= 0; --st->bucket) {
rcu_read_lock_bh();
- r = rt_hash_table[st->bucket].chain;
- if (r)
- break;
+ r = rcu_dereference(rt_hash_table[st->bucket].chain);
+ while (r) {
+ if (r->rt_genid == st->genid)
+ return r;
+ r = rcu_dereference(r->u.dst.rt_next);
+ }
rcu_read_unlock_bh();
}
- return rcu_dereference(r);
+ return r;
}
-static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r)
+static struct rtable *rt_cache_get_next(struct rt_cache_iter_state *st, struct rtable *r)
{
- struct rt_cache_iter_state *st = seq->private;
-
r = r->u.dst.rt_next;
while (!r) {
rcu_read_unlock_bh();
@@ -313,29 +307,38 @@ static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r)
return rcu_dereference(r);
}
-static struct rtable *rt_cache_get_idx(struct seq_file *seq, loff_t pos)
+static struct rtable *rt_cache_get_idx(struct rt_cache_iter_state *st, loff_t pos)
{
- struct rtable *r = rt_cache_get_first(seq);
+ struct rtable *r = rt_cache_get_first(st);
if (r)
- while (pos && (r = rt_cache_get_next(seq, r)))
+ while (pos && (r = rt_cache_get_next(st, r))) {
+ if (r->rt_genid != st->genid)
+ continue;
--pos;
+ }
return pos ? NULL : r;
}
static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
{
- return *pos ? rt_cache_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ struct rt_cache_iter_state *st = seq->private;
+
+ if (*pos)
+ return rt_cache_get_idx(st, *pos - 1);
+ st->genid = atomic_read(&rt_genid);
+ return SEQ_START_TOKEN;
}
static void *rt_cache_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct rtable *r = NULL;
+ struct rtable *r;
+ struct rt_cache_iter_state *st = seq->private;
if (v == SEQ_START_TOKEN)
- r = rt_cache_get_first(seq);
+ r = rt_cache_get_first(st);
else
- r = rt_cache_get_next(seq, v);
+ r = rt_cache_get_next(st, v);
++*pos;
return r;
}
@@ -708,6 +711,11 @@ static void rt_check_expire(void)
continue;
spin_lock_bh(rt_hash_lock_addr(i));
while ((rth = *rthp) != NULL) {
+ if (rth->rt_genid != atomic_read(&rt_genid)) {
+ *rthp = rth->u.dst.rt_next;
+ rt_free(rth);
+ continue;
+ }
if (rth->u.dst.expires) {
/* Entry is expired even if it is in use */
if (time_before_eq(jiffies, rth->u.dst.expires)) {
@@ -732,83 +740,45 @@ static void rt_check_expire(void)
/*
* rt_worker_func() is run in process context.
- * If a whole flush was scheduled, it is done.
- * Else, we call rt_check_expire() to scan part of the hash table
+ * we call rt_check_expire() to scan part of the hash table
*/
static void rt_worker_func(struct work_struct *work)
{
- if (ip_rt_flush_expected) {
- ip_rt_flush_expected = 0;
- rt_do_flush(1);
- } else
- rt_check_expire();
+ rt_check_expire();
schedule_delayed_work(&expires_work, ip_rt_gc_interval);
}
-/* This can run from both BH and non-BH contexts, the latter
- * in the case of a forced flush event.
+/*
+ * Pertubation of rt_genid by a small quantity [1..256]
+ * Using 8 bits of shuffling ensure we can call rt_cache_invalidate()
+ * many times (2^24) without giving recent rt_genid.
+ * Jenkins hash is strong enough that litle changes of rt_genid are OK.
*/
-static void rt_run_flush(unsigned long process_context)
+static void rt_cache_invalidate(void)
{
- rt_deadline = 0;
-
- get_random_bytes(&rt_hash_rnd, 4);
+ unsigned char shuffle;
- rt_do_flush(process_context);
+ get_random_bytes(&shuffle, sizeof(shuffle));
+ atomic_add(shuffle + 1U, &rt_genid);
}
-static DEFINE_SPINLOCK(rt_flush_lock);
-
+/*
+ * delay < 0 : invalidate cache (fast : entries will be deleted later)
+ * delay >= 0 : invalidate & flush cache (can be long)
+ */
void rt_cache_flush(int delay)
{
- unsigned long now = jiffies;
- int user_mode = !in_softirq();
-
- if (delay < 0)
- delay = ip_rt_min_delay;
-
- spin_lock_bh(&rt_flush_lock);
-
- if (del_timer(&rt_flush_timer) && delay > 0 && rt_deadline) {
- long tmo = (long)(rt_deadline - now);
-
- /* If flush timer is already running
- and flush request is not immediate (delay > 0):
-
- if deadline is not achieved, prolongate timer to "delay",
- otherwise fire it at deadline time.
- */
-
- if (user_mode && tmo < ip_rt_max_delay-ip_rt_min_delay)
- tmo = 0;
-
- if (delay > tmo)
- delay = tmo;
- }
-
- if (delay <= 0) {
- spin_unlock_bh(&rt_flush_lock);
- rt_run_flush(user_mode);
- return;
- }
-
- if (rt_deadline == 0)
- rt_deadline = now + ip_rt_max_delay;
-
- mod_timer(&rt_flush_timer, now+delay);
- spin_unlock_bh(&rt_flush_lock);
+ rt_cache_invalidate();
+ if (delay >= 0)
+ rt_do_flush(!in_softirq());
}
/*
- * We change rt_hash_rnd and ask next rt_worker_func() invocation
- * to perform a flush in process context
+ * We change rt_genid and let gc do the cleanup
*/
static void rt_secret_rebuild(unsigned long dummy)
{
- get_random_bytes(&rt_hash_rnd, 4);
- ip_rt_flush_expected = 1;
- cancel_delayed_work(&expires_work);
- schedule_delayed_work(&expires_work, HZ/10);
+ rt_cache_invalidate();
mod_timer(&rt_secret_timer, jiffies + ip_rt_secret_interval);
}
@@ -885,7 +855,8 @@ static int rt_garbage_collect(struct dst_ops *ops)
rthp = &rt_hash_table[k].chain;
spin_lock_bh(rt_hash_lock_addr(k));
while ((rth = *rthp) != NULL) {
- if (!rt_may_expire(rth, tmo, expire)) {
+ if (rth->rt_genid == atomic_read(&rt_genid) &&
+ !rt_may_expire(rth, tmo, expire)) {
tmo >>= 1;
rthp = &rth->u.dst.rt_next;
continue;
@@ -966,6 +937,11 @@ restart:
spin_lock_bh(rt_hash_lock_addr(hash));
while ((rth = *rthp) != NULL) {
+ if (rth->rt_genid != atomic_read(&rt_genid)) {
+ *rthp = rth->u.dst.rt_next;
+ rt_free(rth);
+ continue;
+ }
if (compare_keys(&rth->fl, &rt->fl) && compare_netns(rth, rt)) {
/* Put it first */
*rthp = rth->u.dst.rt_next;
@@ -1131,17 +1107,19 @@ void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more)
static void rt_del(unsigned hash, struct rtable *rt)
{
- struct rtable **rthp;
+ struct rtable **rthp, *aux;
+ rthp = &rt_hash_table[hash].chain;
spin_lock_bh(rt_hash_lock_addr(hash));
ip_rt_put(rt);
- for (rthp = &rt_hash_table[hash].chain; *rthp;
- rthp = &(*rthp)->u.dst.rt_next)
- if (*rthp == rt) {
- *rthp = rt->u.dst.rt_next;
- rt_free(rt);
- break;
+ while ((aux = *rthp) != NULL) {
+ if (aux == rt || (aux->rt_genid != atomic_read(&rt_genid))) {
+ *rthp = aux->u.dst.rt_next;
+ rt_free(aux);
+ continue;
}
+ rthp = &aux->u.dst.rt_next;
+ }
spin_unlock_bh(rt_hash_lock_addr(hash));
}
@@ -1186,7 +1164,8 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
if (rth->fl.fl4_dst != daddr ||
rth->fl.fl4_src != skeys[i] ||
rth->fl.oif != ikeys[k] ||
- rth->fl.iif != 0) {
+ rth->fl.iif != 0 ||
+ rth->rt_genid != atomic_read(&rt_genid)) {
rthp = &rth->u.dst.rt_next;
continue;
}
@@ -1224,7 +1203,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
rt->u.dst.neighbour = NULL;
rt->u.dst.hh = NULL;
rt->u.dst.xfrm = NULL;
-
+ rt->rt_genid = atomic_read(&rt_genid);
rt->rt_flags |= RTCF_REDIRECTED;
/* Gateway is different ... */
@@ -1445,7 +1424,8 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
rth->rt_src == iph->saddr &&
rth->fl.iif == 0 &&
!(dst_metric_locked(&rth->u.dst, RTAX_MTU)) &&
- rth->u.dst.dev->nd_net == net) {
+ rth->u.dst.dev->nd_net == net &&
+ rth->rt_genid == atomic_read(&rt_genid)) {
unsigned short mtu = new_mtu;
if (new_mtu < 68 || new_mtu >= old_mtu) {
@@ -1680,8 +1660,9 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
rth->fl.oif = 0;
rth->rt_gateway = daddr;
rth->rt_spec_dst= spec_dst;
- rth->rt_type = RTN_MULTICAST;
+ rth->rt_genid = atomic_read(&rt_genid);
rth->rt_flags = RTCF_MULTICAST;
+ rth->rt_type = RTN_MULTICAST;
if (our) {
rth->u.dst.input= ip_local_deliver;
rth->rt_flags |= RTCF_LOCAL;
@@ -1820,6 +1801,7 @@ static inline int __mkroute_input(struct sk_buff *skb,
rth->u.dst.input = ip_forward;
rth->u.dst.output = ip_output;
+ rth->rt_genid = atomic_read(&rt_genid);
rt_set_nexthop(rth, res, itag);
@@ -1980,6 +1962,7 @@ local_input:
goto e_nobufs;
rth->u.dst.output= ip_rt_bug;
+ rth->rt_genid = atomic_read(&rt_genid);
atomic_set(&rth->u.dst.__refcnt, 1);
rth->u.dst.flags= DST_HOST;
@@ -2071,7 +2054,8 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
rth->fl.oif == 0 &&
rth->fl.mark == skb->mark &&
rth->fl.fl4_tos == tos &&
- rth->u.dst.dev->nd_net == net) {
+ rth->u.dst.dev->nd_net == net &&
+ rth->rt_genid == atomic_read(&rt_genid)) {
dst_use(&rth->u.dst, jiffies);
RT_CACHE_STAT_INC(in_hit);
rcu_read_unlock();
@@ -2199,6 +2183,7 @@ static inline int __mkroute_output(struct rtable **result,
rth->rt_spec_dst= fl->fl4_src;
rth->u.dst.output=ip_output;
+ rth->rt_genid = atomic_read(&rt_genid);
RT_CACHE_STAT_INC(out_slow_tot);
@@ -2471,7 +2456,8 @@ int __ip_route_output_key(struct net *net, struct rtable **rp,
rth->fl.mark == flp->mark &&
!((rth->fl.fl4_tos ^ flp->fl4_tos) &
(IPTOS_RT_MASK | RTO_ONLINK)) &&
- rth->u.dst.dev->nd_net == net) {
+ rth->u.dst.dev->nd_net == net &&
+ rth->rt_genid == atomic_read(&rt_genid)) {
dst_use(&rth->u.dst, jiffies);
RT_CACHE_STAT_INC(out_hit);
rcu_read_unlock_bh();
@@ -2498,6 +2484,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
.check = ipv4_dst_check,
.update_pmtu = ipv4_rt_blackhole_update_pmtu,
.entry_size = sizeof(struct rtable),
+ .entries = ATOMIC_INIT(0),
};
@@ -2525,6 +2512,7 @@ static int ipv4_dst_blackhole(struct rtable **rp, struct flowi *flp, struct sock
rt->idev = ort->idev;
if (rt->idev)
in_dev_hold(rt->idev);
+ rt->rt_genid = atomic_read(&rt_genid);
rt->rt_flags = ort->rt_flags;
rt->rt_type = ort->rt_type;
rt->rt_dst = ort->rt_dst;
@@ -2779,6 +2767,8 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb)
rt = rcu_dereference(rt->u.dst.rt_next), idx++) {
if (idx < s_idx)
continue;
+ if (rt->rt_genid != atomic_read(&rt_genid))
+ continue;
skb->dst = dst_clone(&rt->u.dst);
if (rt_fill_info(skb, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, RTM_NEWROUTE,
@@ -2848,24 +2838,6 @@ ctl_table ipv4_route_table[] = {
.strategy = &ipv4_sysctl_rtcache_flush_strategy,
},
{
- .ctl_name = NET_IPV4_ROUTE_MIN_DELAY,
- .procname = "min_delay",
- .data = &ip_rt_min_delay,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- .strategy = &sysctl_jiffies,
- },
- {
- .ctl_name = NET_IPV4_ROUTE_MAX_DELAY,
- .procname = "max_delay",
- .data = &ip_rt_max_delay,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- .strategy = &sysctl_jiffies,
- },
- {
.ctl_name = NET_IPV4_ROUTE_GC_THRESH,
.procname = "gc_thresh",
.data = &ipv4_dst_ops.gc_thresh,
@@ -3023,8 +2995,8 @@ int __init ip_rt_init(void)
{
int rc = 0;
- rt_hash_rnd = (int) ((num_physpages ^ (num_physpages>>8)) ^
- (jiffies ^ (jiffies >> 7)));
+ atomic_set(&rt_genid, (int) ((num_physpages ^ (num_physpages>>8)) ^
+ (jiffies ^ (jiffies >> 7))));
#ifdef CONFIG_NET_CLS_ROUTE
ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct));
@@ -3057,7 +3029,6 @@ int __init ip_rt_init(void)
devinet_init();
ip_fib_init();
- setup_timer(&rt_flush_timer, rt_run_flush, 0);
setup_timer(&rt_secret_timer, rt_secret_rebuild, 0);
/* All the timers, started at system startup tend
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 82cdf23837e..88286f35d1e 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -185,7 +185,7 @@ static int strategy_allowed_congestion_control(ctl_table *table, int __user *nam
tcp_get_available_congestion_control(tbl.data, tbl.maxlen);
ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen);
- if (ret == 0 && newval && newlen)
+ if (ret == 1 && newval && newlen)
ret = tcp_set_allowed_congestion_control(tbl.data);
kfree(tbl.data);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index fa2c85ca5bc..19c449f6267 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2153,7 +2153,7 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int fast_rexmit)
tp->lost_skb_hint = skb;
tp->lost_cnt_hint = cnt;
- if (tcp_is_fack(tp) ||
+ if (tcp_is_fack(tp) || tcp_is_reno(tp) ||
(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
cnt += tcp_skb_pcount(skb);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 9aea88b8d4f..77c1939a2b0 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -369,8 +369,8 @@ void tcp_v4_err(struct sk_buff *skb, u32 info)
return;
}
- sk = inet_lookup(&tcp_hashinfo, iph->daddr, th->dest, iph->saddr,
- th->source, inet_iif(skb));
+ sk = inet_lookup(skb->dev->nd_net, &tcp_hashinfo, iph->daddr, th->dest,
+ iph->saddr, th->source, inet_iif(skb));
if (!sk) {
ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
return;
@@ -1503,8 +1503,8 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
if (req)
return tcp_check_req(sk, skb, req, prev);
- nsk = inet_lookup_established(&tcp_hashinfo, iph->saddr, th->source,
- iph->daddr, th->dest, inet_iif(skb));
+ nsk = inet_lookup_established(sk->sk_net, &tcp_hashinfo, iph->saddr,
+ th->source, iph->daddr, th->dest, inet_iif(skb));
if (nsk) {
if (nsk->sk_state != TCP_TIME_WAIT) {
@@ -1661,8 +1661,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
TCP_SKB_CB(skb)->flags = iph->tos;
TCP_SKB_CB(skb)->sacked = 0;
- sk = __inet_lookup(&tcp_hashinfo, iph->saddr, th->source,
- iph->daddr, th->dest, inet_iif(skb));
+ sk = __inet_lookup(skb->dev->nd_net, &tcp_hashinfo, iph->saddr,
+ th->source, iph->daddr, th->dest, inet_iif(skb));
if (!sk)
goto no_tcp_socket;
@@ -1735,7 +1735,8 @@ do_time_wait:
}
switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
case TCP_TW_SYN: {
- struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo,
+ struct sock *sk2 = inet_lookup_listener(skb->dev->nd_net,
+ &tcp_hashinfo,
iph->daddr, th->dest,
inet_iif(skb));
if (sk2) {
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 89f0188885c..ed750f9ceb0 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2564,5 +2564,4 @@ EXPORT_SYMBOL(tcp_connect);
EXPORT_SYMBOL(tcp_make_synack);
EXPORT_SYMBOL(tcp_simple_retransmit);
EXPORT_SYMBOL(tcp_sync_mss);
-EXPORT_SYMBOL(sysctl_tcp_tso_win_divisor);
EXPORT_SYMBOL(tcp_mtup_init);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 2fb8d731026..7ea1b67b6de 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -130,14 +130,14 @@ EXPORT_SYMBOL(sysctl_udp_wmem_min);
atomic_t udp_memory_allocated;
EXPORT_SYMBOL(udp_memory_allocated);
-static inline int __udp_lib_lport_inuse(__u16 num,
+static inline int __udp_lib_lport_inuse(struct net *net, __u16 num,
const struct hlist_head udptable[])
{
struct sock *sk;
struct hlist_node *node;
sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)])
- if (sk->sk_hash == num)
+ if (sk->sk_net == net && sk->sk_hash == num)
return 1;
return 0;
}
@@ -159,6 +159,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
struct hlist_head *head;
struct sock *sk2;
int error = 1;
+ struct net *net = sk->sk_net;
write_lock_bh(&udp_hash_lock);
@@ -198,7 +199,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
/* 2nd pass: find hole in shortest hash chain */
rover = best;
for (i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++) {
- if (! __udp_lib_lport_inuse(rover, udptable))
+ if (! __udp_lib_lport_inuse(net, rover, udptable))
goto gotit;
rover += UDP_HTABLE_SIZE;
if (rover > high)
@@ -218,6 +219,7 @@ gotit:
sk_for_each(sk2, node, head)
if (sk2->sk_hash == snum &&
sk2 != sk &&
+ sk2->sk_net == net &&
(!sk2->sk_reuse || !sk->sk_reuse) &&
(!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
|| sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
@@ -261,9 +263,9 @@ static inline int udp_v4_get_port(struct sock *sk, unsigned short snum)
/* UDP is nearly always wildcards out the wazoo, it makes no sense to try
* harder than this. -DaveM
*/
-static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
- __be32 daddr, __be16 dport,
- int dif, struct hlist_head udptable[])
+static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
+ __be16 sport, __be32 daddr, __be16 dport,
+ int dif, struct hlist_head udptable[])
{
struct sock *sk, *result = NULL;
struct hlist_node *node;
@@ -274,7 +276,8 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
struct inet_sock *inet = inet_sk(sk);
- if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) {
+ if (sk->sk_net == net && sk->sk_hash == hnum &&
+ !ipv6_only_sock(sk)) {
int score = (sk->sk_family == PF_INET ? 1 : 0);
if (inet->rcv_saddr) {
if (inet->rcv_saddr != daddr)
@@ -361,8 +364,8 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct hlist_head udptable[])
int harderr;
int err;
- sk = __udp4_lib_lookup(iph->daddr, uh->dest, iph->saddr, uh->source,
- skb->dev->ifindex, udptable );
+ sk = __udp4_lib_lookup(skb->dev->nd_net, iph->daddr, uh->dest,
+ iph->saddr, uh->source, skb->dev->ifindex, udptable);
if (sk == NULL) {
ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
return; /* No socket for error */
@@ -1185,8 +1188,8 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
- sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
- inet_iif(skb), udptable);
+ sk = __udp4_lib_lookup(skb->dev->nd_net, saddr, uh->source, daddr,
+ uh->dest, inet_iif(skb), udptable);
if (sk != NULL) {
int ret = 0;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 3783e3ee56a..10ed7049143 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -247,6 +247,7 @@ static struct dst_ops xfrm4_dst_ops = {
.local_out = __ip_local_out,
.gc_thresh = 1024,
.entry_size = sizeof(struct xfrm_dst),
+ .entries = ATOMIC_INIT(0),
};
static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 32684519562..41f5982d208 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -38,7 +38,7 @@ static void ipip_destroy(struct xfrm_state *x)
{
}
-static struct xfrm_type ipip_type = {
+static const struct xfrm_type ipip_type = {
.description = "IPIP",
.owner = THIS_MODULE,
.proto = IPPROTO_IPIP,
@@ -50,7 +50,7 @@ static struct xfrm_type ipip_type = {
static int xfrm_tunnel_rcv(struct sk_buff *skb)
{
- return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr);
+ return xfrm4_rcv_spi(skb, IPPROTO_IPIP, ip_hdr(skb)->saddr);
}
static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index eb0b8085949..3ffb0323668 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -85,6 +85,7 @@ config INET6_ESP
depends on IPV6
select XFRM
select CRYPTO
+ select CRYPTO_AEAD
select CRYPTO_HMAC
select CRYPTO_MD5
select CRYPTO_CBC
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index fb0d07a15e9..379c8e04c36 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -515,7 +515,7 @@ static void ah6_destroy(struct xfrm_state *x)
kfree(ahp);
}
-static struct xfrm_type ah6_type =
+static const struct xfrm_type ah6_type =
{
.description = "AH6",
.owner = THIS_MODULE,
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 5bd5292ad9f..8e0f1428c71 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -24,33 +24,124 @@
* This file is derived from net/ipv4/esp.c
*/
+#include <crypto/aead.h>
+#include <crypto/authenc.h>
#include <linux/err.h>
#include <linux/module.h>
#include <net/ip.h>
#include <net/xfrm.h>
#include <net/esp.h>
#include <linux/scatterlist.h>
-#include <linux/crypto.h>
#include <linux/kernel.h>
#include <linux/pfkeyv2.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <net/icmp.h>
#include <net/ipv6.h>
#include <net/protocol.h>
#include <linux/icmpv6.h>
+struct esp_skb_cb {
+ struct xfrm_skb_cb xfrm;
+ void *tmp;
+};
+
+#define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
+
+/*
+ * Allocate an AEAD request structure with extra space for SG and IV.
+ *
+ * For alignment considerations the IV is placed at the front, followed
+ * by the request and finally the SG list.
+ *
+ * TODO: Use spare space in skb for this where possible.
+ */
+static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags)
+{
+ unsigned int len;
+
+ len = crypto_aead_ivsize(aead);
+ if (len) {
+ len += crypto_aead_alignmask(aead) &
+ ~(crypto_tfm_ctx_alignment() - 1);
+ len = ALIGN(len, crypto_tfm_ctx_alignment());
+ }
+
+ len += sizeof(struct aead_givcrypt_request) + crypto_aead_reqsize(aead);
+ len = ALIGN(len, __alignof__(struct scatterlist));
+
+ len += sizeof(struct scatterlist) * nfrags;
+
+ return kmalloc(len, GFP_ATOMIC);
+}
+
+static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp)
+{
+ return crypto_aead_ivsize(aead) ?
+ PTR_ALIGN((u8 *)tmp, crypto_aead_alignmask(aead) + 1) : tmp;
+}
+
+static inline struct aead_givcrypt_request *esp_tmp_givreq(
+ struct crypto_aead *aead, u8 *iv)
+{
+ struct aead_givcrypt_request *req;
+
+ req = (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead),
+ crypto_tfm_ctx_alignment());
+ aead_givcrypt_set_tfm(req, aead);
+ return req;
+}
+
+static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv)
+{
+ struct aead_request *req;
+
+ req = (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead),
+ crypto_tfm_ctx_alignment());
+ aead_request_set_tfm(req, aead);
+ return req;
+}
+
+static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
+ struct aead_request *req)
+{
+ return (void *)ALIGN((unsigned long)(req + 1) +
+ crypto_aead_reqsize(aead),
+ __alignof__(struct scatterlist));
+}
+
+static inline struct scatterlist *esp_givreq_sg(
+ struct crypto_aead *aead, struct aead_givcrypt_request *req)
+{
+ return (void *)ALIGN((unsigned long)(req + 1) +
+ crypto_aead_reqsize(aead),
+ __alignof__(struct scatterlist));
+}
+
+static void esp_output_done(struct crypto_async_request *base, int err)
+{
+ struct sk_buff *skb = base->data;
+
+ kfree(ESP_SKB_CB(skb)->tmp);
+ xfrm_output_resume(skb, err);
+}
+
static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
{
int err;
struct ip_esp_hdr *esph;
- struct crypto_blkcipher *tfm;
- struct blkcipher_desc desc;
+ struct crypto_aead *aead;
+ struct aead_givcrypt_request *req;
+ struct scatterlist *sg;
+ struct scatterlist *asg;
struct sk_buff *trailer;
+ void *tmp;
int blksize;
int clen;
int alen;
int nfrags;
+ u8 *iv;
u8 *tail;
struct esp_data *esp = x->data;
@@ -60,18 +151,26 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
/* Round to block size */
clen = skb->len;
- alen = esp->auth.icv_trunc_len;
- tfm = esp->conf.tfm;
- desc.tfm = tfm;
- desc.flags = 0;
- blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
+ aead = esp->aead;
+ alen = crypto_aead_authsize(aead);
+
+ blksize = ALIGN(crypto_aead_blocksize(aead), 4);
clen = ALIGN(clen + 2, blksize);
- if (esp->conf.padlen)
- clen = ALIGN(clen, esp->conf.padlen);
+ if (esp->padlen)
+ clen = ALIGN(clen, esp->padlen);
- if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0) {
+ if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0)
goto error;
- }
+ nfrags = err;
+
+ tmp = esp_alloc_tmp(aead, nfrags + 1);
+ if (!tmp)
+ goto error;
+
+ iv = esp_tmp_iv(aead, tmp);
+ req = esp_tmp_givreq(aead, iv);
+ asg = esp_givreq_sg(aead, req);
+ sg = asg + 1;
/* Fill padding... */
tail = skb_tail_pointer(trailer);
@@ -81,86 +180,113 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
tail[i] = i + 1;
} while (0);
tail[clen-skb->len - 2] = (clen - skb->len) - 2;
- pskb_put(skb, trailer, clen - skb->len);
+ tail[clen - skb->len - 1] = *skb_mac_header(skb);
+ pskb_put(skb, trailer, clen - skb->len + alen);
skb_push(skb, -skb_network_offset(skb));
esph = ip_esp_hdr(skb);
- *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb);
*skb_mac_header(skb) = IPPROTO_ESP;
esph->spi = x->id.spi;
esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
- spin_lock_bh(&x->lock);
+ sg_init_table(sg, nfrags);
+ skb_to_sgvec(skb, sg,
+ esph->enc_data + crypto_aead_ivsize(aead) - skb->data,
+ clen + alen);
+ sg_init_one(asg, esph, sizeof(*esph));
- if (esp->conf.ivlen) {
- if (unlikely(!esp->conf.ivinitted)) {
- get_random_bytes(esp->conf.ivec, esp->conf.ivlen);
- esp->conf.ivinitted = 1;
- }
- crypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
- }
+ aead_givcrypt_set_callback(req, 0, esp_output_done, skb);
+ aead_givcrypt_set_crypt(req, sg, sg, clen, iv);
+ aead_givcrypt_set_assoc(req, asg, sizeof(*esph));
+ aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq);
- do {
- struct scatterlist *sg = &esp->sgbuf[0];
+ ESP_SKB_CB(skb)->tmp = tmp;
+ err = crypto_aead_givencrypt(req);
+ if (err == -EINPROGRESS)
+ goto error;
- if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
- sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
- if (!sg)
- goto unlock;
- }
- sg_init_table(sg, nfrags);
- skb_to_sgvec(skb, sg,
- esph->enc_data +
- esp->conf.ivlen -
- skb->data, clen);
- err = crypto_blkcipher_encrypt(&desc, sg, sg, clen);
- if (unlikely(sg != &esp->sgbuf[0]))
- kfree(sg);
- } while (0);
+ if (err == -EBUSY)
+ err = NET_XMIT_DROP;
+
+ kfree(tmp);
+
+error:
+ return err;
+}
+
+static int esp_input_done2(struct sk_buff *skb, int err)
+{
+ struct xfrm_state *x = xfrm_input_state(skb);
+ struct esp_data *esp = x->data;
+ struct crypto_aead *aead = esp->aead;
+ int alen = crypto_aead_authsize(aead);
+ int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead);
+ int elen = skb->len - hlen;
+ int hdr_len = skb_network_header_len(skb);
+ int padlen;
+ u8 nexthdr[2];
+
+ kfree(ESP_SKB_CB(skb)->tmp);
if (unlikely(err))
- goto unlock;
+ goto out;
- if (esp->conf.ivlen) {
- memcpy(esph->enc_data, esp->conf.ivec, esp->conf.ivlen);
- crypto_blkcipher_get_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
- }
+ if (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2))
+ BUG();
- if (esp->auth.icv_full_len) {
- err = esp_mac_digest(esp, skb, (u8 *)esph - skb->data,
- sizeof(*esph) + esp->conf.ivlen + clen);
- memcpy(pskb_put(skb, trailer, alen), esp->auth.work_icv, alen);
+ err = -EINVAL;
+ padlen = nexthdr[0];
+ if (padlen + 2 + alen >= elen) {
+ LIMIT_NETDEBUG(KERN_WARNING "ipsec esp packet is garbage "
+ "padlen=%d, elen=%d\n", padlen + 2, elen - alen);
+ goto out;
}
-unlock:
- spin_unlock_bh(&x->lock);
+ /* ... check padding bits here. Silly. :-) */
-error:
+ pskb_trim(skb, skb->len - alen - padlen - 2);
+ __skb_pull(skb, hlen);
+ skb_set_transport_header(skb, -hdr_len);
+
+ err = nexthdr[1];
+
+ /* RFC4303: Drop dummy packets without any error */
+ if (err == IPPROTO_NONE)
+ err = -EINVAL;
+
+out:
return err;
}
+static void esp_input_done(struct crypto_async_request *base, int err)
+{
+ struct sk_buff *skb = base->data;
+
+ xfrm_input_resume(skb, esp_input_done2(skb, err));
+}
+
static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
{
- struct ipv6hdr *iph;
struct ip_esp_hdr *esph;
struct esp_data *esp = x->data;
- struct crypto_blkcipher *tfm = esp->conf.tfm;
- struct blkcipher_desc desc = { .tfm = tfm };
+ struct crypto_aead *aead = esp->aead;
+ struct aead_request *req;
struct sk_buff *trailer;
- int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
- int alen = esp->auth.icv_trunc_len;
- int elen = skb->len - sizeof(*esph) - esp->conf.ivlen - alen;
- int hdr_len = skb_network_header_len(skb);
+ int elen = skb->len - sizeof(*esph) - crypto_aead_ivsize(aead);
int nfrags;
int ret = 0;
+ void *tmp;
+ u8 *iv;
+ struct scatterlist *sg;
+ struct scatterlist *asg;
if (!pskb_may_pull(skb, sizeof(*esph))) {
ret = -EINVAL;
goto out;
}
- if (elen <= 0 || (elen & (blksize-1))) {
+ if (elen <= 0) {
ret = -EINVAL;
goto out;
}
@@ -170,86 +296,38 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
goto out;
}
- skb->ip_summed = CHECKSUM_NONE;
-
- spin_lock(&x->lock);
-
- /* If integrity check is required, do this. */
- if (esp->auth.icv_full_len) {
- u8 sum[alen];
-
- ret = esp_mac_digest(esp, skb, 0, skb->len - alen);
- if (ret)
- goto unlock;
+ ret = -ENOMEM;
+ tmp = esp_alloc_tmp(aead, nfrags + 1);
+ if (!tmp)
+ goto out;
- if (skb_copy_bits(skb, skb->len - alen, sum, alen))
- BUG();
+ ESP_SKB_CB(skb)->tmp = tmp;
+ iv = esp_tmp_iv(aead, tmp);
+ req = esp_tmp_req(aead, iv);
+ asg = esp_req_sg(aead, req);
+ sg = asg + 1;
- if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
- ret = -EBADMSG;
- goto unlock;
- }
- }
+ skb->ip_summed = CHECKSUM_NONE;
esph = (struct ip_esp_hdr *)skb->data;
- iph = ipv6_hdr(skb);
/* Get ivec. This can be wrong, check against another impls. */
- if (esp->conf.ivlen)
- crypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen);
-
- {
- struct scatterlist *sg = &esp->sgbuf[0];
-
- if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
- sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
- if (!sg) {
- ret = -ENOMEM;
- goto unlock;
- }
- }
- sg_init_table(sg, nfrags);
- skb_to_sgvec(skb, sg,
- sizeof(*esph) + esp->conf.ivlen,
- elen);
- ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
- if (unlikely(sg != &esp->sgbuf[0]))
- kfree(sg);
- }
+ iv = esph->enc_data;
-unlock:
- spin_unlock(&x->lock);
+ sg_init_table(sg, nfrags);
+ skb_to_sgvec(skb, sg, sizeof(*esph) + crypto_aead_ivsize(aead), elen);
+ sg_init_one(asg, esph, sizeof(*esph));
- if (unlikely(ret))
- goto out;
-
- {
- u8 nexthdr[2];
- u8 padlen;
-
- if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
- BUG();
-
- padlen = nexthdr[0];
- if (padlen+2 >= elen) {
- LIMIT_NETDEBUG(KERN_WARNING "ipsec esp packet is garbage padlen=%d, elen=%d\n", padlen+2, elen);
- ret = -EINVAL;
- goto out;
- }
- /* ... check padding bits here. Silly. :-) */
+ aead_request_set_callback(req, 0, esp_input_done, skb);
+ aead_request_set_crypt(req, sg, sg, elen, iv);
+ aead_request_set_assoc(req, asg, sizeof(*esph));
- /* RFC4303: Drop dummy packets without any error */
- if (nexthdr[1] == IPPROTO_NONE) {
- ret = -EINVAL;
- goto out;
- }
+ ret = crypto_aead_decrypt(req);
+ if (ret == -EINPROGRESS)
+ goto out;
- pskb_trim(skb, skb->len - alen - padlen - 2);
- ret = nexthdr[1];
- }
+ ret = esp_input_done2(skb, ret);
- __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen);
- skb_set_transport_header(skb, -hdr_len);
out:
return ret;
}
@@ -257,11 +335,11 @@ out:
static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
{
struct esp_data *esp = x->data;
- u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
- u32 align = max_t(u32, blksize, esp->conf.padlen);
+ u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4);
+ u32 align = max_t(u32, blksize, esp->padlen);
u32 rem;
- mtu -= x->props.header_len + esp->auth.icv_trunc_len;
+ mtu -= x->props.header_len + crypto_aead_authsize(esp->aead);
rem = mtu & (align - 1);
mtu &= ~(align - 1);
@@ -300,81 +378,146 @@ static void esp6_destroy(struct xfrm_state *x)
if (!esp)
return;
- crypto_free_blkcipher(esp->conf.tfm);
- esp->conf.tfm = NULL;
- kfree(esp->conf.ivec);
- esp->conf.ivec = NULL;
- crypto_free_hash(esp->auth.tfm);
- esp->auth.tfm = NULL;
- kfree(esp->auth.work_icv);
- esp->auth.work_icv = NULL;
+ crypto_free_aead(esp->aead);
kfree(esp);
}
-static int esp6_init_state(struct xfrm_state *x)
+static int esp_init_aead(struct xfrm_state *x)
+{
+ struct esp_data *esp = x->data;
+ struct crypto_aead *aead;
+ int err;
+
+ aead = crypto_alloc_aead(x->aead->alg_name, 0, 0);
+ err = PTR_ERR(aead);
+ if (IS_ERR(aead))
+ goto error;
+
+ esp->aead = aead;
+
+ err = crypto_aead_setkey(aead, x->aead->alg_key,
+ (x->aead->alg_key_len + 7) / 8);
+ if (err)
+ goto error;
+
+ err = crypto_aead_setauthsize(aead, x->aead->alg_icv_len / 8);
+ if (err)
+ goto error;
+
+error:
+ return err;
+}
+
+static int esp_init_authenc(struct xfrm_state *x)
{
- struct esp_data *esp = NULL;
- struct crypto_blkcipher *tfm;
+ struct esp_data *esp = x->data;
+ struct crypto_aead *aead;
+ struct crypto_authenc_key_param *param;
+ struct rtattr *rta;
+ char *key;
+ char *p;
+ char authenc_name[CRYPTO_MAX_ALG_NAME];
+ unsigned int keylen;
+ int err;
+ err = -EINVAL;
if (x->ealg == NULL)
goto error;
- if (x->encap)
+ err = -ENAMETOOLONG;
+ if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME, "authenc(%s,%s)",
+ x->aalg ? x->aalg->alg_name : "digest_null",
+ x->ealg->alg_name) >= CRYPTO_MAX_ALG_NAME)
goto error;
- esp = kzalloc(sizeof(*esp), GFP_KERNEL);
- if (esp == NULL)
- return -ENOMEM;
+ aead = crypto_alloc_aead(authenc_name, 0, 0);
+ err = PTR_ERR(aead);
+ if (IS_ERR(aead))
+ goto error;
+
+ esp->aead = aead;
+
+ keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) +
+ (x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param));
+ err = -ENOMEM;
+ key = kmalloc(keylen, GFP_KERNEL);
+ if (!key)
+ goto error;
+
+ p = key;
+ rta = (void *)p;
+ rta->rta_type = CRYPTO_AUTHENC_KEYA_PARAM;
+ rta->rta_len = RTA_LENGTH(sizeof(*param));
+ param = RTA_DATA(rta);
+ p += RTA_SPACE(sizeof(*param));
if (x->aalg) {
struct xfrm_algo_desc *aalg_desc;
- struct crypto_hash *hash;
-
- hash = crypto_alloc_hash(x->aalg->alg_name, 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(hash))
- goto error;
- esp->auth.tfm = hash;
- if (crypto_hash_setkey(hash, x->aalg->alg_key,
- (x->aalg->alg_key_len + 7) / 8))
- goto error;
+ memcpy(p, x->aalg->alg_key, (x->aalg->alg_key_len + 7) / 8);
+ p += (x->aalg->alg_key_len + 7) / 8;
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
BUG_ON(!aalg_desc);
+ err = -EINVAL;
if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
- crypto_hash_digestsize(hash)) {
+ crypto_aead_authsize(aead)) {
NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n",
x->aalg->alg_name,
- crypto_hash_digestsize(hash),
+ crypto_aead_authsize(aead),
aalg_desc->uinfo.auth.icv_fullbits/8);
- goto error;
+ goto free_key;
}
- esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
- esp->auth.icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8;
-
- esp->auth.work_icv = kmalloc(esp->auth.icv_full_len, GFP_KERNEL);
- if (!esp->auth.work_icv)
- goto error;
- }
- tfm = crypto_alloc_blkcipher(x->ealg->alg_name, 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(tfm))
- goto error;
- esp->conf.tfm = tfm;
- esp->conf.ivlen = crypto_blkcipher_ivsize(tfm);
- esp->conf.padlen = 0;
- if (esp->conf.ivlen) {
- esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL);
- if (unlikely(esp->conf.ivec == NULL))
- goto error;
- esp->conf.ivinitted = 0;
+ err = crypto_aead_setauthsize(
+ aead, aalg_desc->uinfo.auth.icv_truncbits / 8);
+ if (err)
+ goto free_key;
}
- if (crypto_blkcipher_setkey(tfm, x->ealg->alg_key,
- (x->ealg->alg_key_len + 7) / 8))
+
+ param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8);
+ memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8);
+
+ err = crypto_aead_setkey(aead, key, keylen);
+
+free_key:
+ kfree(key);
+
+error:
+ return err;
+}
+
+static int esp6_init_state(struct xfrm_state *x)
+{
+ struct esp_data *esp;
+ struct crypto_aead *aead;
+ u32 align;
+ int err;
+
+ if (x->encap)
+ return -EINVAL;
+
+ esp = kzalloc(sizeof(*esp), GFP_KERNEL);
+ if (esp == NULL)
+ return -ENOMEM;
+
+ x->data = esp;
+
+ if (x->aead)
+ err = esp_init_aead(x);
+ else
+ err = esp_init_authenc(x);
+
+ if (err)
goto error;
- x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
+
+ aead = esp->aead;
+
+ esp->padlen = 0;
+
+ x->props.header_len = sizeof(struct ip_esp_hdr) +
+ crypto_aead_ivsize(aead);
switch (x->props.mode) {
case XFRM_MODE_BEET:
case XFRM_MODE_TRANSPORT:
@@ -385,17 +528,17 @@ static int esp6_init_state(struct xfrm_state *x)
default:
goto error;
}
- x->data = esp;
- return 0;
+
+ align = ALIGN(crypto_aead_blocksize(aead), 4);
+ if (esp->padlen)
+ align = max_t(u32, align, esp->padlen);
+ x->props.trailer_len = align + 1 + crypto_aead_authsize(esp->aead);
error:
- x->data = esp;
- esp6_destroy(x);
- x->data = NULL;
- return -EINVAL;
+ return err;
}
-static struct xfrm_type esp6_type =
+static const struct xfrm_type esp6_type =
{
.description = "ESP6",
.owner = THIS_MODULE,
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index a66a7d8e281..d325a995890 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -54,7 +54,8 @@ EXPORT_SYMBOL(__inet6_hash);
*
* The sockhash lock must be held as a reader here.
*/
-struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
+struct sock *__inet6_lookup_established(struct net *net,
+ struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr,
const __be16 sport,
const struct in6_addr *daddr,
@@ -75,22 +76,13 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
read_lock(lock);
sk_for_each(sk, node, &head->chain) {
/* For IPV6 do the cheaper port and family tests first. */
- if (INET6_MATCH(sk, hash, saddr, daddr, ports, dif))
+ if (INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif))
goto hit; /* You sunk my battleship! */
}
/* Must check for a TIME_WAIT'er before going to listener hash. */
sk_for_each(sk, node, &head->twchain) {
- const struct inet_timewait_sock *tw = inet_twsk(sk);
-
- if(*((__portpair *)&(tw->tw_dport)) == ports &&
- sk->sk_family == PF_INET6) {
- const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
-
- if (ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) &&
- ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
- (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif))
- goto hit;
- }
+ if (INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif))
+ goto hit;
}
read_unlock(lock);
return NULL;
@@ -102,9 +94,9 @@ hit:
}
EXPORT_SYMBOL(__inet6_lookup_established);
-struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
- const struct in6_addr *daddr,
- const unsigned short hnum, const int dif)
+struct sock *inet6_lookup_listener(struct net *net,
+ struct inet_hashinfo *hashinfo, const struct in6_addr *daddr,
+ const unsigned short hnum, const int dif)
{
struct sock *sk;
const struct hlist_node *node;
@@ -113,7 +105,8 @@ struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
read_lock(&hashinfo->lhash_lock);
sk_for_each(sk, node, &hashinfo->listening_hash[inet_lhashfn(hnum)]) {
- if (inet_sk(sk)->num == hnum && sk->sk_family == PF_INET6) {
+ if (sk->sk_net == net && inet_sk(sk)->num == hnum &&
+ sk->sk_family == PF_INET6) {
const struct ipv6_pinfo *np = inet6_sk(sk);
score = 1;
@@ -145,7 +138,7 @@ struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
EXPORT_SYMBOL_GPL(inet6_lookup_listener);
-struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
+struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr, const __be16 sport,
const struct in6_addr *daddr, const __be16 dport,
const int dif)
@@ -153,7 +146,7 @@ struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
struct sock *sk;
local_bh_disable();
- sk = __inet6_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif);
+ sk = __inet6_lookup(net, hashinfo, saddr, sport, daddr, ntohs(dport), dif);
local_bh_enable();
return sk;
@@ -179,21 +172,16 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
struct sock *sk2;
const struct hlist_node *node;
struct inet_timewait_sock *tw;
+ struct net *net = sk->sk_net;
prefetch(head->chain.first);
write_lock(lock);
/* Check TIME-WAIT sockets first. */
sk_for_each(sk2, node, &head->twchain) {
- const struct inet6_timewait_sock *tw6 = inet6_twsk(sk2);
-
tw = inet_twsk(sk2);
- if(*((__portpair *)&(tw->tw_dport)) == ports &&
- sk2->sk_family == PF_INET6 &&
- ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) &&
- ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
- (!sk2->sk_bound_dev_if || sk2->sk_bound_dev_if == dif)) {
+ if (INET6_TW_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) {
if (twsk_unique(sk, sk2, twp))
goto unique;
else
@@ -204,7 +192,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
/* And established part... */
sk_for_each(sk2, node, &head->chain) {
- if (INET6_MATCH(sk2, hash, saddr, daddr, ports, dif))
+ if (INET6_MATCH(sk2, net, hash, saddr, daddr, ports, dif))
goto not_unique;
}
@@ -248,97 +236,8 @@ static inline u32 inet6_sk_port_offset(const struct sock *sk)
int inet6_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk)
{
- struct inet_hashinfo *hinfo = death_row->hashinfo;
- const unsigned short snum = inet_sk(sk)->num;
- struct inet_bind_hashbucket *head;
- struct inet_bind_bucket *tb;
- int ret;
-
- if (snum == 0) {
- int i, port, low, high, remaining;
- static u32 hint;
- const u32 offset = hint + inet6_sk_port_offset(sk);
- struct hlist_node *node;
- struct inet_timewait_sock *tw = NULL;
-
- inet_get_local_port_range(&low, &high);
- remaining = (high - low) + 1;
-
- local_bh_disable();
- for (i = 1; i <= remaining; i++) {
- port = low + (i + offset) % remaining;
- head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
- spin_lock(&head->lock);
-
- /* Does not bother with rcv_saddr checks,
- * because the established check is already
- * unique enough.
- */
- inet_bind_bucket_for_each(tb, node, &head->chain) {
- if (tb->port == port) {
- BUG_TRAP(!hlist_empty(&tb->owners));
- if (tb->fastreuse >= 0)
- goto next_port;
- if (!__inet6_check_established(death_row,
- sk, port,
- &tw))
- goto ok;
- goto next_port;
- }
- }
-
- tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
- head, port);
- if (!tb) {
- spin_unlock(&head->lock);
- break;
- }
- tb->fastreuse = -1;
- goto ok;
-
- next_port:
- spin_unlock(&head->lock);
- }
- local_bh_enable();
-
- return -EADDRNOTAVAIL;
-
-ok:
- hint += i;
-
- /* Head lock still held and bh's disabled */
- inet_bind_hash(sk, tb, port);
- if (sk_unhashed(sk)) {
- inet_sk(sk)->sport = htons(port);
- __inet6_hash(hinfo, sk);
- }
- spin_unlock(&head->lock);
-
- if (tw) {
- inet_twsk_deschedule(tw, death_row);
- inet_twsk_put(tw);
- }
-
- ret = 0;
- goto out;
- }
-
- head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)];
- tb = inet_csk(sk)->icsk_bind_hash;
- spin_lock_bh(&head->lock);
-
- if (sk_head(&tb->owners) == sk && sk->sk_bind_node.next == NULL) {
- __inet6_hash(hinfo, sk);
- spin_unlock_bh(&head->lock);
- return 0;
- } else {
- spin_unlock(&head->lock);
- /* No definite answer... Walk to established hash table */
- ret = __inet6_check_established(death_row, sk, snum, NULL);
-out:
- local_bh_enable();
- return ret;
- }
+ return __inet_hash_connect(death_row, sk,
+ __inet6_check_established, __inet6_hash);
}
EXPORT_SYMBOL_GPL(inet6_hash_connect);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 15c4f6cee3e..9ac6ca2521c 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -257,6 +257,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
ipv6_addr_copy(&hdr->daddr, first_hop);
skb->priority = sk->sk_priority;
+ skb->mark = sk->sk_mark;
mtu = dst_mtu(dst);
if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) {
@@ -636,6 +637,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
if (skb_shinfo(skb)->frag_list) {
int first_len = skb_pagelen(skb);
+ int truesizes = 0;
if (first_len - hlen > mtu ||
((first_len - hlen) & 7) ||
@@ -658,7 +660,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
sock_hold(skb->sk);
frag->sk = skb->sk;
frag->destructor = sock_wfree;
- skb->truesize -= frag->truesize;
+ truesizes += frag->truesize;
}
}
@@ -689,6 +691,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
first_len = skb_pagelen(skb);
skb->data_len = first_len - skb_headlen(skb);
+ skb->truesize -= truesizes;
skb->len = first_len;
ipv6_hdr(skb)->payload_len = htons(first_len -
sizeof(struct ipv6hdr));
@@ -1437,6 +1440,7 @@ int ip6_push_pending_frames(struct sock *sk)
ipv6_addr_copy(&hdr->daddr, final_dst);
skb->priority = sk->sk_priority;
+ skb->mark = sk->sk_mark;
skb->dst = dst_clone(&rt->u.dst);
IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index b276d04d6db..b90039593a7 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -64,6 +64,7 @@ static LIST_HEAD(ipcomp6_tfms_list);
static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
{
+ int nexthdr;
int err = -ENOMEM;
struct ip_comp_hdr *ipch;
int plen, dlen;
@@ -79,6 +80,8 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
/* Remove ipcomp header and decompress original payload */
ipch = (void *)skb->data;
+ nexthdr = ipch->nexthdr;
+
skb->transport_header = skb->network_header + sizeof(*ipch);
__skb_pull(skb, sizeof(*ipch));
@@ -108,7 +111,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
skb->truesize += dlen - plen;
__skb_put(skb, dlen - plen);
skb_copy_to_linear_data(skb, scratch, dlen);
- err = ipch->nexthdr;
+ err = nexthdr;
out_put_cpu:
put_cpu();
@@ -450,7 +453,7 @@ error:
goto out;
}
-static struct xfrm_type ipcomp6_type =
+static const struct xfrm_type ipcomp6_type =
{
.description = "IPCOMP6",
.owner = THIS_MODULE,
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 49d396620ea..cd8a5bda13c 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -330,7 +330,7 @@ static void mip6_destopt_destroy(struct xfrm_state *x)
{
}
-static struct xfrm_type mip6_destopt_type =
+static const struct xfrm_type mip6_destopt_type =
{
.description = "MIP6DESTOPT",
.owner = THIS_MODULE,
@@ -462,7 +462,7 @@ static void mip6_rthdr_destroy(struct xfrm_state *x)
{
}
-static struct xfrm_type mip6_rthdr_type =
+static const struct xfrm_type mip6_rthdr_type =
{
.description = "MIP6RT",
.owner = THIS_MODULE,
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 56b4ea6d29e..e869916b05f 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -515,6 +515,7 @@ static struct notifier_block ipq_nl_notifier = {
.notifier_call = ipq_rcv_nl_event,
};
+#ifdef CONFIG_SYSCTL
static struct ctl_table_header *ipq_sysctl_header;
static ctl_table ipq_table[] = {
@@ -528,7 +529,9 @@ static ctl_table ipq_table[] = {
},
{ .ctl_name = 0 }
};
+#endif
+#ifdef CONFIG_PROC_FS
static int ip6_queue_show(struct seq_file *m, void *v)
{
read_lock_bh(&queue_lock);
@@ -565,6 +568,7 @@ static const struct file_operations ip6_queue_proc_fops = {
.release = single_release,
.owner = THIS_MODULE,
};
+#endif
static const struct nf_queue_handler nfqh = {
.name = "ip6_queue",
@@ -574,7 +578,7 @@ static const struct nf_queue_handler nfqh = {
static int __init ip6_queue_init(void)
{
int status = -ENOMEM;
- struct proc_dir_entry *proc;
+ struct proc_dir_entry *proc __maybe_unused;
netlink_register_notifier(&ipq_nl_notifier);
ipqnl = netlink_kernel_create(&init_net, NETLINK_IP6_FW, 0,
@@ -584,6 +588,7 @@ static int __init ip6_queue_init(void)
goto cleanup_netlink_notifier;
}
+#ifdef CONFIG_PROC_FS
proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net);
if (proc) {
proc->owner = THIS_MODULE;
@@ -592,10 +597,11 @@ static int __init ip6_queue_init(void)
printk(KERN_ERR "ip6_queue: failed to create proc entry\n");
goto cleanup_ipqnl;
}
-
+#endif
register_netdevice_notifier(&ipq_dev_notifier);
+#ifdef CONFIG_SYSCTL
ipq_sysctl_header = register_sysctl_paths(net_ipv6_ctl_path, ipq_table);
-
+#endif
status = nf_register_queue_handler(PF_INET6, &nfqh);
if (status < 0) {
printk(KERN_ERR "ip6_queue: failed to register queue handler\n");
@@ -604,11 +610,13 @@ static int __init ip6_queue_init(void)
return status;
cleanup_sysctl:
+#ifdef CONFIG_SYSCTL
unregister_sysctl_table(ipq_sysctl_header);
+#endif
unregister_netdevice_notifier(&ipq_dev_notifier);
proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
-cleanup_ipqnl:
+cleanup_ipqnl: __maybe_unused
netlink_kernel_release(ipqnl);
mutex_lock(&ipqnl_mutex);
mutex_unlock(&ipqnl_mutex);
@@ -624,7 +632,9 @@ static void __exit ip6_queue_fini(void)
synchronize_net();
ipq_flush(NULL, 0);
+#ifdef CONFIG_SYSCTL
unregister_sysctl_table(ipq_sysctl_header);
+#endif
unregister_netdevice_notifier(&ipq_dev_notifier);
proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index dd7860fea61..bf9bb6e55bb 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -320,7 +320,7 @@ static void trace_packet(struct sk_buff *skb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
- char *tablename,
+ const char *tablename,
struct xt_table_info *private,
struct ip6t_entry *e)
{
@@ -1118,7 +1118,7 @@ static int compat_table_info(const struct xt_table_info *info,
}
#endif
-static int get_info(void __user *user, int *len, int compat)
+static int get_info(struct net *net, void __user *user, int *len, int compat)
{
char name[IP6T_TABLE_MAXNAMELEN];
struct xt_table *t;
@@ -1138,7 +1138,7 @@ static int get_info(void __user *user, int *len, int compat)
if (compat)
xt_compat_lock(AF_INET6);
#endif
- t = try_then_request_module(xt_find_table_lock(AF_INET6, name),
+ t = try_then_request_module(xt_find_table_lock(net, AF_INET6, name),
"ip6table_%s", name);
if (t && !IS_ERR(t)) {
struct ip6t_getinfo info;
@@ -1178,7 +1178,7 @@ static int get_info(void __user *user, int *len, int compat)
}
static int
-get_entries(struct ip6t_get_entries __user *uptr, int *len)
+get_entries(struct net *net, struct ip6t_get_entries __user *uptr, int *len)
{
int ret;
struct ip6t_get_entries get;
@@ -1196,7 +1196,7 @@ get_entries(struct ip6t_get_entries __user *uptr, int *len)
return -EINVAL;
}
- t = xt_find_table_lock(AF_INET6, get.name);
+ t = xt_find_table_lock(net, AF_INET6, get.name);
if (t && !IS_ERR(t)) {
struct xt_table_info *private = t->private;
duprintf("t->private->number = %u\n", private->number);
@@ -1217,7 +1217,7 @@ get_entries(struct ip6t_get_entries __user *uptr, int *len)
}
static int
-__do_replace(const char *name, unsigned int valid_hooks,
+__do_replace(struct net *net, const char *name, unsigned int valid_hooks,
struct xt_table_info *newinfo, unsigned int num_counters,
void __user *counters_ptr)
{
@@ -1235,7 +1235,7 @@ __do_replace(const char *name, unsigned int valid_hooks,
goto out;
}
- t = try_then_request_module(xt_find_table_lock(AF_INET6, name),
+ t = try_then_request_module(xt_find_table_lock(net, AF_INET6, name),
"ip6table_%s", name);
if (!t || IS_ERR(t)) {
ret = t ? PTR_ERR(t) : -ENOENT;
@@ -1288,7 +1288,7 @@ __do_replace(const char *name, unsigned int valid_hooks,
}
static int
-do_replace(void __user *user, unsigned int len)
+do_replace(struct net *net, void __user *user, unsigned int len)
{
int ret;
struct ip6t_replace tmp;
@@ -1322,7 +1322,7 @@ do_replace(void __user *user, unsigned int len)
duprintf("ip_tables: Translated table\n");
- ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+ ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
tmp.num_counters, tmp.counters);
if (ret)
goto free_newinfo_untrans;
@@ -1358,7 +1358,8 @@ add_counter_to_entry(struct ip6t_entry *e,
}
static int
-do_add_counters(void __user *user, unsigned int len, int compat)
+do_add_counters(struct net *net, void __user *user, unsigned int len,
+ int compat)
{
unsigned int i;
struct xt_counters_info tmp;
@@ -1410,7 +1411,7 @@ do_add_counters(void __user *user, unsigned int len, int compat)
goto free;
}
- t = xt_find_table_lock(AF_INET6, name);
+ t = xt_find_table_lock(net, AF_INET6, name);
if (!t || IS_ERR(t)) {
ret = t ? PTR_ERR(t) : -ENOENT;
goto free;
@@ -1456,7 +1457,7 @@ struct compat_ip6t_replace {
static int
compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
- compat_uint_t *size, struct xt_counters *counters,
+ unsigned int *size, struct xt_counters *counters,
unsigned int *i)
{
struct ip6t_entry_target *t;
@@ -1503,7 +1504,7 @@ compat_find_calc_match(struct ip6t_entry_match *m,
const char *name,
const struct ip6t_ip6 *ipv6,
unsigned int hookmask,
- int *size, int *i)
+ int *size, unsigned int *i)
{
struct xt_match *match;
@@ -1561,7 +1562,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
struct ip6t_entry_target *t;
struct xt_target *target;
unsigned int entry_offset;
- int ret, off, h, j;
+ unsigned int j;
+ int ret, off, h;
duprintf("check_compat_entry_size_and_hooks %p\n", e);
if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0
@@ -1673,7 +1675,8 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
static int compat_check_entry(struct ip6t_entry *e, const char *name,
unsigned int *i)
{
- int j, ret;
+ unsigned int j;
+ int ret;
j = 0;
ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6,
@@ -1815,7 +1818,7 @@ out_unlock:
}
static int
-compat_do_replace(void __user *user, unsigned int len)
+compat_do_replace(struct net *net, void __user *user, unsigned int len)
{
int ret;
struct compat_ip6t_replace tmp;
@@ -1852,7 +1855,7 @@ compat_do_replace(void __user *user, unsigned int len)
duprintf("compat_do_replace: Translated table\n");
- ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+ ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
tmp.num_counters, compat_ptr(tmp.counters));
if (ret)
goto free_newinfo_untrans;
@@ -1876,11 +1879,11 @@ compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user,
switch (cmd) {
case IP6T_SO_SET_REPLACE:
- ret = compat_do_replace(user, len);
+ ret = compat_do_replace(sk->sk_net, user, len);
break;
case IP6T_SO_SET_ADD_COUNTERS:
- ret = do_add_counters(user, len, 1);
+ ret = do_add_counters(sk->sk_net, user, len, 1);
break;
default:
@@ -1929,7 +1932,8 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
}
static int
-compat_get_entries(struct compat_ip6t_get_entries __user *uptr, int *len)
+compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr,
+ int *len)
{
int ret;
struct compat_ip6t_get_entries get;
@@ -1950,7 +1954,7 @@ compat_get_entries(struct compat_ip6t_get_entries __user *uptr, int *len)
}
xt_compat_lock(AF_INET6);
- t = xt_find_table_lock(AF_INET6, get.name);
+ t = xt_find_table_lock(net, AF_INET6, get.name);
if (t && !IS_ERR(t)) {
struct xt_table_info *private = t->private;
struct xt_table_info info;
@@ -1986,10 +1990,10 @@ compat_do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
switch (cmd) {
case IP6T_SO_GET_INFO:
- ret = get_info(user, len, 1);
+ ret = get_info(sk->sk_net, user, len, 1);
break;
case IP6T_SO_GET_ENTRIES:
- ret = compat_get_entries(user, len);
+ ret = compat_get_entries(sk->sk_net, user, len);
break;
default:
ret = do_ip6t_get_ctl(sk, cmd, user, len);
@@ -2008,11 +2012,11 @@ do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
switch (cmd) {
case IP6T_SO_SET_REPLACE:
- ret = do_replace(user, len);
+ ret = do_replace(sk->sk_net, user, len);
break;
case IP6T_SO_SET_ADD_COUNTERS:
- ret = do_add_counters(user, len, 0);
+ ret = do_add_counters(sk->sk_net, user, len, 0);
break;
default:
@@ -2033,11 +2037,11 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
switch (cmd) {
case IP6T_SO_GET_INFO:
- ret = get_info(user, len, 0);
+ ret = get_info(sk->sk_net, user, len, 0);
break;
case IP6T_SO_GET_ENTRIES:
- ret = get_entries(user, len);
+ ret = get_entries(sk->sk_net, user, len);
break;
case IP6T_SO_GET_REVISION_MATCH:
@@ -2074,17 +2078,21 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
return ret;
}
-int ip6t_register_table(struct xt_table *table, const struct ip6t_replace *repl)
+struct xt_table *ip6t_register_table(struct net *net, struct xt_table *table,
+ const struct ip6t_replace *repl)
{
int ret;
struct xt_table_info *newinfo;
struct xt_table_info bootstrap
= { 0, 0, 0, { 0 }, { 0 }, { } };
void *loc_cpu_entry;
+ struct xt_table *new_table;
newinfo = xt_alloc_table_info(repl->size);
- if (!newinfo)
- return -ENOMEM;
+ if (!newinfo) {
+ ret = -ENOMEM;
+ goto out;
+ }
/* choose the copy on our node/cpu, but dont care about preemption */
loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
@@ -2095,30 +2103,35 @@ int ip6t_register_table(struct xt_table *table, const struct ip6t_replace *repl)
repl->num_entries,
repl->hook_entry,
repl->underflow);
- if (ret != 0) {
- xt_free_table_info(newinfo);
- return ret;
- }
+ if (ret != 0)
+ goto out_free;
- ret = xt_register_table(table, &bootstrap, newinfo);
- if (ret != 0) {
- xt_free_table_info(newinfo);
- return ret;
+ new_table = xt_register_table(net, table, &bootstrap, newinfo);
+ if (IS_ERR(new_table)) {
+ ret = PTR_ERR(new_table);
+ goto out_free;
}
+ return new_table;
- return 0;
+out_free:
+ xt_free_table_info(newinfo);
+out:
+ return ERR_PTR(ret);
}
void ip6t_unregister_table(struct xt_table *table)
{
struct xt_table_info *private;
void *loc_cpu_entry;
+ struct module *table_owner = table->me;
private = xt_unregister_table(table);
/* Decrease module usage counts and free resources */
loc_cpu_entry = private->entries[raw_smp_processor_id()];
IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL);
+ if (private->number > private->initial_entries)
+ module_put(table_owner);
xt_free_table_info(private);
}
@@ -2225,11 +2238,26 @@ static struct xt_match icmp6_matchstruct __read_mostly = {
.family = AF_INET6,
};
+static int __net_init ip6_tables_net_init(struct net *net)
+{
+ return xt_proto_init(net, AF_INET6);
+}
+
+static void __net_exit ip6_tables_net_exit(struct net *net)
+{
+ xt_proto_fini(net, AF_INET6);
+}
+
+static struct pernet_operations ip6_tables_net_ops = {
+ .init = ip6_tables_net_init,
+ .exit = ip6_tables_net_exit,
+};
+
static int __init ip6_tables_init(void)
{
int ret;
- ret = xt_proto_init(AF_INET6);
+ ret = register_pernet_subsys(&ip6_tables_net_ops);
if (ret < 0)
goto err1;
@@ -2259,7 +2287,7 @@ err4:
err3:
xt_unregister_target(&ip6t_standard_target);
err2:
- xt_proto_fini(AF_INET6);
+ unregister_pernet_subsys(&ip6_tables_net_ops);
err1:
return ret;
}
@@ -2271,7 +2299,8 @@ static void __exit ip6_tables_fini(void)
xt_unregister_match(&icmp6_matchstruct);
xt_unregister_target(&ip6t_error_target);
xt_unregister_target(&ip6t_standard_target);
- xt_proto_fini(AF_INET6);
+
+ unregister_pernet_subsys(&ip6_tables_net_ops);
}
/*
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 87d38d08aad..2d9cd095a72 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -26,7 +26,7 @@ static struct
struct ip6t_replace repl;
struct ip6t_standard entries[3];
struct ip6t_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
.repl = {
.name = "filter",
.valid_hooks = FILTER_VALID_HOOKS,
@@ -67,7 +67,7 @@ ip6t_hook(unsigned int hook,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return ip6t_do_table(skb, hook, in, out, &packet_filter);
+ return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_filter);
}
static unsigned int
@@ -87,7 +87,7 @@ ip6t_local_out_hook(unsigned int hook,
}
#endif
- return ip6t_do_table(skb, hook, in, out, &packet_filter);
+ return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_filter);
}
static struct nf_hook_ops ip6t_ops[] __read_mostly = {
@@ -118,6 +118,26 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
static int forward = NF_ACCEPT;
module_param(forward, bool, 0000);
+static int __net_init ip6table_filter_net_init(struct net *net)
+{
+ /* Register table */
+ net->ipv6.ip6table_filter =
+ ip6t_register_table(net, &packet_filter, &initial_table.repl);
+ if (IS_ERR(net->ipv6.ip6table_filter))
+ return PTR_ERR(net->ipv6.ip6table_filter);
+ return 0;
+}
+
+static void __net_exit ip6table_filter_net_exit(struct net *net)
+{
+ ip6t_unregister_table(net->ipv6.ip6table_filter);
+}
+
+static struct pernet_operations ip6table_filter_net_ops = {
+ .init = ip6table_filter_net_init,
+ .exit = ip6table_filter_net_exit,
+};
+
static int __init ip6table_filter_init(void)
{
int ret;
@@ -130,8 +150,7 @@ static int __init ip6table_filter_init(void)
/* Entry 1 is the FORWARD hook */
initial_table.entries[1].target.verdict = -forward - 1;
- /* Register table */
- ret = ip6t_register_table(&packet_filter, &initial_table.repl);
+ ret = register_pernet_subsys(&ip6table_filter_net_ops);
if (ret < 0)
return ret;
@@ -143,14 +162,14 @@ static int __init ip6table_filter_init(void)
return ret;
cleanup_table:
- ip6t_unregister_table(&packet_filter);
+ unregister_pernet_subsys(&ip6table_filter_net_ops);
return ret;
}
static void __exit ip6table_filter_fini(void)
{
nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
- ip6t_unregister_table(&packet_filter);
+ unregister_pernet_subsys(&ip6table_filter_net_ops);
}
module_init(ip6table_filter_init);
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index d6082600bc5..035343a90ff 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -26,7 +26,7 @@ static struct
struct ip6t_replace repl;
struct ip6t_standard entries[5];
struct ip6t_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
.repl = {
.name = "mangle",
.valid_hooks = MANGLE_VALID_HOOKS,
@@ -73,7 +73,7 @@ ip6t_route_hook(unsigned int hook,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return ip6t_do_table(skb, hook, in, out, &packet_mangler);
+ return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle);
}
static unsigned int
@@ -108,7 +108,7 @@ ip6t_local_hook(unsigned int hook,
/* flowlabel and prio (includes version, which shouldn't change either */
flowlabel = *((u_int32_t *)ipv6_hdr(skb));
- ret = ip6t_do_table(skb, hook, in, out, &packet_mangler);
+ ret = ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle);
if (ret != NF_DROP && ret != NF_STOLEN
&& (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr))
@@ -158,12 +158,31 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
},
};
+static int __net_init ip6table_mangle_net_init(struct net *net)
+{
+ /* Register table */
+ net->ipv6.ip6table_mangle =
+ ip6t_register_table(net, &packet_mangler, &initial_table.repl);
+ if (IS_ERR(net->ipv6.ip6table_mangle))
+ return PTR_ERR(net->ipv6.ip6table_mangle);
+ return 0;
+}
+
+static void __net_exit ip6table_mangle_net_exit(struct net *net)
+{
+ ip6t_unregister_table(net->ipv6.ip6table_mangle);
+}
+
+static struct pernet_operations ip6table_mangle_net_ops = {
+ .init = ip6table_mangle_net_init,
+ .exit = ip6table_mangle_net_exit,
+};
+
static int __init ip6table_mangle_init(void)
{
int ret;
- /* Register table */
- ret = ip6t_register_table(&packet_mangler, &initial_table.repl);
+ ret = register_pernet_subsys(&ip6table_mangle_net_ops);
if (ret < 0)
return ret;
@@ -175,14 +194,14 @@ static int __init ip6table_mangle_init(void)
return ret;
cleanup_table:
- ip6t_unregister_table(&packet_mangler);
+ unregister_pernet_subsys(&ip6table_mangle_net_ops);
return ret;
}
static void __exit ip6table_mangle_fini(void)
{
nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
- ip6t_unregister_table(&packet_mangler);
+ unregister_pernet_subsys(&ip6table_mangle_net_ops);
}
module_init(ip6table_mangle_init);
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index eccbaaa104a..5cd84203abf 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -13,7 +13,7 @@ static struct
struct ip6t_replace repl;
struct ip6t_standard entries[2];
struct ip6t_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
.repl = {
.name = "raw",
.valid_hooks = RAW_VALID_HOOKS,
@@ -51,7 +51,7 @@ ip6t_hook(unsigned int hook,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return ip6t_do_table(skb, hook, in, out, &packet_raw);
+ return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_raw);
}
static struct nf_hook_ops ip6t_ops[] __read_mostly = {
@@ -71,12 +71,31 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
},
};
+static int __net_init ip6table_raw_net_init(struct net *net)
+{
+ /* Register table */
+ net->ipv6.ip6table_raw =
+ ip6t_register_table(net, &packet_raw, &initial_table.repl);
+ if (IS_ERR(net->ipv6.ip6table_raw))
+ return PTR_ERR(net->ipv6.ip6table_raw);
+ return 0;
+}
+
+static void __net_exit ip6table_raw_net_exit(struct net *net)
+{
+ ip6t_unregister_table(net->ipv6.ip6table_raw);
+}
+
+static struct pernet_operations ip6table_raw_net_ops = {
+ .init = ip6table_raw_net_init,
+ .exit = ip6table_raw_net_exit,
+};
+
static int __init ip6table_raw_init(void)
{
int ret;
- /* Register table */
- ret = ip6t_register_table(&packet_raw, &initial_table.repl);
+ ret = register_pernet_subsys(&ip6table_raw_net_ops);
if (ret < 0)
return ret;
@@ -88,14 +107,14 @@ static int __init ip6table_raw_init(void)
return ret;
cleanup_table:
- ip6t_unregister_table(&packet_raw);
+ unregister_pernet_subsys(&ip6table_raw_net_ops);
return ret;
}
static void __exit ip6table_raw_fini(void)
{
nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
- ip6t_unregister_table(&packet_raw);
+ unregister_pernet_subsys(&ip6table_raw_net_ops);
}
module_init(ip6table_raw_init);
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 2d7b0246475..3717bdf34f6 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -30,7 +30,8 @@
static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
struct nf_conntrack_tuple *tuple)
{
- u_int32_t _addrs[8], *ap;
+ const u_int32_t *ap;
+ u_int32_t _addrs[8];
ap = skb_header_pointer(skb, nhoff + offsetof(struct ipv6hdr, saddr),
sizeof(_addrs), _addrs);
@@ -146,8 +147,8 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
int (*okfn)(struct sk_buff *))
{
struct nf_conn *ct;
- struct nf_conn_help *help;
- struct nf_conntrack_helper *helper;
+ const struct nf_conn_help *help;
+ const struct nf_conntrack_helper *helper;
enum ip_conntrack_info ctinfo;
unsigned int ret, protoff;
unsigned int extoff = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index da924c6b5f0..0897d0f4c4a 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -32,7 +32,8 @@ static int icmpv6_pkt_to_tuple(const struct sk_buff *skb,
unsigned int dataoff,
struct nf_conntrack_tuple *tuple)
{
- struct icmp6hdr _hdr, *hp;
+ const struct icmp6hdr *hp;
+ struct icmp6hdr _hdr;
hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
if (hp == NULL)
@@ -45,7 +46,7 @@ static int icmpv6_pkt_to_tuple(const struct sk_buff *skb,
}
/* Add 1; spaces filled with 0. */
-static u_int8_t invmap[] = {
+static const u_int8_t invmap[] = {
[ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1,
[ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1,
[ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1,
@@ -101,24 +102,24 @@ static int icmpv6_packet(struct nf_conn *ct,
}
/* Called when a new connection for this protocol found. */
-static int icmpv6_new(struct nf_conn *conntrack,
+static int icmpv6_new(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff)
{
- static u_int8_t valid_new[] = {
+ static const u_int8_t valid_new[] = {
[ICMPV6_ECHO_REQUEST - 128] = 1,
[ICMPV6_NI_QUERY - 128] = 1
};
- int type = conntrack->tuplehash[0].tuple.dst.u.icmp.type - 128;
+ int type = ct->tuplehash[0].tuple.dst.u.icmp.type - 128;
if (type < 0 || type >= sizeof(valid_new) || !valid_new[type]) {
/* Can't create a new ICMPv6 `conn' with this. */
pr_debug("icmpv6: can't create new conn with type %u\n",
type + 128);
- NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
+ NF_CT_DUMP_TUPLE(&ct->tuplehash[0].tuple);
return 0;
}
- atomic_set(&conntrack->proto.icmp.count, 0);
+ atomic_set(&ct->proto.icmp.count, 0);
return 1;
}
@@ -129,8 +130,8 @@ icmpv6_error_message(struct sk_buff *skb,
unsigned int hooknum)
{
struct nf_conntrack_tuple intuple, origtuple;
- struct nf_conntrack_tuple_hash *h;
- struct nf_conntrack_l4proto *inproto;
+ const struct nf_conntrack_tuple_hash *h;
+ const struct nf_conntrack_l4proto *inproto;
NF_CT_ASSERT(skb->nfct == NULL);
@@ -176,7 +177,8 @@ static int
icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
{
- struct icmp6hdr _ih, *icmp6h;
+ const struct icmp6hdr *icmp6h;
+ struct icmp6hdr _ih;
icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
if (icmp6h == NULL) {
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 022da6ce4c0..2a0d698b24d 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -39,6 +39,7 @@
#include <net/rawv6.h>
#include <net/ndisc.h>
#include <net/addrconf.h>
+#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
#include <linux/sysctl.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6.h>
@@ -680,21 +681,6 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
nf_conntrack_put_reasm(skb);
}
-int nf_ct_frag6_kfree_frags(struct sk_buff *skb)
-{
- struct sk_buff *s, *s2;
-
- for (s = NFCT_FRAG6_CB(skb)->orig; s; s = s2) {
-
- s2 = s->next;
- kfree_skb(s);
- }
-
- kfree_skb(skb);
-
- return 0;
-}
-
int nf_ct_frag6_init(void)
{
nf_frags.hashfn = nf_hashfn;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 4d880551fe6..8897ccf8086 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -641,6 +641,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
skb_reserve(skb, hh_len);
skb->priority = sk->sk_priority;
+ skb->mark = sk->sk_mark;
skb->dst = dst_clone(&rt->u.dst);
skb_put(skb, length);
@@ -767,6 +768,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
*/
memset(&fl, 0, sizeof(fl));
+ fl.mark = sk->sk_mark;
+
if (sin6) {
if (addr_len < SIN6_LEN_RFC2133)
return -EINVAL;
@@ -1259,7 +1262,7 @@ static const struct seq_operations raw6_seq_ops = {
static int raw6_seq_open(struct inode *inode, struct file *file)
{
- return raw_seq_open(inode, file, &raw_v6_hashinfo, PF_INET6);
+ return raw_seq_open(inode, file, &raw_v6_hashinfo, &raw6_seq_ops);
}
static const struct file_operations raw6_seq_fops = {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 4004c5f0b8d..513f72e3db0 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -107,6 +107,7 @@ static struct dst_ops ip6_dst_ops = {
.update_pmtu = ip6_rt_update_pmtu,
.local_out = ip6_local_out,
.entry_size = sizeof(struct rt6_info),
+ .entries = ATOMIC_INIT(0),
};
static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -120,6 +121,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
.check = ip6_dst_check,
.update_pmtu = ip6_rt_blackhole_update_pmtu,
.entry_size = sizeof(struct rt6_info),
+ .entries = ATOMIC_INIT(0),
};
struct rt6_info ip6_null_entry = {
@@ -1907,7 +1909,7 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
*/
if (rt->rt6i_dev == arg->dev &&
!dst_metric_locked(&rt->u.dst, RTAX_MTU) &&
- (dst_mtu(&rt->u.dst) > arg->mtu ||
+ (dst_mtu(&rt->u.dst) >= arg->mtu ||
(dst_mtu(&rt->u.dst) < arg->mtu &&
dst_mtu(&rt->u.dst) == idev->cnf.mtu6))) {
rt->u.dst.metrics[RTAX_MTU-1] = arg->mtu;
@@ -1960,6 +1962,7 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
cfg->fc_nlinfo.nlh = nlh;
+ cfg->fc_nlinfo.nl_net = skb->sk->sk_net;
if (tb[RTA_GATEWAY]) {
nla_memcpy(&cfg->fc_gateway, tb[RTA_GATEWAY], 16);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 00c08399837..59d0029e93a 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -330,8 +330,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
struct tcp_sock *tp;
__u32 seq;
- sk = inet6_lookup(&tcp_hashinfo, &hdr->daddr, th->dest, &hdr->saddr,
- th->source, skb->dev->ifindex);
+ sk = inet6_lookup(skb->dev->nd_net, &tcp_hashinfo, &hdr->daddr,
+ th->dest, &hdr->saddr, th->source, skb->dev->ifindex);
if (sk == NULL) {
ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
@@ -1208,9 +1208,9 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
if (req)
return tcp_check_req(sk, skb, req, prev);
- nsk = __inet6_lookup_established(&tcp_hashinfo, &ipv6_hdr(skb)->saddr,
- th->source, &ipv6_hdr(skb)->daddr,
- ntohs(th->dest), inet6_iif(skb));
+ nsk = __inet6_lookup_established(sk->sk_net, &tcp_hashinfo,
+ &ipv6_hdr(skb)->saddr, th->source,
+ &ipv6_hdr(skb)->daddr, ntohs(th->dest), inet6_iif(skb));
if (nsk) {
if (nsk->sk_state != TCP_TIME_WAIT) {
@@ -1710,9 +1710,10 @@ static int tcp_v6_rcv(struct sk_buff *skb)
TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb));
TCP_SKB_CB(skb)->sacked = 0;
- sk = __inet6_lookup(&tcp_hashinfo, &ipv6_hdr(skb)->saddr, th->source,
- &ipv6_hdr(skb)->daddr, ntohs(th->dest),
- inet6_iif(skb));
+ sk = __inet6_lookup(skb->dev->nd_net, &tcp_hashinfo,
+ &ipv6_hdr(skb)->saddr, th->source,
+ &ipv6_hdr(skb)->daddr, ntohs(th->dest),
+ inet6_iif(skb));
if (!sk)
goto no_tcp_socket;
@@ -1792,7 +1793,7 @@ do_time_wait:
{
struct sock *sk2;
- sk2 = inet6_lookup_listener(&tcp_hashinfo,
+ sk2 = inet6_lookup_listener(skb->dev->nd_net, &tcp_hashinfo,
&ipv6_hdr(skb)->daddr,
ntohs(th->dest), inet6_iif(skb));
if (sk2 != NULL) {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index bd4b9df8f61..53739de829d 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -56,7 +56,8 @@ static inline int udp_v6_get_port(struct sock *sk, unsigned short snum)
return udp_get_port(sk, snum, ipv6_rcv_saddr_equal);
}
-static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,
+static struct sock *__udp6_lib_lookup(struct net *net,
+ struct in6_addr *saddr, __be16 sport,
struct in6_addr *daddr, __be16 dport,
int dif, struct hlist_head udptable[])
{
@@ -69,7 +70,8 @@ static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,
sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
struct inet_sock *inet = inet_sk(sk);
- if (sk->sk_hash == hnum && sk->sk_family == PF_INET6) {
+ if (sk->sk_net == net && sk->sk_hash == hnum &&
+ sk->sk_family == PF_INET6) {
struct ipv6_pinfo *np = inet6_sk(sk);
int score = 0;
if (inet->dport) {
@@ -233,7 +235,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
struct sock *sk;
int err;
- sk = __udp6_lib_lookup(daddr, uh->dest,
+ sk = __udp6_lib_lookup(skb->dev->nd_net, daddr, uh->dest,
saddr, uh->source, inet6_iif(skb), udptable);
if (sk == NULL)
return;
@@ -478,7 +480,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
* check socket cache ... must talk to Alan about his plans
* for sock caches... i'll skip this for now.
*/
- sk = __udp6_lib_lookup(saddr, uh->source,
+ sk = __udp6_lib_lookup(skb->dev->nd_net, saddr, uh->source,
daddr, uh->dest, inet6_iif(skb), udptable);
if (sk == NULL) {
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index c25a6b527fc..7d20199ee1f 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -272,6 +272,7 @@ static struct dst_ops xfrm6_dst_ops = {
.local_out = __ip6_local_out,
.gc_thresh = 1024,
.entry_size = sizeof(struct xfrm_dst),
+ .entries = ATOMIC_INIT(0),
};
static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index fae90ff3108..639fe8a6ff1 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -319,7 +319,7 @@ static void xfrm6_tunnel_destroy(struct xfrm_state *x)
xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr);
}
-static struct xfrm_type xfrm6_tunnel_type = {
+static const struct xfrm_type xfrm6_tunnel_type = {
.description = "IP6IP6",
.owner = THIS_MODULE,
.proto = IPPROTO_IPV6,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 89e1e3070ec..d44c87269bc 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -340,9 +340,42 @@ static u32 ieee80211_rx_load_stats(struct ieee80211_local *local,
return load;
}
+static ieee80211_txrx_result
+ieee80211_rx_h_verify_ip_alignment(struct ieee80211_txrx_data *rx)
+{
+ int hdrlen;
+
+ /*
+ * Drivers are required to align the payload data in a way that
+ * guarantees that the contained IP header is aligned to a four-
+ * byte boundary. In the case of regular frames, this simply means
+ * aligning the payload to a four-byte boundary (because either
+ * the IP header is directly contained, or IV/RFC1042 headers that
+ * have a length divisible by four are in front of it.
+ *
+ * With A-MSDU frames, however, the payload data address must
+ * yield two modulo four because there are 14-byte 802.3 headers
+ * within the A-MSDU frames that push the IP header further back
+ * to a multiple of four again. Thankfully, the specs were sane
+ * enough this time around to require padding each A-MSDU subframe
+ * to a length that is a multiple of four.
+ *
+ * Padding like atheros hardware adds which is inbetween the 802.11
+ * header and the payload is not supported, the driver is required
+ * to move the 802.11 header further back in that case.
+ */
+ hdrlen = ieee80211_get_hdrlen(rx->fc);
+ if (rx->flags & IEEE80211_TXRXD_RX_AMSDU)
+ hdrlen += ETH_HLEN;
+ WARN_ON_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3);
+
+ return TXRX_CONTINUE;
+}
+
ieee80211_rx_handler ieee80211_rx_pre_handlers[] =
{
ieee80211_rx_h_parse_qos,
+ ieee80211_rx_h_verify_ip_alignment,
NULL
};
@@ -1679,7 +1712,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
struct ieee80211_sub_if_data *prev = NULL;
struct sk_buff *skb_new;
u8 *bssid;
- int hdrlen;
hdr = (struct ieee80211_hdr *) skb->data;
memset(&rx, 0, sizeof(rx));
@@ -1691,18 +1723,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
rx.fc = le16_to_cpu(hdr->frame_control);
type = rx.fc & IEEE80211_FCTL_FTYPE;
- /*
- * Drivers are required to align the payload data to a four-byte
- * boundary, so the last two bits of the address where it starts
- * may not be set. The header is required to be directly before
- * the payload data, padding like atheros hardware adds which is
- * inbetween the 802.11 header and the payload is not supported,
- * the driver is required to move the 802.11 header further back
- * in that case.
- */
- hdrlen = ieee80211_get_hdrlen(rx.fc);
- WARN_ON_ONCE(((unsigned long)(skb->data + hdrlen)) & 3);
-
if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT)
local->dot11ReceivedFragmentCount++;
@@ -1952,7 +1972,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
goto end_reorder;
/* null data frames are excluded */
- if (unlikely(fc & IEEE80211_STYPE_QOS_NULLFUNC))
+ if (unlikely(fc & IEEE80211_STYPE_NULLFUNC))
goto end_reorder;
/* new un-ordered ampdu frame - process it */
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 078fff0335a..327e847d270 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -40,7 +40,7 @@
#define NF_CONNTRACK_VERSION "0.5.0"
-DEFINE_RWLOCK(nf_conntrack_lock);
+DEFINE_SPINLOCK(nf_conntrack_lock);
EXPORT_SYMBOL_GPL(nf_conntrack_lock);
/* nf_conntrack_standalone needs this */
@@ -73,15 +73,19 @@ static unsigned int nf_conntrack_hash_rnd;
static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple,
unsigned int size, unsigned int rnd)
{
- unsigned int a, b;
-
- a = jhash2(tuple->src.u3.all, ARRAY_SIZE(tuple->src.u3.all),
- (tuple->src.l3num << 16) | tuple->dst.protonum);
- b = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
- ((__force __u16)tuple->src.u.all << 16) |
- (__force __u16)tuple->dst.u.all);
-
- return ((u64)jhash_2words(a, b, rnd) * size) >> 32;
+ unsigned int n;
+ u_int32_t h;
+
+ /* The direction must be ignored, so we hash everything up to the
+ * destination ports (which is a multiple of 4) and treat the last
+ * three bytes manually.
+ */
+ n = (sizeof(tuple->src) + sizeof(tuple->dst.u3)) / sizeof(u32);
+ h = jhash2((u32 *)tuple, n,
+ rnd ^ (((__force __u16)tuple->dst.u.all << 16) |
+ tuple->dst.protonum));
+
+ return ((u64)h * size) >> 32;
}
static inline u_int32_t hash_conntrack(const struct nf_conntrack_tuple *tuple)
@@ -166,8 +170,8 @@ static void
clean_from_lists(struct nf_conn *ct)
{
pr_debug("clean_from_lists(%p)\n", ct);
- hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
- hlist_del(&ct->tuplehash[IP_CT_DIR_REPLY].hnode);
+ hlist_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
+ hlist_del_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode);
/* Destroy all pending expectations */
nf_ct_remove_expectations(ct);
@@ -199,7 +203,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
rcu_read_unlock();
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
/* Expectations will have been removed in clean_from_lists,
* except TFTP can create an expectation on the first packet,
* before connection is in the list, so we need to clean here,
@@ -213,7 +217,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
}
NF_CT_STAT_INC(delete);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
if (ct->master)
nf_ct_put(ct->master);
@@ -236,26 +240,24 @@ static void death_by_timeout(unsigned long ul_conntrack)
rcu_read_unlock();
}
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
/* Inside lock so preempt is disabled on module removal path.
* Otherwise we can get spurious warnings. */
NF_CT_STAT_INC(delete_list);
clean_from_lists(ct);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
nf_ct_put(ct);
}
struct nf_conntrack_tuple_hash *
-__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
- const struct nf_conn *ignored_conntrack)
+__nf_conntrack_find(const struct nf_conntrack_tuple *tuple)
{
struct nf_conntrack_tuple_hash *h;
struct hlist_node *n;
unsigned int hash = hash_conntrack(tuple);
- hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) {
- if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
- nf_ct_tuple_equal(tuple, &h->tuple)) {
+ hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) {
+ if (nf_ct_tuple_equal(tuple, &h->tuple)) {
NF_CT_STAT_INC(found);
return h;
}
@@ -271,12 +273,16 @@ struct nf_conntrack_tuple_hash *
nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple)
{
struct nf_conntrack_tuple_hash *h;
+ struct nf_conn *ct;
- read_lock_bh(&nf_conntrack_lock);
- h = __nf_conntrack_find(tuple, NULL);
- if (h)
- atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
+ h = __nf_conntrack_find(tuple);
+ if (h) {
+ ct = nf_ct_tuplehash_to_ctrack(h);
+ if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
+ h = NULL;
+ }
+ rcu_read_unlock();
return h;
}
@@ -286,10 +292,10 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
unsigned int hash,
unsigned int repl_hash)
{
- hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
- &nf_conntrack_hash[hash]);
- hlist_add_head(&ct->tuplehash[IP_CT_DIR_REPLY].hnode,
- &nf_conntrack_hash[repl_hash]);
+ hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
+ &nf_conntrack_hash[hash]);
+ hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode,
+ &nf_conntrack_hash[repl_hash]);
}
void nf_conntrack_hash_insert(struct nf_conn *ct)
@@ -299,9 +305,9 @@ void nf_conntrack_hash_insert(struct nf_conn *ct)
hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
__nf_conntrack_hash_insert(ct, hash, repl_hash);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
}
EXPORT_SYMBOL_GPL(nf_conntrack_hash_insert);
@@ -338,7 +344,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
pr_debug("Confirming conntrack %p\n", ct);
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
/* See if there's one in the list already, including reverse:
NAT could have grabbed it without realizing, since we're
@@ -364,7 +370,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
atomic_inc(&ct->ct_general.use);
set_bit(IPS_CONFIRMED_BIT, &ct->status);
NF_CT_STAT_INC(insert);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
help = nfct_help(ct);
if (help && help->helper)
nf_conntrack_event_cache(IPCT_HELPER, skb);
@@ -379,7 +385,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
out:
NF_CT_STAT_INC(insert_failed);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return NF_DROP;
}
EXPORT_SYMBOL_GPL(__nf_conntrack_confirm);
@@ -391,12 +397,22 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
const struct nf_conn *ignored_conntrack)
{
struct nf_conntrack_tuple_hash *h;
+ struct hlist_node *n;
+ unsigned int hash = hash_conntrack(tuple);
- read_lock_bh(&nf_conntrack_lock);
- h = __nf_conntrack_find(tuple, ignored_conntrack);
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) {
+ if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
+ nf_ct_tuple_equal(tuple, &h->tuple)) {
+ NF_CT_STAT_INC(found);
+ rcu_read_unlock();
+ return 1;
+ }
+ NF_CT_STAT_INC(searched);
+ }
+ rcu_read_unlock();
- return h != NULL;
+ return 0;
}
EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
@@ -404,7 +420,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
/* There's a small race here where we may free a just-assured
connection. Too bad: we're in trouble anyway. */
-static int early_drop(unsigned int hash)
+static noinline int early_drop(unsigned int hash)
{
/* Use oldest entry, which is roughly LRU */
struct nf_conntrack_tuple_hash *h;
@@ -413,21 +429,23 @@ static int early_drop(unsigned int hash)
unsigned int i, cnt = 0;
int dropped = 0;
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
for (i = 0; i < nf_conntrack_htable_size; i++) {
- hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) {
+ hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash],
+ hnode) {
tmp = nf_ct_tuplehash_to_ctrack(h);
if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
ct = tmp;
cnt++;
}
+
+ if (ct && unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
+ ct = NULL;
if (ct || cnt >= NF_CT_EVICTION_RANGE)
break;
hash = (hash + 1) % nf_conntrack_htable_size;
}
- if (ct)
- atomic_inc(&ct->ct_general.use);
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
if (!ct)
return dropped;
@@ -444,7 +462,7 @@ static int early_drop(unsigned int hash)
struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
const struct nf_conntrack_tuple *repl)
{
- struct nf_conn *conntrack = NULL;
+ struct nf_conn *ct = NULL;
if (unlikely(!nf_conntrack_hash_rnd_initted)) {
get_random_bytes(&nf_conntrack_hash_rnd, 4);
@@ -454,8 +472,8 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
/* We don't want any race condition at early drop stage */
atomic_inc(&nf_conntrack_count);
- if (nf_conntrack_max
- && atomic_read(&nf_conntrack_count) > nf_conntrack_max) {
+ if (nf_conntrack_max &&
+ unlikely(atomic_read(&nf_conntrack_count) > nf_conntrack_max)) {
unsigned int hash = hash_conntrack(orig);
if (!early_drop(hash)) {
atomic_dec(&nf_conntrack_count);
@@ -467,30 +485,37 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
}
}
- conntrack = kmem_cache_zalloc(nf_conntrack_cachep, GFP_ATOMIC);
- if (conntrack == NULL) {
+ ct = kmem_cache_zalloc(nf_conntrack_cachep, GFP_ATOMIC);
+ if (ct == NULL) {
pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n");
atomic_dec(&nf_conntrack_count);
return ERR_PTR(-ENOMEM);
}
- atomic_set(&conntrack->ct_general.use, 1);
- conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
- conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
+ atomic_set(&ct->ct_general.use, 1);
+ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
+ ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
/* Don't set timer yet: wait for confirmation */
- setup_timer(&conntrack->timeout, death_by_timeout,
- (unsigned long)conntrack);
+ setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
+ INIT_RCU_HEAD(&ct->rcu);
- return conntrack;
+ return ct;
}
EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
-void nf_conntrack_free(struct nf_conn *conntrack)
+static void nf_conntrack_free_rcu(struct rcu_head *head)
{
- nf_ct_ext_free(conntrack);
- kmem_cache_free(nf_conntrack_cachep, conntrack);
+ struct nf_conn *ct = container_of(head, struct nf_conn, rcu);
+
+ nf_ct_ext_free(ct);
+ kmem_cache_free(nf_conntrack_cachep, ct);
atomic_dec(&nf_conntrack_count);
}
+
+void nf_conntrack_free(struct nf_conn *ct)
+{
+ call_rcu(&ct->rcu, nf_conntrack_free_rcu);
+}
EXPORT_SYMBOL_GPL(nf_conntrack_free);
/* Allocate a new conntrack: we return -ENOMEM if classification
@@ -502,7 +527,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
struct sk_buff *skb,
unsigned int dataoff)
{
- struct nf_conn *conntrack;
+ struct nf_conn *ct;
struct nf_conn_help *help;
struct nf_conntrack_tuple repl_tuple;
struct nf_conntrack_expect *exp;
@@ -512,46 +537,46 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
return NULL;
}
- conntrack = nf_conntrack_alloc(tuple, &repl_tuple);
- if (conntrack == NULL || IS_ERR(conntrack)) {
+ ct = nf_conntrack_alloc(tuple, &repl_tuple);
+ if (ct == NULL || IS_ERR(ct)) {
pr_debug("Can't allocate conntrack.\n");
- return (struct nf_conntrack_tuple_hash *)conntrack;
+ return (struct nf_conntrack_tuple_hash *)ct;
}
- if (!l4proto->new(conntrack, skb, dataoff)) {
- nf_conntrack_free(conntrack);
+ if (!l4proto->new(ct, skb, dataoff)) {
+ nf_conntrack_free(ct);
pr_debug("init conntrack: can't track with proto module\n");
return NULL;
}
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
exp = nf_ct_find_expectation(tuple);
if (exp) {
pr_debug("conntrack: expectation arrives ct=%p exp=%p\n",
- conntrack, exp);
+ ct, exp);
/* Welcome, Mr. Bond. We've been expecting you... */
- __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
- conntrack->master = exp->master;
+ __set_bit(IPS_EXPECTED_BIT, &ct->status);
+ ct->master = exp->master;
if (exp->helper) {
- help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
+ help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
if (help)
rcu_assign_pointer(help->helper, exp->helper);
}
#ifdef CONFIG_NF_CONNTRACK_MARK
- conntrack->mark = exp->master->mark;
+ ct->mark = exp->master->mark;
#endif
#ifdef CONFIG_NF_CONNTRACK_SECMARK
- conntrack->secmark = exp->master->secmark;
+ ct->secmark = exp->master->secmark;
#endif
- nf_conntrack_get(&conntrack->master->ct_general);
+ nf_conntrack_get(&ct->master->ct_general);
NF_CT_STAT_INC(expect_new);
} else {
struct nf_conntrack_helper *helper;
helper = __nf_ct_helper_find(&repl_tuple);
if (helper) {
- help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
+ help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
if (help)
rcu_assign_pointer(help->helper, helper);
}
@@ -559,18 +584,17 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
}
/* Overload tuple linked list to put us in unconfirmed list. */
- hlist_add_head(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
- &unconfirmed);
+ hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode, &unconfirmed);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
if (exp) {
if (exp->expectfn)
- exp->expectfn(conntrack, exp);
+ exp->expectfn(ct, exp);
nf_ct_expect_put(exp);
}
- return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
+ return &ct->tuplehash[IP_CT_DIR_ORIGINAL];
}
/* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
@@ -729,7 +753,6 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
struct nf_conn_help *help = nfct_help(ct);
struct nf_conntrack_helper *helper;
- write_lock_bh(&nf_conntrack_lock);
/* Should be unconfirmed, so not in hash table yet */
NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
@@ -738,8 +761,9 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
if (ct->master || (help && help->expecting != 0))
- goto out;
+ return;
+ rcu_read_lock();
helper = __nf_ct_helper_find(newreply);
if (helper == NULL) {
if (help)
@@ -757,7 +781,7 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
rcu_assign_pointer(help->helper, helper);
out:
- write_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
@@ -773,13 +797,11 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct);
NF_CT_ASSERT(skb);
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
/* Only update if this is not a fixed timeout */
- if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) {
- write_unlock_bh(&nf_conntrack_lock);
- return;
- }
+ if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status))
+ goto acct;
/* If not in hash table, timer will not be active yet */
if (!nf_ct_is_confirmed(ct)) {
@@ -799,6 +821,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
}
}
+acct:
#ifdef CONFIG_NF_CT_ACCT
if (do_acct) {
ct->counters[CTINFO2DIR(ctinfo)].packets++;
@@ -811,7 +834,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
}
#endif
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
/* must be unlocked when calling event cache */
if (event)
@@ -879,14 +902,6 @@ static void nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
nf_conntrack_get(nskb->nfct);
}
-static inline int
-do_iter(const struct nf_conntrack_tuple_hash *i,
- int (*iter)(struct nf_conn *i, void *data),
- void *data)
-{
- return iter(nf_ct_tuplehash_to_ctrack(i), data);
-}
-
/* Bring out ya dead! */
static struct nf_conn *
get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
@@ -896,7 +911,7 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
struct nf_conn *ct;
struct hlist_node *n;
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
hlist_for_each_entry(h, n, &nf_conntrack_hash[*bucket], hnode) {
ct = nf_ct_tuplehash_to_ctrack(h);
@@ -909,11 +924,11 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
if (iter(ct, data))
set_bit(IPS_DYING_BIT, &ct->status);
}
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return NULL;
found:
atomic_inc(&ct->ct_general.use);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return ct;
}
@@ -939,7 +954,7 @@ static int kill_all(struct nf_conn *i, void *data)
return 1;
}
-void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, int size)
+void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, unsigned int size)
{
if (vmalloced)
vfree(hash);
@@ -988,7 +1003,7 @@ void nf_conntrack_cleanup(void)
nf_conntrack_expect_fini();
}
-struct hlist_head *nf_ct_alloc_hashtable(int *sizep, int *vmalloced)
+struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced)
{
struct hlist_head *hash;
unsigned int size, i;
@@ -1015,8 +1030,8 @@ EXPORT_SYMBOL_GPL(nf_ct_alloc_hashtable);
int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
{
- int i, bucket, hashsize, vmalloced;
- int old_vmalloced, old_size;
+ int i, bucket, vmalloced, old_vmalloced;
+ unsigned int hashsize, old_size;
int rnd;
struct hlist_head *hash, *old_hash;
struct nf_conntrack_tuple_hash *h;
@@ -1025,7 +1040,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
if (!nf_conntrack_htable_size)
return param_set_uint(val, kp);
- hashsize = simple_strtol(val, NULL, 0);
+ hashsize = simple_strtoul(val, NULL, 0);
if (!hashsize)
return -EINVAL;
@@ -1037,12 +1052,17 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
* use a newrandom seed */
get_random_bytes(&rnd, 4);
- write_lock_bh(&nf_conntrack_lock);
+ /* Lookups in the old hash might happen in parallel, which means we
+ * might get false negatives during connection lookup. New connections
+ * created because of a false negative won't make it into the hash
+ * though since that required taking the lock.
+ */
+ spin_lock_bh(&nf_conntrack_lock);
for (i = 0; i < nf_conntrack_htable_size; i++) {
while (!hlist_empty(&nf_conntrack_hash[i])) {
h = hlist_entry(nf_conntrack_hash[i].first,
struct nf_conntrack_tuple_hash, hnode);
- hlist_del(&h->hnode);
+ hlist_del_rcu(&h->hnode);
bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
hlist_add_head(&h->hnode, &hash[bucket]);
}
@@ -1055,7 +1075,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
nf_conntrack_vmalloc = vmalloced;
nf_conntrack_hash = hash;
nf_conntrack_hash_rnd = rnd;
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
nf_ct_free_hashtable(old_hash, old_vmalloced, old_size);
return 0;
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index e0cd9d00aa6..e06bf0028bb 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -50,7 +50,7 @@ void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
NF_CT_ASSERT(master_help);
NF_CT_ASSERT(!timer_pending(&exp->timeout));
- hlist_del(&exp->hnode);
+ hlist_del_rcu(&exp->hnode);
nf_ct_expect_count--;
hlist_del(&exp->lnode);
@@ -65,9 +65,9 @@ static void nf_ct_expectation_timed_out(unsigned long ul_expect)
{
struct nf_conntrack_expect *exp = (void *)ul_expect;
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
nf_ct_unlink_expect(exp);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
nf_ct_expect_put(exp);
}
@@ -97,7 +97,7 @@ __nf_ct_expect_find(const struct nf_conntrack_tuple *tuple)
return NULL;
h = nf_ct_expect_dst_hash(tuple);
- hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) {
+ hlist_for_each_entry_rcu(i, n, &nf_ct_expect_hash[h], hnode) {
if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask))
return i;
}
@@ -111,11 +111,11 @@ nf_ct_expect_find_get(const struct nf_conntrack_tuple *tuple)
{
struct nf_conntrack_expect *i;
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
i = __nf_ct_expect_find(tuple);
- if (i)
- atomic_inc(&i->use);
- read_unlock_bh(&nf_conntrack_lock);
+ if (i && !atomic_inc_not_zero(&i->use))
+ i = NULL;
+ rcu_read_unlock();
return i;
}
@@ -201,12 +201,12 @@ static inline int expect_matches(const struct nf_conntrack_expect *a,
/* Generally a bad idea to call this: could have matched already. */
void nf_ct_unexpect_related(struct nf_conntrack_expect *exp)
{
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
if (del_timer(&exp->timeout)) {
nf_ct_unlink_expect(exp);
nf_ct_expect_put(exp);
}
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
}
EXPORT_SYMBOL_GPL(nf_ct_unexpect_related);
@@ -223,6 +223,7 @@ struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me)
new->master = me;
atomic_set(&new->use, 1);
+ INIT_RCU_HEAD(&new->rcu);
return new;
}
EXPORT_SYMBOL_GPL(nf_ct_expect_alloc);
@@ -278,10 +279,18 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
}
EXPORT_SYMBOL_GPL(nf_ct_expect_init);
+static void nf_ct_expect_free_rcu(struct rcu_head *head)
+{
+ struct nf_conntrack_expect *exp;
+
+ exp = container_of(head, struct nf_conntrack_expect, rcu);
+ kmem_cache_free(nf_ct_expect_cachep, exp);
+}
+
void nf_ct_expect_put(struct nf_conntrack_expect *exp)
{
if (atomic_dec_and_test(&exp->use))
- kmem_cache_free(nf_ct_expect_cachep, exp);
+ call_rcu(&exp->rcu, nf_ct_expect_free_rcu);
}
EXPORT_SYMBOL_GPL(nf_ct_expect_put);
@@ -295,7 +304,7 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
hlist_add_head(&exp->lnode, &master_help->expectations);
master_help->expecting++;
- hlist_add_head(&exp->hnode, &nf_ct_expect_hash[h]);
+ hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]);
nf_ct_expect_count++;
setup_timer(&exp->timeout, nf_ct_expectation_timed_out,
@@ -346,7 +355,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
NF_CT_ASSERT(master_help);
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
if (!master_help->helper) {
ret = -ESHUTDOWN;
goto out;
@@ -381,7 +390,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
nf_ct_expect_event(IPEXP_NEW, expect);
ret = 0;
out:
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return ret;
}
EXPORT_SYMBOL_GPL(nf_ct_expect_related);
@@ -394,10 +403,12 @@ struct ct_expect_iter_state {
static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
{
struct ct_expect_iter_state *st = seq->private;
+ struct hlist_node *n;
for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
- if (!hlist_empty(&nf_ct_expect_hash[st->bucket]))
- return nf_ct_expect_hash[st->bucket].first;
+ n = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
+ if (n)
+ return n;
}
return NULL;
}
@@ -407,11 +418,11 @@ static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
{
struct ct_expect_iter_state *st = seq->private;
- head = head->next;
+ head = rcu_dereference(head->next);
while (head == NULL) {
if (++st->bucket >= nf_ct_expect_hsize)
return NULL;
- head = nf_ct_expect_hash[st->bucket].first;
+ head = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
}
return head;
}
@@ -427,8 +438,9 @@ static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
}
static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
return ct_expect_get_idx(seq, *pos);
}
@@ -439,8 +451,9 @@ static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void exp_seq_stop(struct seq_file *seq, void *v)
+ __releases(RCU)
{
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
}
static int exp_seq_show(struct seq_file *s, void *v)
diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c
index ff66fba514f..867882313e4 100644
--- a/net/netfilter/nf_conntrack_h323_asn1.c
+++ b/net/netfilter/nf_conntrack_h323_asn1.c
@@ -87,7 +87,7 @@ typedef struct field_t {
unsigned char ub;
unsigned short attr;
unsigned short offset;
- struct field_t *fields;
+ const struct field_t *fields;
} field_t;
/* Bit Stream */
@@ -96,7 +96,7 @@ typedef struct {
unsigned char *beg;
unsigned char *end;
unsigned char *cur;
- unsigned bit;
+ unsigned int bit;
} bitstr_t;
/* Tool Functions */
@@ -104,29 +104,29 @@ typedef struct {
#define INC_BITS(bs,b) if(((bs)->bit+=(b))>7){(bs)->cur+=(bs)->bit>>3;(bs)->bit&=7;}
#define BYTE_ALIGN(bs) if((bs)->bit){(bs)->cur++;(bs)->bit=0;}
#define CHECK_BOUND(bs,n) if((bs)->cur+(n)>(bs)->end)return(H323_ERROR_BOUND)
-static unsigned get_len(bitstr_t * bs);
-static unsigned get_bit(bitstr_t * bs);
-static unsigned get_bits(bitstr_t * bs, unsigned b);
-static unsigned get_bitmap(bitstr_t * bs, unsigned b);
-static unsigned get_uint(bitstr_t * bs, int b);
+static unsigned int get_len(bitstr_t *bs);
+static unsigned int get_bit(bitstr_t *bs);
+static unsigned int get_bits(bitstr_t *bs, unsigned int b);
+static unsigned int get_bitmap(bitstr_t *bs, unsigned int b);
+static unsigned int get_uint(bitstr_t *bs, int b);
/* Decoder Functions */
-static int decode_nul(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_bool(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_oid(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_int(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_enum(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_seq(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_choice(bitstr_t * bs, field_t * f, char *base, int level);
+static int decode_nul(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_bool(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_oid(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_int(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_enum(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_bitstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_numstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_octstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_bmpstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_seq(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_seqof(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_choice(bitstr_t *bs, const struct field_t *f, char *base, int level);
/* Decoder Functions Vector */
-typedef int (*decoder_t) (bitstr_t *, field_t *, char *, int);
-static decoder_t Decoders[] = {
+typedef int (*decoder_t)(bitstr_t *, const struct field_t *, char *, int);
+static const decoder_t Decoders[] = {
decode_nul,
decode_bool,
decode_oid,
@@ -150,9 +150,9 @@ static decoder_t Decoders[] = {
* Functions
****************************************************************************/
/* Assume bs is aligned && v < 16384 */
-unsigned get_len(bitstr_t * bs)
+static unsigned int get_len(bitstr_t *bs)
{
- unsigned v;
+ unsigned int v;
v = *bs->cur++;
@@ -166,9 +166,9 @@ unsigned get_len(bitstr_t * bs)
}
/****************************************************************************/
-unsigned get_bit(bitstr_t * bs)
+static unsigned int get_bit(bitstr_t *bs)
{
- unsigned b = (*bs->cur) & (0x80 >> bs->bit);
+ unsigned int b = (*bs->cur) & (0x80 >> bs->bit);
INC_BIT(bs);
@@ -177,9 +177,9 @@ unsigned get_bit(bitstr_t * bs)
/****************************************************************************/
/* Assume b <= 8 */
-unsigned get_bits(bitstr_t * bs, unsigned b)
+static unsigned int get_bits(bitstr_t *bs, unsigned int b)
{
- unsigned v, l;
+ unsigned int v, l;
v = (*bs->cur) & (0xffU >> bs->bit);
l = b + bs->bit;
@@ -203,9 +203,9 @@ unsigned get_bits(bitstr_t * bs, unsigned b)
/****************************************************************************/
/* Assume b <= 32 */
-unsigned get_bitmap(bitstr_t * bs, unsigned b)
+static unsigned int get_bitmap(bitstr_t *bs, unsigned int b)
{
- unsigned v, l, shift, bytes;
+ unsigned int v, l, shift, bytes;
if (!b)
return 0;
@@ -213,18 +213,18 @@ unsigned get_bitmap(bitstr_t * bs, unsigned b)
l = bs->bit + b;
if (l < 8) {
- v = (unsigned) (*bs->cur) << (bs->bit + 24);
+ v = (unsigned int)(*bs->cur) << (bs->bit + 24);
bs->bit = l;
} else if (l == 8) {
- v = (unsigned) (*bs->cur++) << (bs->bit + 24);
+ v = (unsigned int)(*bs->cur++) << (bs->bit + 24);
bs->bit = 0;
} else {
for (bytes = l >> 3, shift = 24, v = 0; bytes;
bytes--, shift -= 8)
- v |= (unsigned) (*bs->cur++) << shift;
+ v |= (unsigned int)(*bs->cur++) << shift;
if (l < 32) {
- v |= (unsigned) (*bs->cur) << shift;
+ v |= (unsigned int)(*bs->cur) << shift;
v <<= bs->bit;
} else if (l > 32) {
v <<= bs->bit;
@@ -242,9 +242,9 @@ unsigned get_bitmap(bitstr_t * bs, unsigned b)
/****************************************************************************
* Assume bs is aligned and sizeof(unsigned int) == 4
****************************************************************************/
-unsigned get_uint(bitstr_t * bs, int b)
+static unsigned int get_uint(bitstr_t *bs, int b)
{
- unsigned v = 0;
+ unsigned int v = 0;
switch (b) {
case 4:
@@ -264,7 +264,8 @@ unsigned get_uint(bitstr_t * bs, int b)
}
/****************************************************************************/
-int decode_nul(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_nul(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -272,7 +273,8 @@ int decode_nul(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_bool(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_bool(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -283,7 +285,8 @@ int decode_bool(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_oid(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_oid(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
int len;
@@ -299,9 +302,10 @@ int decode_oid(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_int(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_int(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned len;
+ unsigned int len;
PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
@@ -318,9 +322,9 @@ int decode_int(bitstr_t * bs, field_t * f, char *base, int level)
len = get_bits(bs, 2) + 1;
BYTE_ALIGN(bs);
if (base && (f->attr & DECODE)) { /* timeToLive */
- unsigned v = get_uint(bs, len) + f->lb;
+ unsigned int v = get_uint(bs, len) + f->lb;
PRINT(" = %u", v);
- *((unsigned *) (base + f->offset)) = v;
+ *((unsigned int *)(base + f->offset)) = v;
}
bs->cur += len;
break;
@@ -342,7 +346,8 @@ int decode_int(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_enum(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_enum(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -357,9 +362,10 @@ int decode_enum(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_bitstr(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned len;
+ unsigned int len;
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -390,9 +396,10 @@ int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_numstr(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned len;
+ unsigned int len;
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -407,9 +414,10 @@ int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_octstr(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned len;
+ unsigned int len;
PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
@@ -424,7 +432,7 @@ int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level)
bs->cur[0], bs->cur[1],
bs->cur[2], bs->cur[3],
bs->cur[4] * 256 + bs->cur[5]));
- *((unsigned *) (base + f->offset)) =
+ *((unsigned int *)(base + f->offset)) =
bs->cur - bs->buf;
}
}
@@ -455,9 +463,10 @@ int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_bmpstr(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned len;
+ unsigned int len;
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -480,11 +489,12 @@ int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_seq(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned ext, bmp, i, opt, len = 0, bmp2, bmp2_len;
+ unsigned int ext, bmp, i, opt, len = 0, bmp2, bmp2_len;
int err;
- field_t *son;
+ const struct field_t *son;
unsigned char *beg = NULL;
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -498,7 +508,7 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
/* Get fields bitmap */
bmp = get_bitmap(bs, f->sz);
if (base)
- *(unsigned *) base = bmp;
+ *(unsigned int *)base = bmp;
/* Decode the root components */
for (i = opt = 0, son = f->fields; i < f->lb; i++, son++) {
@@ -550,7 +560,7 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
bmp2 = get_bitmap(bs, bmp2_len);
bmp |= bmp2 >> f->sz;
if (base)
- *(unsigned *) base = bmp;
+ *(unsigned int *)base = bmp;
BYTE_ALIGN(bs);
/* Decode the extension components */
@@ -596,11 +606,12 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_seqof(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned count, effective_count = 0, i, len = 0;
+ unsigned int count, effective_count = 0, i, len = 0;
int err;
- field_t *son;
+ const struct field_t *son;
unsigned char *beg = NULL;
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -636,8 +647,8 @@ int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level)
/* Write Count */
if (base) {
effective_count = count > f->ub ? f->ub : count;
- *(unsigned *) base = effective_count;
- base += sizeof(unsigned);
+ *(unsigned int *)base = effective_count;
+ base += sizeof(unsigned int);
}
/* Decode nested field */
@@ -685,11 +696,12 @@ int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level)
/****************************************************************************/
-int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_choice(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned type, ext, len = 0;
+ unsigned int type, ext, len = 0;
int err;
- field_t *son;
+ const struct field_t *son;
unsigned char *beg = NULL;
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -710,7 +722,7 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
/* Write Type */
if (base)
- *(unsigned *) base = type;
+ *(unsigned int *)base = type;
/* Check Range */
if (type >= f->ub) { /* Newer version? */
@@ -754,9 +766,9 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage * ras)
+int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage *ras)
{
- static field_t ras_message = {
+ static const struct field_t ras_message = {
FNAME("RasMessage") CHOICE, 5, 24, 32, DECODE | EXT,
0, _RasMessage
};
@@ -771,9 +783,9 @@ int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage * ras)
/****************************************************************************/
static int DecodeH323_UserInformation(unsigned char *buf, unsigned char *beg,
- size_t sz, H323_UserInformation * uuie)
+ size_t sz, H323_UserInformation *uuie)
{
- static field_t h323_userinformation = {
+ static const struct field_t h323_userinformation = {
FNAME("H323-UserInformation") SEQ, 1, 2, 2, DECODE | EXT,
0, _H323_UserInformation
};
@@ -792,7 +804,7 @@ int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz,
MultimediaSystemControlMessage *
mscm)
{
- static field_t multimediasystemcontrolmessage = {
+ static const struct field_t multimediasystemcontrolmessage = {
FNAME("MultimediaSystemControlMessage") CHOICE, 2, 4, 4,
DECODE | EXT, 0, _MultimediaSystemControlMessage
};
@@ -807,7 +819,7 @@ int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz,
}
/****************************************************************************/
-int DecodeQ931(unsigned char *buf, size_t sz, Q931 * q931)
+int DecodeQ931(unsigned char *buf, size_t sz, Q931 *q931)
{
unsigned char *p = buf;
int len;
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 872c1aa3124..62137879e6a 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -114,7 +114,8 @@ static int get_tpkt_data(struct sk_buff *skb, unsigned int protoff,
{
struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
int dir = CTINFO2DIR(ctinfo);
- struct tcphdr _tcph, *th;
+ const struct tcphdr *th;
+ struct tcphdr _tcph;
int tcpdatalen;
int tcpdataoff;
unsigned char *tpkt;
@@ -212,11 +213,11 @@ static int get_tpkt_data(struct sk_buff *skb, unsigned int protoff,
}
/****************************************************************************/
-static int get_h245_addr(struct nf_conn *ct, unsigned char *data,
+static int get_h245_addr(struct nf_conn *ct, const unsigned char *data,
H245_TransportAddress *taddr,
union nf_inet_addr *addr, __be16 *port)
{
- unsigned char *p;
+ const unsigned char *p;
int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
int len;
@@ -625,7 +626,7 @@ int get_h225_addr(struct nf_conn *ct, unsigned char *data,
TransportAddress *taddr,
union nf_inet_addr *addr, __be16 *port)
{
- unsigned char *p;
+ const unsigned char *p;
int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
int len;
@@ -704,9 +705,8 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
/* If the calling party is on the same side of the forward-to party,
* we don't need to track the second call */
-static int callforward_do_filter(union nf_inet_addr *src,
- union nf_inet_addr *dst,
- int family)
+static int callforward_do_filter(const union nf_inet_addr *src,
+ const union nf_inet_addr *dst, int family)
{
const struct nf_afinfo *afinfo;
struct flowi fl1, fl2;
@@ -1185,7 +1185,8 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
static unsigned char *get_udp_data(struct sk_buff *skb, unsigned int protoff,
int *datalen)
{
- struct udphdr _uh, *uh;
+ const struct udphdr *uh;
+ struct udphdr _uh;
int dataoff;
uh = skb_header_pointer(skb, protoff, sizeof(_uh), &_uh);
@@ -1415,7 +1416,7 @@ static int process_rcf(struct sk_buff *skb, struct nf_conn *ct,
nf_ct_refresh(ct, skb, info->timeout * HZ);
/* Set expect timeout */
- read_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
exp = find_expect(ct, &ct->tuplehash[dir].tuple.dst.u3,
info->sig_port[!dir]);
if (exp) {
@@ -1425,7 +1426,7 @@ static int process_rcf(struct sk_buff *skb, struct nf_conn *ct,
NF_CT_DUMP_TUPLE(&exp->tuple);
set_expect_timeout(exp, info->timeout);
}
- read_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
}
return 0;
@@ -1468,7 +1469,7 @@ static int process_arq(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, AdmissionRequest *arq)
{
- struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
+ const struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
int dir = CTINFO2DIR(ctinfo);
__be16 port;
union nf_inet_addr addr;
diff --git a/net/netfilter/nf_conntrack_h323_types.c b/net/netfilter/nf_conntrack_h323_types.c
index 3a21fdf1a26..d880f3523c1 100644
--- a/net/netfilter/nf_conntrack_h323_types.c
+++ b/net/netfilter/nf_conntrack_h323_types.c
@@ -5,22 +5,22 @@
* This source code is licensed under General Public License version 2.
*/
-static field_t _TransportAddress_ipAddress[] = { /* SEQUENCE */
+static const struct field_t _TransportAddress_ipAddress[] = { /* SEQUENCE */
{FNAME("ip") OCTSTR, FIXD, 4, 0, DECODE,
offsetof(TransportAddress_ipAddress, ip), NULL},
{FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _TransportAddress_ipSourceRoute_route[] = { /* SEQUENCE OF */
+static const struct field_t _TransportAddress_ipSourceRoute_route[] = { /* SEQUENCE OF */
{FNAME("item") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
};
-static field_t _TransportAddress_ipSourceRoute_routing[] = { /* CHOICE */
+static const struct field_t _TransportAddress_ipSourceRoute_routing[] = { /* CHOICE */
{FNAME("strict") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("loose") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _TransportAddress_ipSourceRoute[] = { /* SEQUENCE */
+static const struct field_t _TransportAddress_ipSourceRoute[] = { /* SEQUENCE */
{FNAME("ip") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
{FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
{FNAME("route") SEQOF, SEMI, 0, 0, SKIP, 0,
@@ -29,37 +29,37 @@ static field_t _TransportAddress_ipSourceRoute[] = { /* SEQUENCE */
_TransportAddress_ipSourceRoute_routing},
};
-static field_t _TransportAddress_ipxAddress[] = { /* SEQUENCE */
+static const struct field_t _TransportAddress_ipxAddress[] = { /* SEQUENCE */
{FNAME("node") OCTSTR, FIXD, 6, 0, SKIP, 0, NULL},
{FNAME("netnum") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
{FNAME("port") OCTSTR, FIXD, 2, 0, SKIP, 0, NULL},
};
-static field_t _TransportAddress_ip6Address[] = { /* SEQUENCE */
+static const struct field_t _TransportAddress_ip6Address[] = { /* SEQUENCE */
{FNAME("ip") OCTSTR, FIXD, 16, 0, DECODE,
offsetof(TransportAddress_ip6Address, ip), NULL},
{FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _H221NonStandard[] = { /* SEQUENCE */
+static const struct field_t _H221NonStandard[] = { /* SEQUENCE */
{FNAME("t35CountryCode") INT, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("t35Extension") INT, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("manufacturerCode") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _NonStandardIdentifier[] = { /* CHOICE */
+static const struct field_t _NonStandardIdentifier[] = { /* CHOICE */
{FNAME("object") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("h221NonStandard") SEQ, 0, 3, 3, SKIP | EXT, 0,
_H221NonStandard},
};
-static field_t _NonStandardParameter[] = { /* SEQUENCE */
+static const struct field_t _NonStandardParameter[] = { /* SEQUENCE */
{FNAME("nonStandardIdentifier") CHOICE, 1, 2, 2, SKIP | EXT, 0,
_NonStandardIdentifier},
{FNAME("data") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _TransportAddress[] = { /* CHOICE */
+static const struct field_t _TransportAddress[] = { /* CHOICE */
{FNAME("ipAddress") SEQ, 0, 2, 2, DECODE,
offsetof(TransportAddress, ipAddress), _TransportAddress_ipAddress},
{FNAME("ipSourceRoute") SEQ, 0, 4, 4, SKIP | EXT, 0,
@@ -75,7 +75,7 @@ static field_t _TransportAddress[] = { /* CHOICE */
_NonStandardParameter},
};
-static field_t _AliasAddress[] = { /* CHOICE */
+static const struct field_t _AliasAddress[] = { /* CHOICE */
{FNAME("dialedDigits") NUMDGT, 7, 1, 0, SKIP, 0, NULL},
{FNAME("h323-ID") BMPSTR, BYTE, 1, 0, SKIP, 0, NULL},
{FNAME("url-ID") IA5STR, WORD, 1, 0, SKIP, 0, NULL},
@@ -85,78 +85,78 @@ static field_t _AliasAddress[] = { /* CHOICE */
{FNAME("mobileUIM") CHOICE, 1, 2, 2, SKIP | EXT, 0, NULL},
};
-static field_t _Setup_UUIE_sourceAddress[] = { /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_sourceAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _VendorIdentifier[] = { /* SEQUENCE */
+static const struct field_t _VendorIdentifier[] = { /* SEQUENCE */
{FNAME("vendor") SEQ, 0, 3, 3, SKIP | EXT, 0, _H221NonStandard},
{FNAME("productId") OCTSTR, BYTE, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("versionId") OCTSTR, BYTE, 1, 0, SKIP | OPT, 0, NULL},
};
-static field_t _GatekeeperInfo[] = { /* SEQUENCE */
+static const struct field_t _GatekeeperInfo[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
};
-static field_t _H310Caps[] = { /* SEQUENCE */
+static const struct field_t _H310Caps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H320Caps[] = { /* SEQUENCE */
+static const struct field_t _H320Caps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H321Caps[] = { /* SEQUENCE */
+static const struct field_t _H321Caps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H322Caps[] = { /* SEQUENCE */
+static const struct field_t _H322Caps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H323Caps[] = { /* SEQUENCE */
+static const struct field_t _H323Caps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H324Caps[] = { /* SEQUENCE */
+static const struct field_t _H324Caps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _VoiceCaps[] = { /* SEQUENCE */
+static const struct field_t _VoiceCaps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _T120OnlyCaps[] = { /* SEQUENCE */
+static const struct field_t _T120OnlyCaps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _SupportedProtocols[] = { /* CHOICE */
+static const struct field_t _SupportedProtocols[] = { /* CHOICE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP, 0,
_NonStandardParameter},
{FNAME("h310") SEQ, 1, 1, 3, SKIP | EXT, 0, _H310Caps},
@@ -171,29 +171,29 @@ static field_t _SupportedProtocols[] = { /* CHOICE */
{FNAME("t38FaxAnnexbOnly") SEQ, 2, 5, 5, SKIP | EXT, 0, NULL},
};
-static field_t _GatewayInfo_protocol[] = { /* SEQUENCE OF */
+static const struct field_t _GatewayInfo_protocol[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 4, 9, 11, SKIP | EXT, 0, _SupportedProtocols},
};
-static field_t _GatewayInfo[] = { /* SEQUENCE */
+static const struct field_t _GatewayInfo[] = { /* SEQUENCE */
{FNAME("protocol") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
_GatewayInfo_protocol},
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
};
-static field_t _McuInfo[] = { /* SEQUENCE */
+static const struct field_t _McuInfo[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("protocol") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
};
-static field_t _TerminalInfo[] = { /* SEQUENCE */
+static const struct field_t _TerminalInfo[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
};
-static field_t _EndpointType[] = { /* SEQUENCE */
+static const struct field_t _EndpointType[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("vendor") SEQ, 2, 3, 3, SKIP | EXT | OPT, 0,
@@ -210,19 +210,19 @@ static field_t _EndpointType[] = { /* SEQUENCE */
0, NULL},
};
-static field_t _Setup_UUIE_destinationAddress[] = { /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_destinationAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _Setup_UUIE_destExtraCallInfo[] = { /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_destExtraCallInfo[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _Setup_UUIE_destExtraCRV[] = { /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_destExtraCRV[] = { /* SEQUENCE OF */
{FNAME("item") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _Setup_UUIE_conferenceGoal[] = { /* CHOICE */
+static const struct field_t _Setup_UUIE_conferenceGoal[] = { /* CHOICE */
{FNAME("create") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("join") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("invite") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -231,12 +231,12 @@ static field_t _Setup_UUIE_conferenceGoal[] = { /* CHOICE */
0, NULL},
};
-static field_t _Q954Details[] = { /* SEQUENCE */
+static const struct field_t _Q954Details[] = { /* SEQUENCE */
{FNAME("conferenceCalling") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("threePartyService") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _QseriesOptions[] = { /* SEQUENCE */
+static const struct field_t _QseriesOptions[] = { /* SEQUENCE */
{FNAME("q932Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("q951Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("q952Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -247,32 +247,32 @@ static field_t _QseriesOptions[] = { /* SEQUENCE */
{FNAME("q954Info") SEQ, 0, 2, 2, SKIP | EXT, 0, _Q954Details},
};
-static field_t _CallType[] = { /* CHOICE */
+static const struct field_t _CallType[] = { /* CHOICE */
{FNAME("pointToPoint") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("oneToN") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("nToOne") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("nToN") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _H245_NonStandardIdentifier_h221NonStandard[] = { /* SEQUENCE */
+static const struct field_t _H245_NonStandardIdentifier_h221NonStandard[] = { /* SEQUENCE */
{FNAME("t35CountryCode") INT, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("t35Extension") INT, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("manufacturerCode") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _H245_NonStandardIdentifier[] = { /* CHOICE */
+static const struct field_t _H245_NonStandardIdentifier[] = { /* CHOICE */
{FNAME("object") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("h221NonStandard") SEQ, 0, 3, 3, SKIP, 0,
_H245_NonStandardIdentifier_h221NonStandard},
};
-static field_t _H245_NonStandardParameter[] = { /* SEQUENCE */
+static const struct field_t _H245_NonStandardParameter[] = { /* SEQUENCE */
{FNAME("nonStandardIdentifier") CHOICE, 1, 2, 2, SKIP, 0,
_H245_NonStandardIdentifier},
{FNAME("data") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H261VideoCapability[] = { /* SEQUENCE */
+static const struct field_t _H261VideoCapability[] = { /* SEQUENCE */
{FNAME("qcifMPI") INT, 2, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("cifMPI") INT, 2, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("temporalSpatialTradeOffCapability") BOOL, FIXD, 0, 0, SKIP, 0,
@@ -282,7 +282,7 @@ static field_t _H261VideoCapability[] = { /* SEQUENCE */
{FNAME("videoBadMBsCap") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _H262VideoCapability[] = { /* SEQUENCE */
+static const struct field_t _H262VideoCapability[] = { /* SEQUENCE */
{FNAME("profileAndLevel-SPatML") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("profileAndLevel-MPatLL") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("profileAndLevel-MPatML") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -304,7 +304,7 @@ static field_t _H262VideoCapability[] = { /* SEQUENCE */
{FNAME("videoBadMBsCap") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _H263VideoCapability[] = { /* SEQUENCE */
+static const struct field_t _H263VideoCapability[] = { /* SEQUENCE */
{FNAME("sqcifMPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("qcifMPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("cifMPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
@@ -330,7 +330,7 @@ static field_t _H263VideoCapability[] = { /* SEQUENCE */
{FNAME("h263Options") SEQ, 5, 29, 31, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _IS11172VideoCapability[] = { /* SEQUENCE */
+static const struct field_t _IS11172VideoCapability[] = { /* SEQUENCE */
{FNAME("constrainedBitstream") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("videoBitRate") INT, CONS, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("vbvBufferSize") INT, CONS, 0, 0, SKIP | OPT, 0, NULL},
@@ -341,7 +341,7 @@ static field_t _IS11172VideoCapability[] = { /* SEQUENCE */
{FNAME("videoBadMBsCap") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _VideoCapability[] = { /* CHOICE */
+static const struct field_t _VideoCapability[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("h261VideoCapability") SEQ, 2, 5, 6, SKIP | EXT, 0,
@@ -355,12 +355,12 @@ static field_t _VideoCapability[] = { /* CHOICE */
{FNAME("genericVideoCapability") SEQ, 5, 6, 6, SKIP | EXT, 0, NULL},
};
-static field_t _AudioCapability_g7231[] = { /* SEQUENCE */
+static const struct field_t _AudioCapability_g7231[] = { /* SEQUENCE */
{FNAME("maxAl-sduAudioFrames") INT, BYTE, 1, 0, SKIP, 0, NULL},
{FNAME("silenceSuppression") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _IS11172AudioCapability[] = { /* SEQUENCE */
+static const struct field_t _IS11172AudioCapability[] = { /* SEQUENCE */
{FNAME("audioLayer1") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("audioLayer2") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("audioLayer3") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -372,7 +372,7 @@ static field_t _IS11172AudioCapability[] = { /* SEQUENCE */
{FNAME("bitRate") INT, WORD, 1, 0, SKIP, 0, NULL},
};
-static field_t _IS13818AudioCapability[] = { /* SEQUENCE */
+static const struct field_t _IS13818AudioCapability[] = { /* SEQUENCE */
{FNAME("audioLayer1") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("audioLayer2") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("audioLayer3") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -396,7 +396,7 @@ static field_t _IS13818AudioCapability[] = { /* SEQUENCE */
{FNAME("bitRate") INT, WORD, 1, 0, SKIP, 0, NULL},
};
-static field_t _AudioCapability[] = { /* CHOICE */
+static const struct field_t _AudioCapability[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("g711Alaw64k") INT, BYTE, 1, 0, SKIP, 0, NULL},
@@ -424,7 +424,7 @@ static field_t _AudioCapability[] = { /* CHOICE */
{FNAME("g729Extensions") SEQ, 1, 8, 8, SKIP | EXT, 0, NULL},
};
-static field_t _DataProtocolCapability[] = { /* CHOICE */
+static const struct field_t _DataProtocolCapability[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("v14buffered") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -442,7 +442,7 @@ static field_t _DataProtocolCapability[] = { /* CHOICE */
{FNAME("udp") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _T84Profile_t84Restricted[] = { /* SEQUENCE */
+static const struct field_t _T84Profile_t84Restricted[] = { /* SEQUENCE */
{FNAME("qcif") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("cif") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("ccir601Seq") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -464,25 +464,25 @@ static field_t _T84Profile_t84Restricted[] = { /* SEQUENCE */
{FNAME("digPhotoHighProg") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _T84Profile[] = { /* CHOICE */
+static const struct field_t _T84Profile[] = { /* CHOICE */
{FNAME("t84Unrestricted") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("t84Restricted") SEQ, 0, 19, 19, SKIP | EXT, 0,
_T84Profile_t84Restricted},
};
-static field_t _DataApplicationCapability_application_t84[] = { /* SEQUENCE */
+static const struct field_t _DataApplicationCapability_application_t84[] = { /* SEQUENCE */
{FNAME("t84Protocol") CHOICE, 3, 7, 14, SKIP | EXT, 0,
_DataProtocolCapability},
{FNAME("t84Profile") CHOICE, 1, 2, 2, SKIP, 0, _T84Profile},
};
-static field_t _DataApplicationCapability_application_nlpid[] = { /* SEQUENCE */
+static const struct field_t _DataApplicationCapability_application_nlpid[] = { /* SEQUENCE */
{FNAME("nlpidProtocol") CHOICE, 3, 7, 14, SKIP | EXT, 0,
_DataProtocolCapability},
{FNAME("nlpidData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _DataApplicationCapability_application[] = { /* CHOICE */
+static const struct field_t _DataApplicationCapability_application[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("t120") CHOICE, 3, 7, 14, DECODE | EXT,
@@ -509,20 +509,20 @@ static field_t _DataApplicationCapability_application[] = { /* CHOICE */
{FNAME("genericDataCapability") SEQ, 5, 6, 6, SKIP | EXT, 0, NULL},
};
-static field_t _DataApplicationCapability[] = { /* SEQUENCE */
+static const struct field_t _DataApplicationCapability[] = { /* SEQUENCE */
{FNAME("application") CHOICE, 4, 10, 14, DECODE | EXT,
offsetof(DataApplicationCapability, application),
_DataApplicationCapability_application},
{FNAME("maxBitRate") INT, CONS, 0, 0, SKIP, 0, NULL},
};
-static field_t _EncryptionMode[] = { /* CHOICE */
+static const struct field_t _EncryptionMode[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("h233Encryption") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _DataType[] = { /* CHOICE */
+static const struct field_t _DataType[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("nullData") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -538,7 +538,7 @@ static field_t _DataType[] = { /* CHOICE */
{FNAME("multiplexedStream") SEQ, 0, 2, 2, SKIP | EXT, 0, NULL},
};
-static field_t _H222LogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _H222LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("resourceID") INT, WORD, 0, 0, SKIP, 0, NULL},
{FNAME("subChannelID") INT, WORD, 0, 0, SKIP, 0, NULL},
{FNAME("pcr-pid") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
@@ -546,12 +546,12 @@ static field_t _H222LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("streamDescriptors") OCTSTR, SEMI, 0, 0, SKIP | OPT, 0, NULL},
};
-static field_t _H223LogicalChannelParameters_adaptationLayerType_al3[] = { /* SEQUENCE */
+static const struct field_t _H223LogicalChannelParameters_adaptationLayerType_al3[] = { /* SEQUENCE */
{FNAME("controlFieldOctets") INT, 2, 0, 0, SKIP, 0, NULL},
{FNAME("sendBufferSize") INT, CONS, 0, 0, SKIP, 0, NULL},
};
-static field_t _H223LogicalChannelParameters_adaptationLayerType[] = { /* CHOICE */
+static const struct field_t _H223LogicalChannelParameters_adaptationLayerType[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("al1Framed") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -565,53 +565,53 @@ static field_t _H223LogicalChannelParameters_adaptationLayerType[] = { /* CHOICE
{FNAME("al3M") SEQ, 0, 5, 6, SKIP | EXT, 0, NULL},
};
-static field_t _H223LogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _H223LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("adaptationLayerType") CHOICE, 3, 6, 9, SKIP | EXT, 0,
_H223LogicalChannelParameters_adaptationLayerType},
{FNAME("segmentableFlag") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _CRCLength[] = { /* CHOICE */
+static const struct field_t _CRCLength[] = { /* CHOICE */
{FNAME("crc8bit") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("crc16bit") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("crc32bit") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _V76HDLCParameters[] = { /* SEQUENCE */
+static const struct field_t _V76HDLCParameters[] = { /* SEQUENCE */
{FNAME("crcLength") CHOICE, 2, 3, 3, SKIP | EXT, 0, _CRCLength},
{FNAME("n401") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("loopbackTestProcedure") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _V76LogicalChannelParameters_suspendResume[] = { /* CHOICE */
+static const struct field_t _V76LogicalChannelParameters_suspendResume[] = { /* CHOICE */
{FNAME("noSuspendResume") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("suspendResumewAddress") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("suspendResumewoAddress") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _V76LogicalChannelParameters_mode_eRM_recovery[] = { /* CHOICE */
+static const struct field_t _V76LogicalChannelParameters_mode_eRM_recovery[] = { /* CHOICE */
{FNAME("rej") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("sREJ") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("mSREJ") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _V76LogicalChannelParameters_mode_eRM[] = { /* SEQUENCE */
+static const struct field_t _V76LogicalChannelParameters_mode_eRM[] = { /* SEQUENCE */
{FNAME("windowSize") INT, 7, 1, 0, SKIP, 0, NULL},
{FNAME("recovery") CHOICE, 2, 3, 3, SKIP | EXT, 0,
_V76LogicalChannelParameters_mode_eRM_recovery},
};
-static field_t _V76LogicalChannelParameters_mode[] = { /* CHOICE */
+static const struct field_t _V76LogicalChannelParameters_mode[] = { /* CHOICE */
{FNAME("eRM") SEQ, 0, 2, 2, SKIP | EXT, 0,
_V76LogicalChannelParameters_mode_eRM},
{FNAME("uNERM") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _V75Parameters[] = { /* SEQUENCE */
+static const struct field_t _V75Parameters[] = { /* SEQUENCE */
{FNAME("audioHeaderPresent") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _V76LogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _V76LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("hdlcParameters") SEQ, 0, 3, 3, SKIP | EXT, 0,
_V76HDLCParameters},
{FNAME("suspendResume") CHOICE, 2, 3, 3, SKIP | EXT, 0,
@@ -622,38 +622,38 @@ static field_t _V76LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("v75Parameters") SEQ, 0, 1, 1, SKIP | EXT, 0, _V75Parameters},
};
-static field_t _H2250LogicalChannelParameters_nonStandard[] = { /* SEQUENCE OF */
+static const struct field_t _H2250LogicalChannelParameters_nonStandard[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 0, 2, 2, SKIP, 0, _H245_NonStandardParameter},
};
-static field_t _UnicastAddress_iPAddress[] = { /* SEQUENCE */
+static const struct field_t _UnicastAddress_iPAddress[] = { /* SEQUENCE */
{FNAME("network") OCTSTR, FIXD, 4, 0, DECODE,
offsetof(UnicastAddress_iPAddress, network), NULL},
{FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _UnicastAddress_iPXAddress[] = { /* SEQUENCE */
+static const struct field_t _UnicastAddress_iPXAddress[] = { /* SEQUENCE */
{FNAME("node") OCTSTR, FIXD, 6, 0, SKIP, 0, NULL},
{FNAME("netnum") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
{FNAME("tsapIdentifier") OCTSTR, FIXD, 2, 0, SKIP, 0, NULL},
};
-static field_t _UnicastAddress_iP6Address[] = { /* SEQUENCE */
+static const struct field_t _UnicastAddress_iP6Address[] = { /* SEQUENCE */
{FNAME("network") OCTSTR, FIXD, 16, 0, DECODE,
offsetof(UnicastAddress_iP6Address, network), NULL},
{FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _UnicastAddress_iPSourceRouteAddress_routing[] = { /* CHOICE */
+static const struct field_t _UnicastAddress_iPSourceRouteAddress_routing[] = { /* CHOICE */
{FNAME("strict") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("loose") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _UnicastAddress_iPSourceRouteAddress_route[] = { /* SEQUENCE OF */
+static const struct field_t _UnicastAddress_iPSourceRouteAddress_route[] = { /* SEQUENCE OF */
{FNAME("item") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
};
-static field_t _UnicastAddress_iPSourceRouteAddress[] = { /* SEQUENCE */
+static const struct field_t _UnicastAddress_iPSourceRouteAddress[] = { /* SEQUENCE */
{FNAME("routing") CHOICE, 1, 2, 2, SKIP, 0,
_UnicastAddress_iPSourceRouteAddress_routing},
{FNAME("network") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
@@ -662,7 +662,7 @@ static field_t _UnicastAddress_iPSourceRouteAddress[] = { /* SEQUENCE */
_UnicastAddress_iPSourceRouteAddress_route},
};
-static field_t _UnicastAddress[] = { /* CHOICE */
+static const struct field_t _UnicastAddress[] = { /* CHOICE */
{FNAME("iPAddress") SEQ, 0, 2, 2, DECODE | EXT,
offsetof(UnicastAddress, iPAddress), _UnicastAddress_iPAddress},
{FNAME("iPXAddress") SEQ, 0, 3, 3, SKIP | EXT, 0,
@@ -676,17 +676,17 @@ static field_t _UnicastAddress[] = { /* CHOICE */
{FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0, NULL},
};
-static field_t _MulticastAddress_iPAddress[] = { /* SEQUENCE */
+static const struct field_t _MulticastAddress_iPAddress[] = { /* SEQUENCE */
{FNAME("network") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
{FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _MulticastAddress_iP6Address[] = { /* SEQUENCE */
+static const struct field_t _MulticastAddress_iP6Address[] = { /* SEQUENCE */
{FNAME("network") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
{FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _MulticastAddress[] = { /* CHOICE */
+static const struct field_t _MulticastAddress[] = { /* CHOICE */
{FNAME("iPAddress") SEQ, 0, 2, 2, SKIP | EXT, 0,
_MulticastAddress_iPAddress},
{FNAME("iP6Address") SEQ, 0, 2, 2, SKIP | EXT, 0,
@@ -695,14 +695,14 @@ static field_t _MulticastAddress[] = { /* CHOICE */
{FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0, NULL},
};
-static field_t _H245_TransportAddress[] = { /* CHOICE */
+static const struct field_t _H245_TransportAddress[] = { /* CHOICE */
{FNAME("unicastAddress") CHOICE, 3, 5, 7, DECODE | EXT,
offsetof(H245_TransportAddress, unicastAddress), _UnicastAddress},
{FNAME("multicastAddress") CHOICE, 1, 2, 4, SKIP | EXT, 0,
_MulticastAddress},
};
-static field_t _H2250LogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _H2250LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("nonStandard") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
_H2250LogicalChannelParameters_nonStandard},
{FNAME("sessionID") INT, BYTE, 0, 0, SKIP, 0, NULL},
@@ -728,7 +728,7 @@ static field_t _H2250LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("source") SEQ, 0, 2, 2, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
+static const struct field_t _OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
{FNAME("h222LogicalChannelParameters") SEQ, 3, 5, 5, SKIP | EXT, 0,
_H222LogicalChannelParameters},
{FNAME("h223LogicalChannelParameters") SEQ, 0, 2, 2, SKIP | EXT, 0,
@@ -742,7 +742,7 @@ static field_t _OpenLogicalChannel_forwardLogicalChannelParameters_multiplexPara
{FNAME("none") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _OpenLogicalChannel_forwardLogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _OpenLogicalChannel_forwardLogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("portNumber") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("dataType") CHOICE, 3, 6, 9, DECODE | EXT,
offsetof(OpenLogicalChannel_forwardLogicalChannelParameters,
@@ -756,7 +756,7 @@ static field_t _OpenLogicalChannel_forwardLogicalChannelParameters[] = { /* SEQU
{FNAME("replacementFor") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
};
-static field_t _OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
+static const struct field_t _OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
{FNAME("h223LogicalChannelParameters") SEQ, 0, 2, 2, SKIP | EXT, 0,
_H223LogicalChannelParameters},
{FNAME("v76LogicalChannelParameters") SEQ, 0, 5, 5, SKIP | EXT, 0,
@@ -767,7 +767,7 @@ static field_t _OpenLogicalChannel_reverseLogicalChannelParameters_multiplexPara
h2250LogicalChannelParameters), _H2250LogicalChannelParameters},
};
-static field_t _OpenLogicalChannel_reverseLogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _OpenLogicalChannel_reverseLogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("dataType") CHOICE, 3, 6, 9, SKIP | EXT, 0, _DataType},
{FNAME("multiplexParameters") CHOICE, 1, 2, 3, DECODE | EXT | OPT,
offsetof(OpenLogicalChannel_reverseLogicalChannelParameters,
@@ -778,23 +778,23 @@ static field_t _OpenLogicalChannel_reverseLogicalChannelParameters[] = { /* SEQU
{FNAME("replacementFor") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
};
-static field_t _NetworkAccessParameters_distribution[] = { /* CHOICE */
+static const struct field_t _NetworkAccessParameters_distribution[] = { /* CHOICE */
{FNAME("unicast") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("multicast") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _Q2931Address_address[] = { /* CHOICE */
+static const struct field_t _Q2931Address_address[] = { /* CHOICE */
{FNAME("internationalNumber") NUMSTR, 4, 1, 0, SKIP, 0, NULL},
{FNAME("nsapAddress") OCTSTR, 5, 1, 0, SKIP, 0, NULL},
};
-static field_t _Q2931Address[] = { /* SEQUENCE */
+static const struct field_t _Q2931Address[] = { /* SEQUENCE */
{FNAME("address") CHOICE, 1, 2, 2, SKIP | EXT, 0,
_Q2931Address_address},
{FNAME("subaddress") OCTSTR, 5, 1, 0, SKIP | OPT, 0, NULL},
};
-static field_t _NetworkAccessParameters_networkAddress[] = { /* CHOICE */
+static const struct field_t _NetworkAccessParameters_networkAddress[] = { /* CHOICE */
{FNAME("q2931Address") SEQ, 1, 2, 2, SKIP | EXT, 0, _Q2931Address},
{FNAME("e164Address") NUMDGT, 7, 1, 0, SKIP, 0, NULL},
{FNAME("localAreaAddress") CHOICE, 1, 2, 2, DECODE | EXT,
@@ -802,7 +802,7 @@ static field_t _NetworkAccessParameters_networkAddress[] = { /* CHOICE */
_H245_TransportAddress},
};
-static field_t _NetworkAccessParameters[] = { /* SEQUENCE */
+static const struct field_t _NetworkAccessParameters[] = { /* SEQUENCE */
{FNAME("distribution") CHOICE, 1, 2, 2, SKIP | EXT | OPT, 0,
_NetworkAccessParameters_distribution},
{FNAME("networkAddress") CHOICE, 2, 3, 3, DECODE | EXT,
@@ -814,7 +814,7 @@ static field_t _NetworkAccessParameters[] = { /* SEQUENCE */
NULL},
};
-static field_t _OpenLogicalChannel[] = { /* SEQUENCE */
+static const struct field_t _OpenLogicalChannel[] = { /* SEQUENCE */
{FNAME("forwardLogicalChannelNumber") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("forwardLogicalChannelParameters") SEQ, 1, 3, 5, DECODE | EXT,
offsetof(OpenLogicalChannel, forwardLogicalChannelParameters),
@@ -829,13 +829,13 @@ static field_t _OpenLogicalChannel[] = { /* SEQUENCE */
{FNAME("encryptionSync") SEQ, 2, 4, 4, STOP | EXT | OPT, 0, NULL},
};
-static field_t _Setup_UUIE_fastStart[] = { /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_fastStart[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
sizeof(OpenLogicalChannel), _OpenLogicalChannel}
,
};
-static field_t _Setup_UUIE[] = { /* SEQUENCE */
+static const struct field_t _Setup_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("h245Address") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
offsetof(Setup_UUIE, h245Address), _TransportAddress},
@@ -894,13 +894,13 @@ static field_t _Setup_UUIE[] = { /* SEQUENCE */
NULL},
};
-static field_t _CallProceeding_UUIE_fastStart[] = { /* SEQUENCE OF */
+static const struct field_t _CallProceeding_UUIE_fastStart[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
sizeof(OpenLogicalChannel), _OpenLogicalChannel}
,
};
-static field_t _CallProceeding_UUIE[] = { /* SEQUENCE */
+static const struct field_t _CallProceeding_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT, 0,
_EndpointType},
@@ -920,13 +920,13 @@ static field_t _CallProceeding_UUIE[] = { /* SEQUENCE */
{FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _Connect_UUIE_fastStart[] = { /* SEQUENCE OF */
+static const struct field_t _Connect_UUIE_fastStart[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
sizeof(OpenLogicalChannel), _OpenLogicalChannel}
,
};
-static field_t _Connect_UUIE[] = { /* SEQUENCE */
+static const struct field_t _Connect_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("h245Address") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
offsetof(Connect_UUIE, h245Address), _TransportAddress},
@@ -954,13 +954,13 @@ static field_t _Connect_UUIE[] = { /* SEQUENCE */
{FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _Alerting_UUIE_fastStart[] = { /* SEQUENCE OF */
+static const struct field_t _Alerting_UUIE_fastStart[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
sizeof(OpenLogicalChannel), _OpenLogicalChannel}
,
};
-static field_t _Alerting_UUIE[] = { /* SEQUENCE */
+static const struct field_t _Alerting_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT, 0,
_EndpointType},
@@ -986,7 +986,7 @@ static field_t _Alerting_UUIE[] = { /* SEQUENCE */
{FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _Information_UUIE[] = { /* SEQUENCE */
+static const struct field_t _Information_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL},
{FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
@@ -996,7 +996,7 @@ static field_t _Information_UUIE[] = { /* SEQUENCE */
{FNAME("circuitInfo") SEQ, 3, 3, 3, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _ReleaseCompleteReason[] = { /* CHOICE */
+static const struct field_t _ReleaseCompleteReason[] = { /* CHOICE */
{FNAME("noBandwidth") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("gatekeeperResources") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("unreachableDestination") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -1022,7 +1022,7 @@ static field_t _ReleaseCompleteReason[] = { /* CHOICE */
{FNAME("tunnelledSignallingRejected") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _ReleaseComplete_UUIE[] = { /* SEQUENCE */
+static const struct field_t _ReleaseComplete_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("reason") CHOICE, 4, 12, 22, SKIP | EXT | OPT, 0,
_ReleaseCompleteReason},
@@ -1039,11 +1039,11 @@ static field_t _ReleaseComplete_UUIE[] = { /* SEQUENCE */
{FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _Facility_UUIE_alternativeAliasAddress[] = { /* SEQUENCE OF */
+static const struct field_t _Facility_UUIE_alternativeAliasAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _FacilityReason[] = { /* CHOICE */
+static const struct field_t _FacilityReason[] = { /* CHOICE */
{FNAME("routeCallToGatekeeper") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("callForwarded") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("routeCallToMC") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -1057,13 +1057,13 @@ static field_t _FacilityReason[] = { /* CHOICE */
{FNAME("transportedInformation") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _Facility_UUIE_fastStart[] = { /* SEQUENCE OF */
+static const struct field_t _Facility_UUIE_fastStart[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
sizeof(OpenLogicalChannel), _OpenLogicalChannel}
,
};
-static field_t _Facility_UUIE[] = { /* SEQUENCE */
+static const struct field_t _Facility_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("alternativeAddress") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
offsetof(Facility_UUIE, alternativeAddress), _TransportAddress},
@@ -1094,17 +1094,17 @@ static field_t _Facility_UUIE[] = { /* SEQUENCE */
NULL},
};
-static field_t _CallIdentifier[] = { /* SEQUENCE */
+static const struct field_t _CallIdentifier[] = { /* SEQUENCE */
{FNAME("guid") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
};
-static field_t _SecurityServiceMode[] = { /* CHOICE */
+static const struct field_t _SecurityServiceMode[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0, _NonStandardParameter},
{FNAME("none") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("default") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _SecurityCapabilities[] = { /* SEQUENCE */
+static const struct field_t _SecurityCapabilities[] = { /* SEQUENCE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("encryption") CHOICE, 2, 3, 3, SKIP | EXT, 0,
@@ -1115,30 +1115,30 @@ static field_t _SecurityCapabilities[] = { /* SEQUENCE */
_SecurityServiceMode},
};
-static field_t _H245Security[] = { /* CHOICE */
+static const struct field_t _H245Security[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0, _NonStandardParameter},
{FNAME("noSecurity") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("tls") SEQ, 1, 4, 4, SKIP | EXT, 0, _SecurityCapabilities},
{FNAME("ipsec") SEQ, 1, 4, 4, SKIP | EXT, 0, _SecurityCapabilities},
};
-static field_t _DHset[] = { /* SEQUENCE */
+static const struct field_t _DHset[] = { /* SEQUENCE */
{FNAME("halfkey") BITSTR, WORD, 0, 0, SKIP, 0, NULL},
{FNAME("modSize") BITSTR, WORD, 0, 0, SKIP, 0, NULL},
{FNAME("generator") BITSTR, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _TypedCertificate[] = { /* SEQUENCE */
+static const struct field_t _TypedCertificate[] = { /* SEQUENCE */
{FNAME("type") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("certificate") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H235_NonStandardParameter[] = { /* SEQUENCE */
+static const struct field_t _H235_NonStandardParameter[] = { /* SEQUENCE */
{FNAME("nonStandardIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("data") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _ClearToken[] = { /* SEQUENCE */
+static const struct field_t _ClearToken[] = { /* SEQUENCE */
{FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("timeStamp") INT, CONS, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("password") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
@@ -1154,120 +1154,120 @@ static field_t _ClearToken[] = { /* SEQUENCE */
{FNAME("sendersID") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
};
-static field_t _Progress_UUIE_tokens[] = { /* SEQUENCE OF */
+static const struct field_t _Progress_UUIE_tokens[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 8, 9, 11, SKIP | EXT, 0, _ClearToken},
};
-static field_t _Params[] = { /* SEQUENCE */
+static const struct field_t _Params[] = { /* SEQUENCE */
{FNAME("ranInt") INT, UNCO, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("iv8") OCTSTR, FIXD, 8, 0, SKIP | OPT, 0, NULL},
{FNAME("iv16") OCTSTR, FIXD, 16, 0, SKIP | OPT, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoEPPwdHash_token[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoEPPwdHash_token[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("hash") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoEPPwdHash[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoEPPwdHash[] = { /* SEQUENCE */
{FNAME("alias") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
{FNAME("timeStamp") INT, CONS, 1, 0, SKIP, 0, NULL},
{FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
_CryptoH323Token_cryptoEPPwdHash_token},
};
-static field_t _CryptoH323Token_cryptoGKPwdHash_token[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoGKPwdHash_token[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("hash") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoGKPwdHash[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoGKPwdHash[] = { /* SEQUENCE */
{FNAME("gatekeeperId") BMPSTR, 7, 1, 0, SKIP, 0, NULL},
{FNAME("timeStamp") INT, CONS, 1, 0, SKIP, 0, NULL},
{FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
_CryptoH323Token_cryptoGKPwdHash_token},
};
-static field_t _CryptoH323Token_cryptoEPPwdEncr[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoEPPwdEncr[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoGKPwdEncr[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoGKPwdEncr[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoEPCert[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoEPCert[] = { /* SEQUENCE */
{FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoGKCert[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoGKCert[] = { /* SEQUENCE */
{FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoFastStart[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoFastStart[] = { /* SEQUENCE */
{FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoToken_cryptoEncryptedToken_token[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoEncryptedToken_token[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoToken_cryptoEncryptedToken[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoEncryptedToken[] = { /* SEQUENCE */
{FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
_CryptoToken_cryptoEncryptedToken_token},
};
-static field_t _CryptoToken_cryptoSignedToken_token[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoSignedToken_token[] = { /* SEQUENCE */
{FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoToken_cryptoSignedToken[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoSignedToken[] = { /* SEQUENCE */
{FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("token") SEQ, 0, 4, 4, SKIP, 0,
_CryptoToken_cryptoSignedToken_token},
};
-static field_t _CryptoToken_cryptoHashedToken_token[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoHashedToken_token[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("hash") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoToken_cryptoHashedToken[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoHashedToken[] = { /* SEQUENCE */
{FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("hashedVals") SEQ, 8, 9, 11, SKIP | EXT, 0, _ClearToken},
{FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
_CryptoToken_cryptoHashedToken_token},
};
-static field_t _CryptoToken_cryptoPwdEncr[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoPwdEncr[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoToken[] = { /* CHOICE */
+static const struct field_t _CryptoToken[] = { /* CHOICE */
{FNAME("cryptoEncryptedToken") SEQ, 0, 2, 2, SKIP, 0,
_CryptoToken_cryptoEncryptedToken},
{FNAME("cryptoSignedToken") SEQ, 0, 2, 2, SKIP, 0,
@@ -1278,7 +1278,7 @@ static field_t _CryptoToken[] = { /* CHOICE */
_CryptoToken_cryptoPwdEncr},
};
-static field_t _CryptoH323Token[] = { /* CHOICE */
+static const struct field_t _CryptoH323Token[] = { /* CHOICE */
{FNAME("cryptoEPPwdHash") SEQ, 0, 3, 3, SKIP, 0,
_CryptoH323Token_cryptoEPPwdHash},
{FNAME("cryptoGKPwdHash") SEQ, 0, 3, 3, SKIP, 0,
@@ -1297,17 +1297,17 @@ static field_t _CryptoH323Token[] = { /* CHOICE */
_CryptoToken},
};
-static field_t _Progress_UUIE_cryptoTokens[] = { /* SEQUENCE OF */
+static const struct field_t _Progress_UUIE_cryptoTokens[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 3, 8, 8, SKIP | EXT, 0, _CryptoH323Token},
};
-static field_t _Progress_UUIE_fastStart[] = { /* SEQUENCE OF */
+static const struct field_t _Progress_UUIE_fastStart[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
sizeof(OpenLogicalChannel), _OpenLogicalChannel}
,
};
-static field_t _Progress_UUIE[] = { /* SEQUENCE */
+static const struct field_t _Progress_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT, 0,
_EndpointType},
@@ -1328,7 +1328,7 @@ static field_t _Progress_UUIE[] = { /* SEQUENCE */
{FNAME("fastConnectRefused") NUL, FIXD, 0, 0, SKIP | OPT, 0, NULL},
};
-static field_t _H323_UU_PDU_h323_message_body[] = { /* CHOICE */
+static const struct field_t _H323_UU_PDU_h323_message_body[] = { /* CHOICE */
{FNAME("setup") SEQ, 7, 13, 39, DECODE | EXT,
offsetof(H323_UU_PDU_h323_message_body, setup), _Setup_UUIE},
{FNAME("callProceeding") SEQ, 1, 3, 12, DECODE | EXT,
@@ -1352,7 +1352,7 @@ static field_t _H323_UU_PDU_h323_message_body[] = { /* CHOICE */
{FNAME("notify") SEQ, 2, 4, 4, SKIP | EXT, 0, NULL},
};
-static field_t _RequestMessage[] = { /* CHOICE */
+static const struct field_t _RequestMessage[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
{FNAME("masterSlaveDetermination") SEQ, 0, 2, 2, STOP | EXT, 0, NULL},
{FNAME("terminalCapabilitySet") SEQ, 3, 5, 5, STOP | EXT, 0, NULL},
@@ -1372,7 +1372,7 @@ static field_t _RequestMessage[] = { /* CHOICE */
NULL},
};
-static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
+static const struct field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
{FNAME("h222LogicalChannelParameters") SEQ, 3, 5, 5, SKIP | EXT, 0,
_H222LogicalChannelParameters},
{FNAME("h2250LogicalChannelParameters") SEQ, 10, 11, 14, DECODE | EXT,
@@ -1381,7 +1381,7 @@ static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexP
h2250LogicalChannelParameters), _H2250LogicalChannelParameters},
};
-static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("reverseLogicalChannelNumber") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("portNumber") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("multiplexParameters") CHOICE, 0, 1, 2, DECODE | EXT | OPT,
@@ -1391,11 +1391,11 @@ static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters[] = { /* S
{FNAME("replacementFor") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
};
-static field_t _H2250LogicalChannelAckParameters_nonStandard[] = { /* SEQUENCE OF */
+static const struct field_t _H2250LogicalChannelAckParameters_nonStandard[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 0, 2, 2, SKIP, 0, _H245_NonStandardParameter},
};
-static field_t _H2250LogicalChannelAckParameters[] = { /* SEQUENCE */
+static const struct field_t _H2250LogicalChannelAckParameters[] = { /* SEQUENCE */
{FNAME("nonStandard") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
_H2250LogicalChannelAckParameters_nonStandard},
{FNAME("sessionID") INT, 8, 1, 0, SKIP | OPT, 0, NULL},
@@ -1410,14 +1410,14 @@ static field_t _H2250LogicalChannelAckParameters[] = { /* SEQUENCE */
{FNAME("portNumber") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
};
-static field_t _OpenLogicalChannelAck_forwardMultiplexAckParameters[] = { /* CHOICE */
+static const struct field_t _OpenLogicalChannelAck_forwardMultiplexAckParameters[] = { /* CHOICE */
{FNAME("h2250LogicalChannelAckParameters") SEQ, 5, 5, 7, DECODE | EXT,
offsetof(OpenLogicalChannelAck_forwardMultiplexAckParameters,
h2250LogicalChannelAckParameters),
_H2250LogicalChannelAckParameters},
};
-static field_t _OpenLogicalChannelAck[] = { /* SEQUENCE */
+static const struct field_t _OpenLogicalChannelAck[] = { /* SEQUENCE */
{FNAME("forwardLogicalChannelNumber") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("reverseLogicalChannelParameters") SEQ, 2, 3, 4,
DECODE | EXT | OPT, offsetof(OpenLogicalChannelAck,
@@ -1433,7 +1433,7 @@ static field_t _OpenLogicalChannelAck[] = { /* SEQUENCE */
{FNAME("encryptionSync") SEQ, 2, 4, 4, STOP | EXT | OPT, 0, NULL},
};
-static field_t _ResponseMessage[] = { /* CHOICE */
+static const struct field_t _ResponseMessage[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
{FNAME("masterSlaveDeterminationAck") SEQ, 0, 1, 1, STOP | EXT, 0,
NULL},
@@ -1469,7 +1469,7 @@ static field_t _ResponseMessage[] = { /* CHOICE */
{FNAME("logicalChannelRateReject") SEQ, 1, 4, 4, STOP | EXT, 0, NULL},
};
-static field_t _MultimediaSystemControlMessage[] = { /* CHOICE */
+static const struct field_t _MultimediaSystemControlMessage[] = { /* CHOICE */
{FNAME("request") CHOICE, 4, 11, 15, DECODE | EXT,
offsetof(MultimediaSystemControlMessage, request), _RequestMessage},
{FNAME("response") CHOICE, 5, 19, 24, DECODE | EXT,
@@ -1479,14 +1479,14 @@ static field_t _MultimediaSystemControlMessage[] = { /* CHOICE */
{FNAME("indication") CHOICE, 4, 14, 23, STOP | EXT, 0, NULL},
};
-static field_t _H323_UU_PDU_h245Control[] = { /* SEQUENCE OF */
+static const struct field_t _H323_UU_PDU_h245Control[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 2, 4, 4, DECODE | OPEN | EXT,
sizeof(MultimediaSystemControlMessage),
_MultimediaSystemControlMessage}
,
};
-static field_t _H323_UU_PDU[] = { /* SEQUENCE */
+static const struct field_t _H323_UU_PDU[] = { /* SEQUENCE */
{FNAME("h323-message-body") CHOICE, 3, 7, 13, DECODE | EXT,
offsetof(H323_UU_PDU, h323_message_body),
_H323_UU_PDU_h323_message_body},
@@ -1507,13 +1507,13 @@ static field_t _H323_UU_PDU[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _H323_UserInformation[] = { /* SEQUENCE */
+static const struct field_t _H323_UserInformation[] = { /* SEQUENCE */
{FNAME("h323-uu-pdu") SEQ, 1, 2, 11, DECODE | EXT,
offsetof(H323_UserInformation, h323_uu_pdu), _H323_UU_PDU},
{FNAME("user-data") SEQ, 0, 2, 2, STOP | EXT | OPT, 0, NULL},
};
-static field_t _GatekeeperRequest[] = { /* SEQUENCE */
+static const struct field_t _GatekeeperRequest[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
@@ -1537,7 +1537,7 @@ static field_t _GatekeeperRequest[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _GatekeeperConfirm[] = { /* SEQUENCE */
+static const struct field_t _GatekeeperConfirm[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
@@ -1557,23 +1557,23 @@ static field_t _GatekeeperConfirm[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _RegistrationRequest_callSignalAddress[] = { /* SEQUENCE OF */
+static const struct field_t _RegistrationRequest_callSignalAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
sizeof(TransportAddress), _TransportAddress}
,
};
-static field_t _RegistrationRequest_rasAddress[] = { /* SEQUENCE OF */
+static const struct field_t _RegistrationRequest_rasAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
sizeof(TransportAddress), _TransportAddress}
,
};
-static field_t _RegistrationRequest_terminalAlias[] = { /* SEQUENCE OF */
+static const struct field_t _RegistrationRequest_terminalAlias[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _RegistrationRequest[] = { /* SEQUENCE */
+static const struct field_t _RegistrationRequest[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
@@ -1621,17 +1621,17 @@ static field_t _RegistrationRequest[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _RegistrationConfirm_callSignalAddress[] = { /* SEQUENCE OF */
+static const struct field_t _RegistrationConfirm_callSignalAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
sizeof(TransportAddress), _TransportAddress}
,
};
-static field_t _RegistrationConfirm_terminalAlias[] = { /* SEQUENCE OF */
+static const struct field_t _RegistrationConfirm_terminalAlias[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _RegistrationConfirm[] = { /* SEQUENCE */
+static const struct field_t _RegistrationConfirm[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
@@ -1667,13 +1667,13 @@ static field_t _RegistrationConfirm[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _UnregistrationRequest_callSignalAddress[] = { /* SEQUENCE OF */
+static const struct field_t _UnregistrationRequest_callSignalAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
sizeof(TransportAddress), _TransportAddress}
,
};
-static field_t _UnregistrationRequest[] = { /* SEQUENCE */
+static const struct field_t _UnregistrationRequest[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("callSignalAddress") SEQOF, SEMI, 0, 10, DECODE,
offsetof(UnregistrationRequest, callSignalAddress),
@@ -1694,24 +1694,24 @@ static field_t _UnregistrationRequest[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _CallModel[] = { /* CHOICE */
+static const struct field_t _CallModel[] = { /* CHOICE */
{FNAME("direct") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("gatekeeperRouted") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _AdmissionRequest_destinationInfo[] = { /* SEQUENCE OF */
+static const struct field_t _AdmissionRequest_destinationInfo[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _AdmissionRequest_destExtraCallInfo[] = { /* SEQUENCE OF */
+static const struct field_t _AdmissionRequest_destExtraCallInfo[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _AdmissionRequest_srcInfo[] = { /* SEQUENCE OF */
+static const struct field_t _AdmissionRequest_srcInfo[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _AdmissionRequest[] = { /* SEQUENCE */
+static const struct field_t _AdmissionRequest[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("callType") CHOICE, 2, 4, 4, SKIP | EXT, 0, _CallType},
{FNAME("callModel") CHOICE, 1, 2, 2, SKIP | EXT | OPT, 0, _CallModel},
@@ -1755,7 +1755,7 @@ static field_t _AdmissionRequest[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _AdmissionConfirm[] = { /* SEQUENCE */
+static const struct field_t _AdmissionConfirm[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("bandWidth") INT, CONS, 0, 0, SKIP, 0, NULL},
{FNAME("callModel") CHOICE, 1, 2, 2, SKIP | EXT, 0, _CallModel},
@@ -1790,11 +1790,11 @@ static field_t _AdmissionConfirm[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _LocationRequest_destinationInfo[] = { /* SEQUENCE OF */
+static const struct field_t _LocationRequest_destinationInfo[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _LocationRequest[] = { /* SEQUENCE */
+static const struct field_t _LocationRequest[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("endpointIdentifier") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("destinationInfo") SEQOF, SEMI, 0, 0, SKIP, 0,
@@ -1818,7 +1818,7 @@ static field_t _LocationRequest[] = { /* SEQUENCE */
{FNAME("circuitInfo") SEQ, 3, 3, 3, STOP | EXT | OPT, 0, NULL},
};
-static field_t _LocationConfirm[] = { /* SEQUENCE */
+static const struct field_t _LocationConfirm[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("callSignalAddress") CHOICE, 3, 7, 7, DECODE | EXT,
offsetof(LocationConfirm, callSignalAddress), _TransportAddress},
@@ -1844,13 +1844,13 @@ static field_t _LocationConfirm[] = { /* SEQUENCE */
{FNAME("serviceControl") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _InfoRequestResponse_callSignalAddress[] = { /* SEQUENCE OF */
+static const struct field_t _InfoRequestResponse_callSignalAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
sizeof(TransportAddress), _TransportAddress}
,
};
-static field_t _InfoRequestResponse[] = { /* SEQUENCE */
+static const struct field_t _InfoRequestResponse[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
@@ -1873,7 +1873,7 @@ static field_t _InfoRequestResponse[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _RasMessage[] = { /* CHOICE */
+static const struct field_t _RasMessage[] = { /* CHOICE */
{FNAME("gatekeeperRequest") SEQ, 4, 8, 18, DECODE | EXT,
offsetof(RasMessage, gatekeeperRequest), _GatekeeperRequest},
{FNAME("gatekeeperConfirm") SEQ, 2, 5, 14, DECODE | EXT,
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 96aa637c093..b1fd21cc1db 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -28,6 +28,7 @@
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_extend.h>
+static DEFINE_MUTEX(nf_ct_helper_mutex);
static struct hlist_head *nf_ct_helper_hash __read_mostly;
static unsigned int nf_ct_helper_hsize __read_mostly;
static unsigned int nf_ct_helper_count __read_mostly;
@@ -54,42 +55,13 @@ __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
return NULL;
h = helper_hash(tuple);
- hlist_for_each_entry(helper, n, &nf_ct_helper_hash[h], hnode) {
+ hlist_for_each_entry_rcu(helper, n, &nf_ct_helper_hash[h], hnode) {
if (nf_ct_tuple_src_mask_cmp(tuple, &helper->tuple, &mask))
return helper;
}
return NULL;
}
-
-struct nf_conntrack_helper *
-nf_ct_helper_find_get(const struct nf_conntrack_tuple *tuple)
-{
- struct nf_conntrack_helper *helper;
-
- /* need nf_conntrack_lock to assure that helper exists until
- * try_module_get() is called */
- read_lock_bh(&nf_conntrack_lock);
-
- helper = __nf_ct_helper_find(tuple);
- if (helper) {
- /* need to increase module usage count to assure helper will
- * not go away while the caller is e.g. busy putting a
- * conntrack in the hash that uses the helper */
- if (!try_module_get(helper->me))
- helper = NULL;
- }
-
- read_unlock_bh(&nf_conntrack_lock);
-
- return helper;
-}
-EXPORT_SYMBOL_GPL(nf_ct_helper_find_get);
-
-void nf_ct_helper_put(struct nf_conntrack_helper *helper)
-{
- module_put(helper->me);
-}
-EXPORT_SYMBOL_GPL(nf_ct_helper_put);
+EXPORT_SYMBOL_GPL(__nf_ct_helper_find);
struct nf_conntrack_helper *
__nf_conntrack_helper_find_byname(const char *name)
@@ -99,7 +71,7 @@ __nf_conntrack_helper_find_byname(const char *name)
unsigned int i;
for (i = 0; i < nf_ct_helper_hsize; i++) {
- hlist_for_each_entry(h, n, &nf_ct_helper_hash[i], hnode) {
+ hlist_for_each_entry_rcu(h, n, &nf_ct_helper_hash[i], hnode) {
if (!strcmp(h->name, name))
return h;
}
@@ -140,10 +112,10 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
BUG_ON(me->timeout == 0);
- write_lock_bh(&nf_conntrack_lock);
- hlist_add_head(&me->hnode, &nf_ct_helper_hash[h]);
+ mutex_lock(&nf_ct_helper_mutex);
+ hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
nf_ct_helper_count++;
- write_unlock_bh(&nf_conntrack_lock);
+ mutex_unlock(&nf_ct_helper_mutex);
return 0;
}
@@ -156,10 +128,17 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
struct hlist_node *n, *next;
unsigned int i;
- /* Need write lock here, to delete helper. */
- write_lock_bh(&nf_conntrack_lock);
- hlist_del(&me->hnode);
+ mutex_lock(&nf_ct_helper_mutex);
+ hlist_del_rcu(&me->hnode);
nf_ct_helper_count--;
+ mutex_unlock(&nf_ct_helper_mutex);
+
+ /* Make sure every nothing is still using the helper unless its a
+ * connection in the hash.
+ */
+ synchronize_rcu();
+
+ spin_lock_bh(&nf_conntrack_lock);
/* Get rid of expectations */
for (i = 0; i < nf_ct_expect_hsize; i++) {
@@ -181,10 +160,7 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
hlist_for_each_entry(h, n, &nf_conntrack_hash[i], hnode)
unhelp(h, me);
}
- write_unlock_bh(&nf_conntrack_lock);
-
- /* Someone could be still looking at the helper in a bh. */
- synchronize_net();
+ spin_unlock_bh(&nf_conntrack_lock);
}
EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index dfaed4ba83c..c336b07a0d4 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -23,7 +23,7 @@
#define MAX_PORTS 8
static unsigned short ports[MAX_PORTS];
-static int ports_c;
+static unsigned int ports_c;
static unsigned int max_dcc_channels = 8;
static unsigned int dcc_timeout __read_mostly = 300;
/* This is slow, but it's simple. --RR */
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 38141f104db..4a1b42b2b7a 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -491,11 +491,6 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
&& ctnetlink_dump_helpinfo(skb, ct) < 0)
goto nla_put_failure;
-#ifdef CONFIG_NF_CONNTRACK_MARK
- if ((events & IPCT_MARK || ct->mark)
- && ctnetlink_dump_mark(skb, ct) < 0)
- goto nla_put_failure;
-#endif
#ifdef CONFIG_NF_CONNTRACK_SECMARK
if ((events & IPCT_SECMARK || ct->secmark)
&& ctnetlink_dump_secmark(skb, ct) < 0)
@@ -516,6 +511,12 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
goto nla_put_failure;
}
+#ifdef CONFIG_NF_CONNTRACK_MARK
+ if ((events & IPCT_MARK || ct->mark)
+ && ctnetlink_dump_mark(skb, ct) < 0)
+ goto nla_put_failure;
+#endif
+
nlh->nlmsg_len = skb->tail - b;
nfnetlink_send(skb, 0, group, 0);
return NOTIFY_DONE;
@@ -545,12 +546,12 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
u_int8_t l3proto = nfmsg->nfgen_family;
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
last = (struct nf_conn *)cb->args[1];
for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
restart:
- hlist_for_each_entry(h, n, &nf_conntrack_hash[cb->args[0]],
- hnode) {
+ hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[cb->args[0]],
+ hnode) {
if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
continue;
ct = nf_ct_tuplehash_to_ctrack(h);
@@ -568,7 +569,8 @@ restart:
cb->nlh->nlmsg_seq,
IPCTNL_MSG_CT_NEW,
1, ct) < 0) {
- nf_conntrack_get(&ct->ct_general);
+ if (!atomic_inc_not_zero(&ct->ct_general.use))
+ continue;
cb->args[1] = (unsigned long)ct;
goto out;
}
@@ -584,7 +586,7 @@ restart:
}
}
out:
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
if (last)
nf_ct_put(last);
@@ -1167,11 +1169,12 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));
#endif
- helper = nf_ct_helper_find_get(rtuple);
+ rcu_read_lock();
+ helper = __nf_ct_helper_find(rtuple);
if (helper) {
help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
if (help == NULL) {
- nf_ct_helper_put(helper);
+ rcu_read_unlock();
err = -ENOMEM;
goto err;
}
@@ -1187,9 +1190,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
add_timer(&ct->timeout);
nf_conntrack_hash_insert(ct);
-
- if (helper)
- nf_ct_helper_put(helper);
+ rcu_read_unlock();
return 0;
@@ -1220,11 +1221,11 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
return err;
}
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
if (cda[CTA_TUPLE_ORIG])
- h = __nf_conntrack_find(&otuple, NULL);
+ h = __nf_conntrack_find(&otuple);
else if (cda[CTA_TUPLE_REPLY])
- h = __nf_conntrack_find(&rtuple, NULL);
+ h = __nf_conntrack_find(&rtuple);
if (h == NULL) {
struct nf_conntrack_tuple master;
@@ -1237,9 +1238,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
CTA_TUPLE_MASTER,
u3);
if (err < 0)
- return err;
+ goto out_unlock;
- master_h = __nf_conntrack_find(&master, NULL);
+ master_h = __nf_conntrack_find(&master);
if (master_h == NULL) {
err = -ENOENT;
goto out_unlock;
@@ -1248,7 +1249,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
atomic_inc(&master_ct->ct_general.use);
}
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
err = -ENOENT;
if (nlh->nlmsg_flags & NLM_F_CREATE)
err = ctnetlink_create_conntrack(cda,
@@ -1281,7 +1282,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
}
out_unlock:
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return err;
}
@@ -1472,7 +1473,7 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
struct hlist_node *n;
u_int8_t l3proto = nfmsg->nfgen_family;
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
last = (struct nf_conntrack_expect *)cb->args[1];
for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) {
restart:
@@ -1489,7 +1490,8 @@ restart:
cb->nlh->nlmsg_seq,
IPCTNL_MSG_EXP_NEW,
1, exp) < 0) {
- atomic_inc(&exp->use);
+ if (!atomic_inc_not_zero(&exp->use))
+ continue;
cb->args[1] = (unsigned long)exp;
goto out;
}
@@ -1500,7 +1502,7 @@ restart:
}
}
out:
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
if (last)
nf_ct_expect_put(last);
@@ -1613,10 +1615,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
struct nf_conn_help *m_help;
/* delete all expectations for this helper */
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
h = __nf_conntrack_helper_find_byname(name);
if (!h) {
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return -EINVAL;
}
for (i = 0; i < nf_ct_expect_hsize; i++) {
@@ -1631,10 +1633,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
}
}
}
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
} else {
/* This basically means we have to flush everything*/
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
for (i = 0; i < nf_ct_expect_hsize; i++) {
hlist_for_each_entry_safe(exp, n, next,
&nf_ct_expect_hash[i],
@@ -1645,7 +1647,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
}
}
}
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
}
return 0;
@@ -1731,11 +1733,11 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
if (err < 0)
return err;
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
exp = __nf_ct_expect_find(&tuple);
if (!exp) {
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
err = -ENOENT;
if (nlh->nlmsg_flags & NLM_F_CREATE)
err = ctnetlink_create_expect(cda, u3);
@@ -1745,7 +1747,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
err = -EEXIST;
if (!(nlh->nlmsg_flags & NLM_F_EXCL))
err = ctnetlink_change_expect(exp, cda);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return err;
}
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 099b6df3e2b..b5cb8e83123 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -67,7 +67,7 @@ EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
#ifdef DEBUG
/* PptpControlMessageType names */
-const char *pptp_msg_name[] = {
+const char *const pptp_msg_name[] = {
"UNKNOWN_MESSAGE",
"START_SESSION_REQUEST",
"START_SESSION_REPLY",
@@ -136,7 +136,7 @@ static void pptp_expectfn(struct nf_conn *ct,
static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
{
- struct nf_conntrack_tuple_hash *h;
+ const struct nf_conntrack_tuple_hash *h;
struct nf_conntrack_expect *exp;
struct nf_conn *sibling;
@@ -168,7 +168,7 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
/* timeout GRE data connections */
static void pptp_destroy_siblings(struct nf_conn *ct)
{
- struct nf_conn_help *help = nfct_help(ct);
+ const struct nf_conn_help *help = nfct_help(ct);
struct nf_conntrack_tuple t;
nf_ct_gre_keymap_destroy(ct);
@@ -497,9 +497,11 @@ conntrack_pptp_help(struct sk_buff *skb, unsigned int protoff,
{
int dir = CTINFO2DIR(ctinfo);
- struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info;
- struct tcphdr _tcph, *tcph;
- struct pptp_pkt_hdr _pptph, *pptph;
+ const struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info;
+ const struct tcphdr *tcph;
+ struct tcphdr _tcph;
+ const struct pptp_pkt_hdr *pptph;
+ struct pptp_pkt_hdr _pptph;
struct PptpControlHeader _ctlh, *ctlh;
union pptp_ctrl_union _pptpReq, *pptpReq;
unsigned int tcplen = skb->len - protoff;
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index 22c5dcb6306..55458915575 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -41,19 +41,19 @@ static int generic_print_tuple(struct seq_file *s,
}
/* Returns verdict for packet, or -1 for invalid. */
-static int packet(struct nf_conn *conntrack,
+static int packet(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
int pf,
unsigned int hooknum)
{
- nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_generic_timeout);
+ nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_generic_timeout);
return NF_ACCEPT;
}
/* Called when a new connection for this protocol found. */
-static int new(struct nf_conn *conntrack, const struct sk_buff *skb,
+static int new(struct nf_conn *ct, const struct sk_buff *skb,
unsigned int dataoff)
{
return 1;
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 4a185f6aa65..e10024a1b66 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -161,9 +161,11 @@ static int gre_pkt_to_tuple(const struct sk_buff *skb,
unsigned int dataoff,
struct nf_conntrack_tuple *tuple)
{
- struct gre_hdr_pptp _pgrehdr, *pgrehdr;
+ const struct gre_hdr_pptp *pgrehdr;
+ struct gre_hdr_pptp _pgrehdr;
__be16 srckey;
- struct gre_hdr _grehdr, *grehdr;
+ const struct gre_hdr *grehdr;
+ struct gre_hdr _grehdr;
/* first only delinearize old RFC1701 GRE header */
grehdr = skb_header_pointer(skb, dataoff, sizeof(_grehdr), &_grehdr);
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 21d29e782ba..f9a08370dbb 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -25,7 +25,7 @@
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_ecache.h>
-/* Protects conntrack->proto.sctp */
+/* Protects ct->proto.sctp */
static DEFINE_RWLOCK(sctp_lock);
/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
@@ -624,7 +624,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
#endif
};
-int __init nf_conntrack_proto_sctp_init(void)
+static int __init nf_conntrack_proto_sctp_init(void)
{
int ret;
@@ -647,7 +647,7 @@ int __init nf_conntrack_proto_sctp_init(void)
return ret;
}
-void __exit nf_conntrack_proto_sctp_fini(void)
+static void __exit nf_conntrack_proto_sctp_fini(void)
{
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 64c9b910419..3e0cccae563 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -26,7 +26,7 @@
#include <net/netfilter/nf_conntrack_ecache.h>
#include <net/netfilter/nf_log.h>
-/* Protects conntrack->proto.tcp */
+/* Protects ct->proto.tcp */
static DEFINE_RWLOCK(tcp_lock);
/* "Be conservative in what you do,
@@ -46,7 +46,7 @@ static int nf_ct_tcp_max_retrans __read_mostly = 3;
/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
closely. They're more complex. --RR */
-static const char *tcp_conntrack_names[] = {
+static const char *const tcp_conntrack_names[] = {
"NONE",
"SYN_SENT",
"SYN_RECV",
@@ -261,7 +261,8 @@ static int tcp_pkt_to_tuple(const struct sk_buff *skb,
unsigned int dataoff,
struct nf_conntrack_tuple *tuple)
{
- struct tcphdr _hdr, *hp;
+ const struct tcphdr *hp;
+ struct tcphdr _hdr;
/* Actually only need first 8 bytes. */
hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
@@ -292,13 +293,12 @@ static int tcp_print_tuple(struct seq_file *s,
}
/* Print out the private part of the conntrack. */
-static int tcp_print_conntrack(struct seq_file *s,
- const struct nf_conn *conntrack)
+static int tcp_print_conntrack(struct seq_file *s, const struct nf_conn *ct)
{
enum tcp_conntrack state;
read_lock_bh(&tcp_lock);
- state = conntrack->proto.tcp.state;
+ state = ct->proto.tcp.state;
read_unlock_bh(&tcp_lock);
return seq_printf(s, "%s ", tcp_conntrack_names[state]);
@@ -344,7 +344,7 @@ static unsigned int get_conntrack_index(const struct tcphdr *tcph)
static inline __u32 segment_seq_plus_len(__u32 seq,
size_t len,
unsigned int dataoff,
- struct tcphdr *tcph)
+ const struct tcphdr *tcph)
{
/* XXX Should I use payload length field in IP/IPv6 header ?
* - YK */
@@ -363,11 +363,11 @@ static inline __u32 segment_seq_plus_len(__u32 seq,
*/
static void tcp_options(const struct sk_buff *skb,
unsigned int dataoff,
- struct tcphdr *tcph,
+ const struct tcphdr *tcph,
struct ip_ct_tcp_state *state)
{
unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
- unsigned char *ptr;
+ const unsigned char *ptr;
int length = (tcph->doff*4) - sizeof(struct tcphdr);
if (!length)
@@ -418,10 +418,10 @@ static void tcp_options(const struct sk_buff *skb,
}
static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
- struct tcphdr *tcph, __u32 *sack)
+ const struct tcphdr *tcph, __u32 *sack)
{
unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
- unsigned char *ptr;
+ const unsigned char *ptr;
int length = (tcph->doff*4) - sizeof(struct tcphdr);
__u32 tmp;
@@ -478,18 +478,18 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
}
}
-static int tcp_in_window(struct nf_conn *ct,
+static int tcp_in_window(const struct nf_conn *ct,
struct ip_ct_tcp *state,
enum ip_conntrack_dir dir,
unsigned int index,
const struct sk_buff *skb,
unsigned int dataoff,
- struct tcphdr *tcph,
+ const struct tcphdr *tcph,
int pf)
{
struct ip_ct_tcp_state *sender = &state->seen[dir];
struct ip_ct_tcp_state *receiver = &state->seen[!dir];
- struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
+ const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
__u32 seq, ack, sack, end, win, swin;
int res;
@@ -687,14 +687,14 @@ static int tcp_in_window(struct nf_conn *ct,
#ifdef CONFIG_NF_NAT_NEEDED
/* Update sender->td_end after NAT successfully mangled the packet */
/* Caller must linearize skb at tcp header. */
-void nf_conntrack_tcp_update(struct sk_buff *skb,
+void nf_conntrack_tcp_update(const struct sk_buff *skb,
unsigned int dataoff,
- struct nf_conn *conntrack,
+ struct nf_conn *ct,
int dir)
{
- struct tcphdr *tcph = (void *)skb->data + dataoff;
- struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[dir];
- struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[!dir];
+ const struct tcphdr *tcph = (const void *)skb->data + dataoff;
+ const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[dir];
+ const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[!dir];
__u32 end;
end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph);
@@ -703,9 +703,9 @@ void nf_conntrack_tcp_update(struct sk_buff *skb,
/*
* We have to worry for the ack in the reply packet only...
*/
- if (after(end, conntrack->proto.tcp.seen[dir].td_end))
- conntrack->proto.tcp.seen[dir].td_end = end;
- conntrack->proto.tcp.last_end = end;
+ if (after(end, ct->proto.tcp.seen[dir].td_end))
+ ct->proto.tcp.seen[dir].td_end = end;
+ ct->proto.tcp.last_end = end;
write_unlock_bh(&tcp_lock);
pr_debug("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
"receiver end=%u maxend=%u maxwin=%u scale=%i\n",
@@ -727,7 +727,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update);
#define TH_CWR 0x80
/* table of valid flag combinations - PUSH, ECE and CWR are always valid */
-static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG) + 1] =
+static const u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG) + 1] =
{
[TH_SYN] = 1,
[TH_SYN|TH_URG] = 1,
@@ -747,7 +747,8 @@ static int tcp_error(struct sk_buff *skb,
int pf,
unsigned int hooknum)
{
- struct tcphdr _tcph, *th;
+ const struct tcphdr *th;
+ struct tcphdr _tcph;
unsigned int tcplen = skb->len - dataoff;
u_int8_t tcpflags;
@@ -794,7 +795,7 @@ static int tcp_error(struct sk_buff *skb,
}
/* Returns verdict for packet, or -1 for invalid. */
-static int tcp_packet(struct nf_conn *conntrack,
+static int tcp_packet(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
@@ -804,7 +805,8 @@ static int tcp_packet(struct nf_conn *conntrack,
struct nf_conntrack_tuple *tuple;
enum tcp_conntrack new_state, old_state;
enum ip_conntrack_dir dir;
- struct tcphdr *th, _tcph;
+ const struct tcphdr *th;
+ struct tcphdr _tcph;
unsigned long timeout;
unsigned int index;
@@ -812,26 +814,24 @@ static int tcp_packet(struct nf_conn *conntrack,
BUG_ON(th == NULL);
write_lock_bh(&tcp_lock);
- old_state = conntrack->proto.tcp.state;
+ old_state = ct->proto.tcp.state;
dir = CTINFO2DIR(ctinfo);
index = get_conntrack_index(th);
new_state = tcp_conntracks[dir][index][old_state];
- tuple = &conntrack->tuplehash[dir].tuple;
+ tuple = &ct->tuplehash[dir].tuple;
switch (new_state) {
case TCP_CONNTRACK_SYN_SENT:
if (old_state < TCP_CONNTRACK_TIME_WAIT)
break;
- if ((conntrack->proto.tcp.seen[!dir].flags &
- IP_CT_TCP_FLAG_CLOSE_INIT)
- || (conntrack->proto.tcp.last_dir == dir
- && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
+ if ((ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_CLOSE_INIT)
+ || (ct->proto.tcp.last_dir == dir
+ && ct->proto.tcp.last_index == TCP_RST_SET)) {
/* Attempt to reopen a closed/aborted connection.
* Delete this connection and look up again. */
write_unlock_bh(&tcp_lock);
- if (del_timer(&conntrack->timeout))
- conntrack->timeout.function((unsigned long)
- conntrack);
+ if (del_timer(&ct->timeout))
+ ct->timeout.function((unsigned long)ct);
return -NF_REPEAT;
}
/* Fall through */
@@ -843,10 +843,9 @@ static int tcp_packet(struct nf_conn *conntrack,
* c) ACK in reply direction after initial SYN in original.
*/
if (index == TCP_SYNACK_SET
- && conntrack->proto.tcp.last_index == TCP_SYN_SET
- && conntrack->proto.tcp.last_dir != dir
- && ntohl(th->ack_seq) ==
- conntrack->proto.tcp.last_end) {
+ && ct->proto.tcp.last_index == TCP_SYN_SET
+ && ct->proto.tcp.last_dir != dir
+ && ntohl(th->ack_seq) == ct->proto.tcp.last_end) {
/* This SYN/ACK acknowledges a SYN that we earlier
* ignored as invalid. This means that the client and
* the server are both in sync, while the firewall is
@@ -858,15 +857,14 @@ static int tcp_packet(struct nf_conn *conntrack,
if (LOG_INVALID(IPPROTO_TCP))
nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
"nf_ct_tcp: killing out of sync session ");
- if (del_timer(&conntrack->timeout))
- conntrack->timeout.function((unsigned long)
- conntrack);
+ if (del_timer(&ct->timeout))
+ ct->timeout.function((unsigned long)ct);
return -NF_DROP;
}
- conntrack->proto.tcp.last_index = index;
- conntrack->proto.tcp.last_dir = dir;
- conntrack->proto.tcp.last_seq = ntohl(th->seq);
- conntrack->proto.tcp.last_end =
+ ct->proto.tcp.last_index = index;
+ ct->proto.tcp.last_dir = dir;
+ ct->proto.tcp.last_seq = ntohl(th->seq);
+ ct->proto.tcp.last_end =
segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
write_unlock_bh(&tcp_lock);
@@ -885,11 +883,11 @@ static int tcp_packet(struct nf_conn *conntrack,
return -NF_ACCEPT;
case TCP_CONNTRACK_CLOSE:
if (index == TCP_RST_SET
- && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
- && conntrack->proto.tcp.last_index == TCP_SYN_SET)
- || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
- && conntrack->proto.tcp.last_index == TCP_ACK_SET))
- && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
+ && ((test_bit(IPS_SEEN_REPLY_BIT, &ct->status)
+ && ct->proto.tcp.last_index == TCP_SYN_SET)
+ || (!test_bit(IPS_ASSURED_BIT, &ct->status)
+ && ct->proto.tcp.last_index == TCP_ACK_SET))
+ && ntohl(th->ack_seq) == ct->proto.tcp.last_end) {
/* RST sent to invalid SYN or ACK we had let through
* at a) and c) above:
*
@@ -907,15 +905,15 @@ static int tcp_packet(struct nf_conn *conntrack,
break;
}
- if (!tcp_in_window(conntrack, &conntrack->proto.tcp, dir, index,
+ if (!tcp_in_window(ct, &ct->proto.tcp, dir, index,
skb, dataoff, th, pf)) {
write_unlock_bh(&tcp_lock);
return -NF_ACCEPT;
}
in_window:
/* From now on we have got in-window packets */
- conntrack->proto.tcp.last_index = index;
- conntrack->proto.tcp.last_dir = dir;
+ ct->proto.tcp.last_index = index;
+ ct->proto.tcp.last_dir = dir;
pr_debug("tcp_conntracks: ");
NF_CT_DUMP_TUPLE(tuple);
@@ -924,12 +922,12 @@ static int tcp_packet(struct nf_conn *conntrack,
(th->fin ? 1 : 0), (th->rst ? 1 : 0),
old_state, new_state);
- conntrack->proto.tcp.state = new_state;
+ ct->proto.tcp.state = new_state;
if (old_state != new_state
&& (new_state == TCP_CONNTRACK_FIN_WAIT
|| new_state == TCP_CONNTRACK_CLOSE))
- conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
- timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans
+ ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
+ timeout = ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans
&& tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
? nf_ct_tcp_timeout_max_retrans : tcp_timeouts[new_state];
write_unlock_bh(&tcp_lock);
@@ -938,41 +936,41 @@ static int tcp_packet(struct nf_conn *conntrack,
if (new_state != old_state)
nf_conntrack_event_cache(IPCT_PROTOINFO, skb);
- if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
+ if (!test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
/* If only reply is a RST, we can consider ourselves not to
have an established connection: this is a fairly common
problem case, so we can delete the conntrack
immediately. --RR */
if (th->rst) {
- if (del_timer(&conntrack->timeout))
- conntrack->timeout.function((unsigned long)
- conntrack);
+ if (del_timer(&ct->timeout))
+ ct->timeout.function((unsigned long)ct);
return NF_ACCEPT;
}
- } else if (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
+ } else if (!test_bit(IPS_ASSURED_BIT, &ct->status)
&& (old_state == TCP_CONNTRACK_SYN_RECV
|| old_state == TCP_CONNTRACK_ESTABLISHED)
&& new_state == TCP_CONNTRACK_ESTABLISHED) {
/* Set ASSURED if we see see valid ack in ESTABLISHED
after SYN_RECV or a valid answer for a picked up
connection. */
- set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ set_bit(IPS_ASSURED_BIT, &ct->status);
nf_conntrack_event_cache(IPCT_STATUS, skb);
}
- nf_ct_refresh_acct(conntrack, ctinfo, skb, timeout);
+ nf_ct_refresh_acct(ct, ctinfo, skb, timeout);
return NF_ACCEPT;
}
/* Called when a new connection for this protocol found. */
-static int tcp_new(struct nf_conn *conntrack,
+static int tcp_new(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff)
{
enum tcp_conntrack new_state;
- struct tcphdr *th, _tcph;
- struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[0];
- struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[1];
+ const struct tcphdr *th;
+ struct tcphdr _tcph;
+ const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0];
+ const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1];
th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
BUG_ON(th == NULL);
@@ -990,17 +988,17 @@ static int tcp_new(struct nf_conn *conntrack,
if (new_state == TCP_CONNTRACK_SYN_SENT) {
/* SYN packet */
- conntrack->proto.tcp.seen[0].td_end =
+ ct->proto.tcp.seen[0].td_end =
segment_seq_plus_len(ntohl(th->seq), skb->len,
dataoff, th);
- conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
- if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
- conntrack->proto.tcp.seen[0].td_maxwin = 1;
- conntrack->proto.tcp.seen[0].td_maxend =
- conntrack->proto.tcp.seen[0].td_end;
-
- tcp_options(skb, dataoff, th, &conntrack->proto.tcp.seen[0]);
- conntrack->proto.tcp.seen[1].flags = 0;
+ ct->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
+ if (ct->proto.tcp.seen[0].td_maxwin == 0)
+ ct->proto.tcp.seen[0].td_maxwin = 1;
+ ct->proto.tcp.seen[0].td_maxend =
+ ct->proto.tcp.seen[0].td_end;
+
+ tcp_options(skb, dataoff, th, &ct->proto.tcp.seen[0]);
+ ct->proto.tcp.seen[1].flags = 0;
} else if (nf_ct_tcp_loose == 0) {
/* Don't try to pick up connections. */
return 0;
@@ -1010,32 +1008,32 @@ static int tcp_new(struct nf_conn *conntrack,
* its history is lost for us.
* Let's try to use the data from the packet.
*/
- conntrack->proto.tcp.seen[0].td_end =
+ ct->proto.tcp.seen[0].td_end =
segment_seq_plus_len(ntohl(th->seq), skb->len,
dataoff, th);
- conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
- if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
- conntrack->proto.tcp.seen[0].td_maxwin = 1;
- conntrack->proto.tcp.seen[0].td_maxend =
- conntrack->proto.tcp.seen[0].td_end +
- conntrack->proto.tcp.seen[0].td_maxwin;
- conntrack->proto.tcp.seen[0].td_scale = 0;
+ ct->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
+ if (ct->proto.tcp.seen[0].td_maxwin == 0)
+ ct->proto.tcp.seen[0].td_maxwin = 1;
+ ct->proto.tcp.seen[0].td_maxend =
+ ct->proto.tcp.seen[0].td_end +
+ ct->proto.tcp.seen[0].td_maxwin;
+ ct->proto.tcp.seen[0].td_scale = 0;
/* We assume SACK and liberal window checking to handle
* window scaling */
- conntrack->proto.tcp.seen[0].flags =
- conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM |
- IP_CT_TCP_FLAG_BE_LIBERAL;
+ ct->proto.tcp.seen[0].flags =
+ ct->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM |
+ IP_CT_TCP_FLAG_BE_LIBERAL;
}
- conntrack->proto.tcp.seen[1].td_end = 0;
- conntrack->proto.tcp.seen[1].td_maxend = 0;
- conntrack->proto.tcp.seen[1].td_maxwin = 1;
- conntrack->proto.tcp.seen[1].td_scale = 0;
+ ct->proto.tcp.seen[1].td_end = 0;
+ ct->proto.tcp.seen[1].td_maxend = 0;
+ ct->proto.tcp.seen[1].td_maxwin = 1;
+ ct->proto.tcp.seen[1].td_scale = 0;
/* tcp_packet will set them */
- conntrack->proto.tcp.state = TCP_CONNTRACK_NONE;
- conntrack->proto.tcp.last_index = TCP_NONE_SET;
+ ct->proto.tcp.state = TCP_CONNTRACK_NONE;
+ ct->proto.tcp.last_index = TCP_NONE_SET;
pr_debug("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
"receiver end=%u maxend=%u maxwin=%u scale=%i\n",
@@ -1098,16 +1096,16 @@ static const struct nla_policy tcp_nla_policy[CTA_PROTOINFO_TCP_MAX+1] = {
static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
{
- struct nlattr *attr = cda[CTA_PROTOINFO_TCP];
+ struct nlattr *pattr = cda[CTA_PROTOINFO_TCP];
struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1];
int err;
/* updates could not contain anything about the private
* protocol info, in that case skip the parsing */
- if (!attr)
+ if (!pattr)
return 0;
- err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr, tcp_nla_policy);
+ err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, pattr, tcp_nla_policy);
if (err < 0)
return err;
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index 38487541108..b8a35cc0641 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -30,7 +30,8 @@ static int udp_pkt_to_tuple(const struct sk_buff *skb,
unsigned int dataoff,
struct nf_conntrack_tuple *tuple)
{
- struct udphdr _hdr, *hp;
+ const struct udphdr *hp;
+ struct udphdr _hdr;
/* Actually only need first 8 bytes. */
hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
@@ -61,7 +62,7 @@ static int udp_print_tuple(struct seq_file *s,
}
/* Returns verdict for packet, and may modify conntracktype */
-static int udp_packet(struct nf_conn *conntrack,
+static int udp_packet(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
@@ -70,20 +71,19 @@ static int udp_packet(struct nf_conn *conntrack,
{
/* If we've seen traffic both ways, this is some kind of UDP
stream. Extend timeout. */
- if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
- nf_ct_refresh_acct(conntrack, ctinfo, skb,
- nf_ct_udp_timeout_stream);
+ if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
+ nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout_stream);
/* Also, more likely to be important, and not a probe */
- if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status))
+ if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
nf_conntrack_event_cache(IPCT_STATUS, skb);
} else
- nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_udp_timeout);
+ nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout);
return NF_ACCEPT;
}
/* Called when a new connection for this protocol found. */
-static int udp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
+static int udp_new(struct nf_conn *ct, const struct sk_buff *skb,
unsigned int dataoff)
{
return 1;
@@ -95,7 +95,8 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff,
unsigned int hooknum)
{
unsigned int udplen = skb->len - dataoff;
- struct udphdr _hdr, *hdr;
+ const struct udphdr *hdr;
+ struct udphdr _hdr;
/* Header is too small? */
hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index 070056d9bcd..9dd03c7aeac 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -31,7 +31,8 @@ static int udplite_pkt_to_tuple(const struct sk_buff *skb,
unsigned int dataoff,
struct nf_conntrack_tuple *tuple)
{
- struct udphdr _hdr, *hp;
+ const struct udphdr *hp;
+ struct udphdr _hdr;
hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
if (hp == NULL)
@@ -60,7 +61,7 @@ static int udplite_print_tuple(struct seq_file *s,
}
/* Returns verdict for packet, and may modify conntracktype */
-static int udplite_packet(struct nf_conn *conntrack,
+static int udplite_packet(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
@@ -69,21 +70,20 @@ static int udplite_packet(struct nf_conn *conntrack,
{
/* If we've seen traffic both ways, this is some kind of UDP
stream. Extend timeout. */
- if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
- nf_ct_refresh_acct(conntrack, ctinfo, skb,
+ if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
+ nf_ct_refresh_acct(ct, ctinfo, skb,
nf_ct_udplite_timeout_stream);
/* Also, more likely to be important, and not a probe */
- if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status))
+ if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
nf_conntrack_event_cache(IPCT_STATUS, skb);
} else
- nf_ct_refresh_acct(conntrack, ctinfo, skb,
- nf_ct_udplite_timeout);
+ nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udplite_timeout);
return NF_ACCEPT;
}
/* Called when a new connection for this protocol found. */
-static int udplite_new(struct nf_conn *conntrack, const struct sk_buff *skb,
+static int udplite_new(struct nf_conn *ct, const struct sk_buff *skb,
unsigned int dataoff)
{
return 1;
@@ -95,7 +95,8 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
unsigned int hooknum)
{
unsigned int udplen = skb->len - dataoff;
- struct udphdr _hdr, *hdr;
+ const struct udphdr *hdr;
+ struct udphdr _hdr;
unsigned int cscov;
/* Header is too small? */
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index b5a16c6e21c..a70051d741a 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -62,8 +62,9 @@ static int help(struct sk_buff *skb,
enum ip_conntrack_info ctinfo)
{
unsigned int dataoff, datalen;
- struct tcphdr _tcph, *th;
- char *sb_ptr;
+ const struct tcphdr *th;
+ struct tcphdr _tcph;
+ void *sb_ptr;
int ret = NF_ACCEPT;
int dir = CTINFO2DIR(ctinfo);
struct nf_ct_sane_master *ct_sane_info;
@@ -99,7 +100,7 @@ static int help(struct sk_buff *skb,
if (datalen != sizeof(struct sane_request))
goto out;
- req = (struct sane_request *)sb_ptr;
+ req = sb_ptr;
if (req->RPC_code != htonl(SANE_NET_START)) {
/* Not an interesting command */
ct_sane_info->state = SANE_STATE_NORMAL;
@@ -123,7 +124,7 @@ static int help(struct sk_buff *skb,
goto out;
}
- reply = (struct sane_reply_net_start *)sb_ptr;
+ reply = sb_ptr;
if (reply->status != htonl(SANE_STATUS_SUCCESS)) {
/* saned refused the command */
pr_debug("nf_ct_sane: unsuccessful SANE_STATUS = %u\n",
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 47d8947cf26..c521c891d35 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -28,7 +28,7 @@ MODULE_ALIAS("ip_conntrack_sip");
#define MAX_PORTS 8
static unsigned short ports[MAX_PORTS];
-static int ports_c;
+static unsigned int ports_c;
module_param_array(ports, ushort, &ports_c, 0400);
MODULE_PARM_DESC(ports, "port numbers of SIP servers");
@@ -48,10 +48,10 @@ unsigned int (*nf_nat_sdp_hook)(struct sk_buff *skb,
const char *dptr) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_sdp_hook);
-static int digits_len(struct nf_conn *, const char *, const char *, int *);
-static int epaddr_len(struct nf_conn *, const char *, const char *, int *);
-static int skp_digits_len(struct nf_conn *, const char *, const char *, int *);
-static int skp_epaddr_len(struct nf_conn *, const char *, const char *, int *);
+static int digits_len(const struct nf_conn *, const char *, const char *, int *);
+static int epaddr_len(const struct nf_conn *, const char *, const char *, int *);
+static int skp_digits_len(const struct nf_conn *, const char *, const char *, int *);
+static int skp_epaddr_len(const struct nf_conn *, const char *, const char *, int *);
struct sip_header_nfo {
const char *lname;
@@ -61,7 +61,7 @@ struct sip_header_nfo {
size_t snlen;
size_t ln_strlen;
int case_sensitive;
- int (*match_len)(struct nf_conn *, const char *,
+ int (*match_len)(const struct nf_conn *, const char *,
const char *, int *);
};
@@ -225,7 +225,7 @@ const char *ct_sip_search(const char *needle, const char *haystack,
}
EXPORT_SYMBOL_GPL(ct_sip_search);
-static int digits_len(struct nf_conn *ct, const char *dptr,
+static int digits_len(const struct nf_conn *ct, const char *dptr,
const char *limit, int *shift)
{
int len = 0;
@@ -237,7 +237,7 @@ static int digits_len(struct nf_conn *ct, const char *dptr,
}
/* get digits length, skipping blank spaces. */
-static int skp_digits_len(struct nf_conn *ct, const char *dptr,
+static int skp_digits_len(const struct nf_conn *ct, const char *dptr,
const char *limit, int *shift)
{
for (; dptr <= limit && *dptr == ' '; dptr++)
@@ -246,8 +246,9 @@ static int skp_digits_len(struct nf_conn *ct, const char *dptr,
return digits_len(ct, dptr, limit, shift);
}
-static int parse_addr(struct nf_conn *ct, const char *cp, const char **endp,
- union nf_inet_addr *addr, const char *limit)
+static int parse_addr(const struct nf_conn *ct, const char *cp,
+ const char **endp, union nf_inet_addr *addr,
+ const char *limit)
{
const char *end;
int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
@@ -272,7 +273,7 @@ static int parse_addr(struct nf_conn *ct, const char *cp, const char **endp,
}
/* skip ip address. returns its length. */
-static int epaddr_len(struct nf_conn *ct, const char *dptr,
+static int epaddr_len(const struct nf_conn *ct, const char *dptr,
const char *limit, int *shift)
{
union nf_inet_addr addr;
@@ -292,7 +293,7 @@ static int epaddr_len(struct nf_conn *ct, const char *dptr,
}
/* get address length, skiping user info. */
-static int skp_epaddr_len(struct nf_conn *ct, const char *dptr,
+static int skp_epaddr_len(const struct nf_conn *ct, const char *dptr,
const char *limit, int *shift)
{
const char *start = dptr;
@@ -319,7 +320,7 @@ static int skp_epaddr_len(struct nf_conn *ct, const char *dptr,
}
/* Returns 0 if not found, -1 error parsing. */
-int ct_sip_get_info(struct nf_conn *ct,
+int ct_sip_get_info(const struct nf_conn *ct,
const char *dptr, size_t dlen,
unsigned int *matchoff,
unsigned int *matchlen,
@@ -407,7 +408,7 @@ static int sip_help(struct sk_buff *skb,
unsigned int dataoff, datalen;
const char *dptr;
int ret = NF_ACCEPT;
- int matchoff, matchlen;
+ unsigned int matchoff, matchlen;
u_int16_t port;
enum sip_header_pos pos;
typeof(nf_nat_sip_hook) nf_nat_sip;
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 696074a037c..e88e96af613 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -31,8 +31,8 @@ MODULE_LICENSE("GPL");
#ifdef CONFIG_PROC_FS
int
print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
- struct nf_conntrack_l3proto *l3proto,
- struct nf_conntrack_l4proto *l4proto)
+ const struct nf_conntrack_l3proto *l3proto,
+ const struct nf_conntrack_l4proto *l4proto)
{
return l3proto->print_tuple(s, tuple) || l4proto->print_tuple(s, tuple);
}
@@ -58,12 +58,14 @@ struct ct_iter_state {
static struct hlist_node *ct_get_first(struct seq_file *seq)
{
struct ct_iter_state *st = seq->private;
+ struct hlist_node *n;
for (st->bucket = 0;
st->bucket < nf_conntrack_htable_size;
st->bucket++) {
- if (!hlist_empty(&nf_conntrack_hash[st->bucket]))
- return nf_conntrack_hash[st->bucket].first;
+ n = rcu_dereference(nf_conntrack_hash[st->bucket].first);
+ if (n)
+ return n;
}
return NULL;
}
@@ -73,11 +75,11 @@ static struct hlist_node *ct_get_next(struct seq_file *seq,
{
struct ct_iter_state *st = seq->private;
- head = head->next;
+ head = rcu_dereference(head->next);
while (head == NULL) {
if (++st->bucket >= nf_conntrack_htable_size)
return NULL;
- head = nf_conntrack_hash[st->bucket].first;
+ head = rcu_dereference(nf_conntrack_hash[st->bucket].first);
}
return head;
}
@@ -93,8 +95,9 @@ static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
}
static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
return ct_get_idx(seq, *pos);
}
@@ -105,79 +108,80 @@ static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
}
static void ct_seq_stop(struct seq_file *s, void *v)
+ __releases(RCU)
{
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
}
/* return 0 on success, 1 in case of error */
static int ct_seq_show(struct seq_file *s, void *v)
{
const struct nf_conntrack_tuple_hash *hash = v;
- const struct nf_conn *conntrack = nf_ct_tuplehash_to_ctrack(hash);
- struct nf_conntrack_l3proto *l3proto;
- struct nf_conntrack_l4proto *l4proto;
+ const struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
+ const struct nf_conntrack_l3proto *l3proto;
+ const struct nf_conntrack_l4proto *l4proto;
- NF_CT_ASSERT(conntrack);
+ NF_CT_ASSERT(ct);
/* we only want to print DIR_ORIGINAL */
if (NF_CT_DIRECTION(hash))
return 0;
- l3proto = __nf_ct_l3proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+ l3proto = __nf_ct_l3proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL]
.tuple.src.l3num);
NF_CT_ASSERT(l3proto);
- l4proto = __nf_ct_l4proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+ l4proto = __nf_ct_l4proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL]
.tuple.src.l3num,
- conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+ ct->tuplehash[IP_CT_DIR_ORIGINAL]
.tuple.dst.protonum);
NF_CT_ASSERT(l4proto);
if (seq_printf(s, "%-8s %u %-8s %u %ld ",
l3proto->name,
- conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num,
+ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num,
l4proto->name,
- conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
- timer_pending(&conntrack->timeout)
- ? (long)(conntrack->timeout.expires - jiffies)/HZ : 0) != 0)
+ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
+ timer_pending(&ct->timeout)
+ ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0)
return -ENOSPC;
- if (l4proto->print_conntrack && l4proto->print_conntrack(s, conntrack))
+ if (l4proto->print_conntrack && l4proto->print_conntrack(s, ct))
return -ENOSPC;
- if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+ if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
l3proto, l4proto))
return -ENOSPC;
- if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_ORIGINAL]))
+ if (seq_print_counters(s, &ct->counters[IP_CT_DIR_ORIGINAL]))
return -ENOSPC;
- if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
+ if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
if (seq_printf(s, "[UNREPLIED] "))
return -ENOSPC;
- if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
+ if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple,
l3proto, l4proto))
return -ENOSPC;
- if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_REPLY]))
+ if (seq_print_counters(s, &ct->counters[IP_CT_DIR_REPLY]))
return -ENOSPC;
- if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
+ if (test_bit(IPS_ASSURED_BIT, &ct->status))
if (seq_printf(s, "[ASSURED] "))
return -ENOSPC;
#if defined(CONFIG_NF_CONNTRACK_MARK)
- if (seq_printf(s, "mark=%u ", conntrack->mark))
+ if (seq_printf(s, "mark=%u ", ct->mark))
return -ENOSPC;
#endif
#ifdef CONFIG_NF_CONNTRACK_SECMARK
- if (seq_printf(s, "secmark=%u ", conntrack->secmark))
+ if (seq_printf(s, "secmark=%u ", ct->secmark))
return -ENOSPC;
#endif
- if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use)))
+ if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use)))
return -ENOSPC;
return 0;
@@ -242,7 +246,7 @@ static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
static int ct_cpu_seq_show(struct seq_file *seq, void *v)
{
unsigned int nr_conntracks = atomic_read(&nf_conntrack_count);
- struct ip_conntrack_stat *st = v;
+ const struct ip_conntrack_stat *st = v;
if (v == SEQ_START_TOKEN) {
seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete\n");
@@ -380,7 +384,7 @@ static ctl_table nf_ct_netfilter_table[] = {
{ .ctl_name = 0 }
};
-struct ctl_path nf_ct_path[] = {
+static struct ctl_path nf_ct_path[] = {
{ .procname = "net", .ctl_name = CTL_NET, },
{ }
};
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
index e894aa1ff3a..bd2e800f23c 100644
--- a/net/netfilter/nf_conntrack_tftp.c
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -25,7 +25,7 @@ MODULE_ALIAS("ip_conntrack_tftp");
#define MAX_PORTS 8
static unsigned short ports[MAX_PORTS];
-static int ports_c;
+static unsigned int ports_c;
module_param_array(ports, ushort, &ports_c, 0400);
MODULE_PARM_DESC(ports, "Port numbers of TFTP servers");
@@ -39,7 +39,8 @@ static int tftp_help(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
{
- struct tftphdr _tftph, *tfh;
+ const struct tftphdr *tfh;
+ struct tftphdr _tftph;
struct nf_conntrack_expect *exp;
struct nf_conntrack_tuple *tuple;
unsigned int ret = NF_ACCEPT;
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 4f5f2885fca..cec9976aecb 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -103,6 +103,7 @@ EXPORT_SYMBOL(nf_log_packet);
#ifdef CONFIG_PROC_FS
static void *seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
rcu_read_lock();
@@ -123,6 +124,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
}
static void seq_stop(struct seq_file *s, void *v)
+ __releases(RCU)
{
rcu_read_unlock();
}
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 5013cb97ce2..7efa40d4739 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -467,7 +467,7 @@ __build_packet_message(struct nfulnl_instance *inst,
read_lock_bh(&skb->sk->sk_callback_lock);
if (skb->sk->sk_socket && skb->sk->sk_socket->file) {
__be32 uid = htonl(skb->sk->sk_socket->file->f_uid);
- __be32 gid = htons(skb->sk->sk_socket->file->f_gid);
+ __be32 gid = htonl(skb->sk->sk_socket->file->f_gid);
/* need to unlock here since NLA_PUT may goto */
read_unlock_bh(&skb->sk->sk_callback_lock);
NLA_PUT_BE32(inst->skb, NFULA_UID, uid);
@@ -866,6 +866,7 @@ static struct hlist_node *get_idx(struct iter_state *st, loff_t pos)
}
static void *seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(instances_lock)
{
read_lock_bh(&instances_lock);
return get_idx(seq->private, *pos);
@@ -878,6 +879,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
}
static void seq_stop(struct seq_file *s, void *v)
+ __releases(instances_lock)
{
read_unlock_bh(&instances_lock);
}
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 51476f82bb5..a48b20fe9cd 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -360,7 +360,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
if (data_len) {
struct nlattr *nla;
- int size = nla_attr_size(data_len);
+ int sz = nla_attr_size(data_len);
if (skb_tailroom(skb) < nla_total_size(data_len)) {
printk(KERN_WARNING "nf_queue: no tailroom!\n");
@@ -369,7 +369,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
nla = (struct nlattr *)skb_put(skb, nla_total_size(data_len));
nla->nla_type = NFQA_PAYLOAD;
- nla->nla_len = size;
+ nla->nla_len = sz;
if (skb_copy_bits(entskb, 0, nla_data(nla), data_len))
BUG();
@@ -845,6 +845,7 @@ static struct hlist_node *get_idx(struct seq_file *seq, loff_t pos)
}
static void *seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(instances_lock)
{
spin_lock(&instances_lock);
return get_idx(seq, *pos);
@@ -857,6 +858,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
}
static void seq_stop(struct seq_file *s, void *v)
+ __releases(instances_lock)
{
spin_unlock(&instances_lock);
}
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 8d4fca96a4a..a6792089fcf 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -44,7 +44,6 @@ struct xt_af {
struct mutex mutex;
struct list_head match;
struct list_head target;
- struct list_head tables;
#ifdef CONFIG_COMPAT
struct mutex compat_mutex;
struct compat_delta *compat_offsets;
@@ -59,12 +58,6 @@ static struct xt_af *xt;
#define duprintf(format, args...)
#endif
-enum {
- TABLE,
- TARGET,
- MATCH,
-};
-
static const char *xt_prefix[NPROTO] = {
[AF_INET] = "ip",
[AF_INET6] = "ip6",
@@ -400,7 +393,7 @@ int xt_compat_match_offset(struct xt_match *match)
EXPORT_SYMBOL_GPL(xt_compat_match_offset);
int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
- int *size)
+ unsigned int *size)
{
struct xt_match *match = m->u.kernel.match;
struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m;
@@ -427,7 +420,7 @@ int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
EXPORT_SYMBOL_GPL(xt_compat_match_from_user);
int xt_compat_match_to_user(struct xt_entry_match *m, void __user **dstptr,
- int *size)
+ unsigned int *size)
{
struct xt_match *match = m->u.kernel.match;
struct compat_xt_entry_match __user *cm = *dstptr;
@@ -494,7 +487,7 @@ int xt_compat_target_offset(struct xt_target *target)
EXPORT_SYMBOL_GPL(xt_compat_target_offset);
void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
- int *size)
+ unsigned int *size)
{
struct xt_target *target = t->u.kernel.target;
struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t;
@@ -520,7 +513,7 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
EXPORT_SYMBOL_GPL(xt_compat_target_from_user);
int xt_compat_target_to_user(struct xt_entry_target *t, void __user **dstptr,
- int *size)
+ unsigned int *size)
{
struct xt_target *target = t->u.kernel.target;
struct compat_xt_entry_target __user *ct = *dstptr;
@@ -597,14 +590,14 @@ void xt_free_table_info(struct xt_table_info *info)
EXPORT_SYMBOL(xt_free_table_info);
/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */
-struct xt_table *xt_find_table_lock(int af, const char *name)
+struct xt_table *xt_find_table_lock(struct net *net, int af, const char *name)
{
struct xt_table *t;
if (mutex_lock_interruptible(&xt[af].mutex) != 0)
return ERR_PTR(-EINTR);
- list_for_each_entry(t, &xt[af].tables, list)
+ list_for_each_entry(t, &net->xt.tables[af], list)
if (strcmp(t->name, name) == 0 && try_module_get(t->me))
return t;
mutex_unlock(&xt[af].mutex);
@@ -660,20 +653,27 @@ xt_replace_table(struct xt_table *table,
}
EXPORT_SYMBOL_GPL(xt_replace_table);
-int xt_register_table(struct xt_table *table,
- struct xt_table_info *bootstrap,
- struct xt_table_info *newinfo)
+struct xt_table *xt_register_table(struct net *net, struct xt_table *table,
+ struct xt_table_info *bootstrap,
+ struct xt_table_info *newinfo)
{
int ret;
struct xt_table_info *private;
struct xt_table *t;
+ /* Don't add one object to multiple lists. */
+ table = kmemdup(table, sizeof(struct xt_table), GFP_KERNEL);
+ if (!table) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
ret = mutex_lock_interruptible(&xt[table->af].mutex);
if (ret != 0)
- return ret;
+ goto out_free;
/* Don't autoload: we'd eat our tail... */
- list_for_each_entry(t, &xt[table->af].tables, list) {
+ list_for_each_entry(t, &net->xt.tables[table->af], list) {
if (strcmp(t->name, table->name) == 0) {
ret = -EEXIST;
goto unlock;
@@ -692,12 +692,16 @@ int xt_register_table(struct xt_table *table,
/* save number of initial entries */
private->initial_entries = private->number;
- list_add(&table->list, &xt[table->af].tables);
+ list_add(&table->list, &net->xt.tables[table->af]);
+ mutex_unlock(&xt[table->af].mutex);
+ return table;
- ret = 0;
unlock:
mutex_unlock(&xt[table->af].mutex);
- return ret;
+out_free:
+ kfree(table);
+out:
+ return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(xt_register_table);
@@ -709,130 +713,204 @@ void *xt_unregister_table(struct xt_table *table)
private = table->private;
list_del(&table->list);
mutex_unlock(&xt[table->af].mutex);
+ kfree(table);
return private;
}
EXPORT_SYMBOL_GPL(xt_unregister_table);
#ifdef CONFIG_PROC_FS
-static struct list_head *xt_get_idx(struct list_head *list, struct seq_file *seq, loff_t pos)
+struct xt_names_priv {
+ struct seq_net_private p;
+ int af;
+};
+static void *xt_table_seq_start(struct seq_file *seq, loff_t *pos)
{
- struct list_head *head = list->next;
+ struct xt_names_priv *priv = seq->private;
+ struct net *net = priv->p.net;
+ int af = priv->af;
- if (!head || list_empty(list))
- return NULL;
+ mutex_lock(&xt[af].mutex);
+ return seq_list_start(&net->xt.tables[af], *pos);
+}
- while (pos && (head = head->next)) {
- if (head == list)
- return NULL;
- pos--;
- }
- return pos ? NULL : head;
-}
-
-static struct list_head *type2list(u_int16_t af, u_int16_t type)
-{
- struct list_head *list;
-
- switch (type) {
- case TARGET:
- list = &xt[af].target;
- break;
- case MATCH:
- list = &xt[af].match;
- break;
- case TABLE:
- list = &xt[af].tables;
- break;
- default:
- list = NULL;
- break;
- }
+static void *xt_table_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct xt_names_priv *priv = seq->private;
+ struct net *net = priv->p.net;
+ int af = priv->af;
- return list;
+ return seq_list_next(v, &net->xt.tables[af], pos);
}
-static void *xt_tgt_seq_start(struct seq_file *seq, loff_t *pos)
+static void xt_table_seq_stop(struct seq_file *seq, void *v)
{
- struct proc_dir_entry *pde = (struct proc_dir_entry *) seq->private;
- u_int16_t af = (unsigned long)pde->data & 0xffff;
- u_int16_t type = (unsigned long)pde->data >> 16;
- struct list_head *list;
+ struct xt_names_priv *priv = seq->private;
+ int af = priv->af;
- if (af >= NPROTO)
- return NULL;
+ mutex_unlock(&xt[af].mutex);
+}
- list = type2list(af, type);
- if (!list)
- return NULL;
+static int xt_table_seq_show(struct seq_file *seq, void *v)
+{
+ struct xt_table *table = list_entry(v, struct xt_table, list);
- if (mutex_lock_interruptible(&xt[af].mutex) != 0)
- return NULL;
+ if (strlen(table->name))
+ return seq_printf(seq, "%s\n", table->name);
+ else
+ return 0;
+}
+
+static const struct seq_operations xt_table_seq_ops = {
+ .start = xt_table_seq_start,
+ .next = xt_table_seq_next,
+ .stop = xt_table_seq_stop,
+ .show = xt_table_seq_show,
+};
- return xt_get_idx(list, seq, *pos);
+static int xt_table_open(struct inode *inode, struct file *file)
+{
+ int ret;
+ struct xt_names_priv *priv;
+
+ ret = seq_open_net(inode, file, &xt_table_seq_ops,
+ sizeof(struct xt_names_priv));
+ if (!ret) {
+ priv = ((struct seq_file *)file->private_data)->private;
+ priv->af = (unsigned long)PDE(inode)->data;
+ }
+ return ret;
}
-static void *xt_tgt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+static const struct file_operations xt_table_ops = {
+ .owner = THIS_MODULE,
+ .open = xt_table_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos)
{
- struct proc_dir_entry *pde = seq->private;
- u_int16_t af = (unsigned long)pde->data & 0xffff;
- u_int16_t type = (unsigned long)pde->data >> 16;
- struct list_head *list;
+ struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
+ u_int16_t af = (unsigned long)pde->data;
- if (af >= NPROTO)
- return NULL;
+ mutex_lock(&xt[af].mutex);
+ return seq_list_start(&xt[af].match, *pos);
+}
- list = type2list(af, type);
- if (!list)
- return NULL;
+static void *xt_match_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
+ u_int16_t af = (unsigned long)pde->data;
- (*pos)++;
- return xt_get_idx(list, seq, *pos);
+ return seq_list_next(v, &xt[af].match, pos);
}
-static void xt_tgt_seq_stop(struct seq_file *seq, void *v)
+static void xt_match_seq_stop(struct seq_file *seq, void *v)
{
struct proc_dir_entry *pde = seq->private;
- u_int16_t af = (unsigned long)pde->data & 0xffff;
+ u_int16_t af = (unsigned long)pde->data;
mutex_unlock(&xt[af].mutex);
}
-static int xt_name_seq_show(struct seq_file *seq, void *v)
+static int xt_match_seq_show(struct seq_file *seq, void *v)
{
- char *name = (char *)v + sizeof(struct list_head);
+ struct xt_match *match = list_entry(v, struct xt_match, list);
- if (strlen(name))
- return seq_printf(seq, "%s\n", name);
+ if (strlen(match->name))
+ return seq_printf(seq, "%s\n", match->name);
else
return 0;
}
-static const struct seq_operations xt_tgt_seq_ops = {
- .start = xt_tgt_seq_start,
- .next = xt_tgt_seq_next,
- .stop = xt_tgt_seq_stop,
- .show = xt_name_seq_show,
+static const struct seq_operations xt_match_seq_ops = {
+ .start = xt_match_seq_start,
+ .next = xt_match_seq_next,
+ .stop = xt_match_seq_stop,
+ .show = xt_match_seq_show,
};
-static int xt_tgt_open(struct inode *inode, struct file *file)
+static int xt_match_open(struct inode *inode, struct file *file)
{
int ret;
- ret = seq_open(file, &xt_tgt_seq_ops);
+ ret = seq_open(file, &xt_match_seq_ops);
if (!ret) {
struct seq_file *seq = file->private_data;
- struct proc_dir_entry *pde = PDE(inode);
- seq->private = pde;
+ seq->private = PDE(inode);
}
+ return ret;
+}
+
+static const struct file_operations xt_match_ops = {
+ .owner = THIS_MODULE,
+ .open = xt_match_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static void *xt_target_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
+ u_int16_t af = (unsigned long)pde->data;
+
+ mutex_lock(&xt[af].mutex);
+ return seq_list_start(&xt[af].target, *pos);
+}
+
+static void *xt_target_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
+ u_int16_t af = (unsigned long)pde->data;
+
+ return seq_list_next(v, &xt[af].target, pos);
+}
+
+static void xt_target_seq_stop(struct seq_file *seq, void *v)
+{
+ struct proc_dir_entry *pde = seq->private;
+ u_int16_t af = (unsigned long)pde->data;
+
+ mutex_unlock(&xt[af].mutex);
+}
+static int xt_target_seq_show(struct seq_file *seq, void *v)
+{
+ struct xt_target *target = list_entry(v, struct xt_target, list);
+
+ if (strlen(target->name))
+ return seq_printf(seq, "%s\n", target->name);
+ else
+ return 0;
+}
+
+static const struct seq_operations xt_target_seq_ops = {
+ .start = xt_target_seq_start,
+ .next = xt_target_seq_next,
+ .stop = xt_target_seq_stop,
+ .show = xt_target_seq_show,
+};
+
+static int xt_target_open(struct inode *inode, struct file *file)
+{
+ int ret;
+
+ ret = seq_open(file, &xt_target_seq_ops);
+ if (!ret) {
+ struct seq_file *seq = file->private_data;
+
+ seq->private = PDE(inode);
+ }
return ret;
}
-static const struct file_operations xt_file_ops = {
+static const struct file_operations xt_target_ops = {
.owner = THIS_MODULE,
- .open = xt_tgt_open,
+ .open = xt_target_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
@@ -844,7 +922,7 @@ static const struct file_operations xt_file_ops = {
#endif /* CONFIG_PROC_FS */
-int xt_proto_init(int af)
+int xt_proto_init(struct net *net, int af)
{
#ifdef CONFIG_PROC_FS
char buf[XT_FUNCTION_MAXNAMELEN];
@@ -858,25 +936,25 @@ int xt_proto_init(int af)
#ifdef CONFIG_PROC_FS
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TABLES, sizeof(buf));
- proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
+ proc = proc_net_fops_create(net, buf, 0440, &xt_table_ops);
if (!proc)
goto out;
- proc->data = (void *) ((unsigned long) af | (TABLE << 16));
+ proc->data = (void *)(unsigned long)af;
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
- proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
+ proc = proc_net_fops_create(net, buf, 0440, &xt_match_ops);
if (!proc)
goto out_remove_tables;
- proc->data = (void *) ((unsigned long) af | (MATCH << 16));
+ proc->data = (void *)(unsigned long)af;
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
- proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
+ proc = proc_net_fops_create(net, buf, 0440, &xt_target_ops);
if (!proc)
goto out_remove_matches;
- proc->data = (void *) ((unsigned long) af | (TARGET << 16));
+ proc->data = (void *)(unsigned long)af;
#endif
return 0;
@@ -885,42 +963,54 @@ int xt_proto_init(int af)
out_remove_matches:
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
- proc_net_remove(&init_net, buf);
+ proc_net_remove(net, buf);
out_remove_tables:
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TABLES, sizeof(buf));
- proc_net_remove(&init_net, buf);
+ proc_net_remove(net, buf);
out:
return -1;
#endif
}
EXPORT_SYMBOL_GPL(xt_proto_init);
-void xt_proto_fini(int af)
+void xt_proto_fini(struct net *net, int af)
{
#ifdef CONFIG_PROC_FS
char buf[XT_FUNCTION_MAXNAMELEN];
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TABLES, sizeof(buf));
- proc_net_remove(&init_net, buf);
+ proc_net_remove(net, buf);
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
- proc_net_remove(&init_net, buf);
+ proc_net_remove(net, buf);
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
- proc_net_remove(&init_net, buf);
+ proc_net_remove(net, buf);
#endif /*CONFIG_PROC_FS*/
}
EXPORT_SYMBOL_GPL(xt_proto_fini);
+static int __net_init xt_net_init(struct net *net)
+{
+ int i;
+
+ for (i = 0; i < NPROTO; i++)
+ INIT_LIST_HEAD(&net->xt.tables[i]);
+ return 0;
+}
+
+static struct pernet_operations xt_net_ops = {
+ .init = xt_net_init,
+};
static int __init xt_init(void)
{
- int i;
+ int i, rv;
xt = kmalloc(sizeof(struct xt_af) * NPROTO, GFP_KERNEL);
if (!xt)
@@ -934,13 +1024,16 @@ static int __init xt_init(void)
#endif
INIT_LIST_HEAD(&xt[i].target);
INIT_LIST_HEAD(&xt[i].match);
- INIT_LIST_HEAD(&xt[i].tables);
}
- return 0;
+ rv = register_pernet_subsys(&xt_net_ops);
+ if (rv < 0)
+ kfree(xt);
+ return rv;
}
static void __exit xt_fini(void)
{
+ unregister_pernet_subsys(&xt_net_ops);
kfree(xt);
}
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index 60e3767cc71..217e2b68632 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -13,7 +13,10 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/tcp.h>
+#include <net/dst.h>
+#include <net/flow.h>
#include <net/ipv6.h>
+#include <net/route.h>
#include <net/tcp.h>
#include <linux/netfilter_ipv4/ip_tables.h>
@@ -41,6 +44,7 @@ optlen(const u_int8_t *opt, unsigned int offset)
static int
tcpmss_mangle_packet(struct sk_buff *skb,
const struct xt_tcpmss_info *info,
+ unsigned int in_mtu,
unsigned int tcphoff,
unsigned int minlen)
{
@@ -76,7 +80,13 @@ tcpmss_mangle_packet(struct sk_buff *skb,
dst_mtu(skb->dst));
return -1;
}
- newmss = dst_mtu(skb->dst) - minlen;
+ if (in_mtu <= minlen) {
+ if (net_ratelimit())
+ printk(KERN_ERR "xt_TCPMSS: unknown or "
+ "invalid path-MTU (%u)\n", in_mtu);
+ return -1;
+ }
+ newmss = min(dst_mtu(skb->dst), in_mtu) - minlen;
} else
newmss = info->mss;
@@ -137,6 +147,28 @@ tcpmss_mangle_packet(struct sk_buff *skb,
return TCPOLEN_MSS;
}
+static u_int32_t tcpmss_reverse_mtu4(const struct iphdr *iph)
+{
+ struct flowi fl = {
+ .fl4_dst = iph->saddr,
+ };
+ const struct nf_afinfo *ai;
+ struct rtable *rt = NULL;
+ u_int32_t mtu = ~0U;
+
+ rcu_read_lock();
+ ai = nf_get_afinfo(AF_INET);
+ if (ai != NULL)
+ ai->route((struct dst_entry **)&rt, &fl);
+ rcu_read_unlock();
+
+ if (rt != NULL) {
+ mtu = dst_mtu(&rt->u.dst);
+ dst_release(&rt->u.dst);
+ }
+ return mtu;
+}
+
static unsigned int
tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
@@ -146,7 +178,8 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
__be16 newlen;
int ret;
- ret = tcpmss_mangle_packet(skb, targinfo, iph->ihl * 4,
+ ret = tcpmss_mangle_packet(skb, targinfo, tcpmss_reverse_mtu4(iph),
+ iph->ihl * 4,
sizeof(*iph) + sizeof(struct tcphdr));
if (ret < 0)
return NF_DROP;
@@ -160,6 +193,28 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
}
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+static u_int32_t tcpmss_reverse_mtu6(const struct ipv6hdr *iph)
+{
+ struct flowi fl = {
+ .fl6_dst = iph->saddr,
+ };
+ const struct nf_afinfo *ai;
+ struct rtable *rt = NULL;
+ u_int32_t mtu = ~0U;
+
+ rcu_read_lock();
+ ai = nf_get_afinfo(AF_INET6);
+ if (ai != NULL)
+ ai->route((struct dst_entry **)&rt, &fl);
+ rcu_read_unlock();
+
+ if (rt != NULL) {
+ mtu = dst_mtu(&rt->u.dst);
+ dst_release(&rt->u.dst);
+ }
+ return mtu;
+}
+
static unsigned int
tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
@@ -174,7 +229,8 @@ tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr);
if (tcphoff < 0)
return NF_DROP;
- ret = tcpmss_mangle_packet(skb, targinfo, tcphoff,
+ ret = tcpmss_mangle_packet(skb, targinfo, tcpmss_reverse_mtu6(ipv6h),
+ tcphoff,
sizeof(*ipv6h) + sizeof(struct tcphdr));
if (ret < 0)
return NF_DROP;
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index e00ecd974fa..3b0111933f6 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -120,11 +120,11 @@ static int count_them(struct xt_connlimit_data *data,
else
hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)];
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
/* check the saved connections */
list_for_each_entry_safe(conn, tmp, hash, list) {
- found = __nf_conntrack_find(&conn->tuple, NULL);
+ found = __nf_conntrack_find(&conn->tuple);
found_ct = NULL;
if (found != NULL)
@@ -163,7 +163,7 @@ static int count_them(struct xt_connlimit_data *data,
++matches;
}
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
if (addit) {
/* save the new connection in our list */
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index e92190eafcc..85330856a29 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -4,7 +4,6 @@
*
* (C) 2001 Marc Boucher (marc@mbsi.ca).
* Copyright © CC Computer Consultants GmbH, 2007 - 2008
- * Jan Engelhardt <jengelh@computergmbh.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -20,6 +19,7 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
MODULE_DESCRIPTION("Xtables: connection tracking state match");
MODULE_ALIAS("ipt_conntrack");
MODULE_ALIAS("ip6t_conntrack");
@@ -166,6 +166,44 @@ conntrack_mt_repldst(const struct nf_conn *ct,
&info->repldst_addr, &info->repldst_mask, family);
}
+static inline bool
+ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info,
+ const struct nf_conn *ct)
+{
+ const struct nf_conntrack_tuple *tuple;
+
+ tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
+ if ((info->match_flags & XT_CONNTRACK_PROTO) &&
+ (tuple->dst.protonum == info->l4proto) ^
+ !(info->invert_flags & XT_CONNTRACK_PROTO))
+ return false;
+
+ /* Shortcut to match all recognized protocols by using ->src.all. */
+ if ((info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) &&
+ (tuple->src.u.all == info->origsrc_port) ^
+ !(info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT))
+ return false;
+
+ if ((info->match_flags & XT_CONNTRACK_ORIGDST_PORT) &&
+ (tuple->dst.u.all == info->origdst_port) ^
+ !(info->invert_flags & XT_CONNTRACK_ORIGDST_PORT))
+ return false;
+
+ tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+
+ if ((info->match_flags & XT_CONNTRACK_REPLSRC_PORT) &&
+ (tuple->src.u.all == info->replsrc_port) ^
+ !(info->invert_flags & XT_CONNTRACK_REPLSRC_PORT))
+ return false;
+
+ if ((info->match_flags & XT_CONNTRACK_REPLDST_PORT) &&
+ (tuple->dst.u.all == info->repldst_port) ^
+ !(info->invert_flags & XT_CONNTRACK_REPLDST_PORT))
+ return false;
+
+ return true;
+}
+
static bool
conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
@@ -200,10 +238,9 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
if (ct == NULL)
return info->match_flags & XT_CONNTRACK_STATE;
-
- if ((info->match_flags & XT_CONNTRACK_PROTO) &&
- ((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
- info->l4proto) ^ !(info->invert_flags & XT_CONNTRACK_PROTO)))
+ if ((info->match_flags & XT_CONNTRACK_DIRECTION) &&
+ (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) ^
+ !!(info->invert_flags & XT_CONNTRACK_DIRECTION))
return false;
if (info->match_flags & XT_CONNTRACK_ORIGSRC)
@@ -226,6 +263,9 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
!(info->invert_flags & XT_CONNTRACK_REPLDST))
return false;
+ if (!ct_proto_port_check(info, ct))
+ return false;
+
if ((info->match_flags & XT_CONNTRACK_STATUS) &&
(!!(info->status_mask & ct->status) ^
!(info->invert_flags & XT_CONNTRACK_STATUS)))
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index d479ca98011..744c7f2ab0b 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -1,9 +1,9 @@
-/* iptables match extension to limit the number of packets per second
- * seperately for each hashbucket (sourceip/sourceport/dstip/dstport)
+/*
+ * xt_hashlimit - Netfilter module to limit the number of packets per time
+ * seperately for each hashbucket (sourceip/sourceport/dstip/dstport)
*
- * (C) 2003-2004 by Harald Welte <laforge@netfilter.org>
- *
- * $Id: ipt_hashlimit.c 3244 2004-10-20 16:24:29Z laforge@netfilter.org $
+ * (C) 2003-2004 by Harald Welte <laforge@netfilter.org>
+ * Copyright © CC Computer Consultants GmbH, 2007 - 2008
*
* Development of this code was funded by Astaro AG, http://www.astaro.com/
*/
@@ -35,6 +35,7 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
MODULE_DESCRIPTION("Xtables: per hash-bucket rate-limit match");
MODULE_ALIAS("ipt_hashlimit");
MODULE_ALIAS("ip6t_hashlimit");
@@ -57,7 +58,7 @@ struct dsthash_dst {
__be32 dst[4];
} ip6;
#endif
- } addr;
+ };
__be16 src_port;
__be16 dst_port;
};
@@ -81,7 +82,7 @@ struct xt_hashlimit_htable {
atomic_t use;
int family;
- struct hashlimit_cfg cfg; /* config */
+ struct hashlimit_cfg1 cfg; /* config */
/* used internally */
spinlock_t lock; /* lock for list_head */
@@ -184,7 +185,7 @@ dsthash_free(struct xt_hashlimit_htable *ht, struct dsthash_ent *ent)
}
static void htable_gc(unsigned long htlong);
-static int htable_create(struct xt_hashlimit_info *minfo, int family)
+static int htable_create_v0(struct xt_hashlimit_info *minfo, int family)
{
struct xt_hashlimit_htable *hinfo;
unsigned int size;
@@ -210,7 +211,18 @@ static int htable_create(struct xt_hashlimit_info *minfo, int family)
minfo->hinfo = hinfo;
/* copy match config into hashtable config */
- memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
+ hinfo->cfg.mode = minfo->cfg.mode;
+ hinfo->cfg.avg = minfo->cfg.avg;
+ hinfo->cfg.burst = minfo->cfg.burst;
+ hinfo->cfg.max = minfo->cfg.max;
+ hinfo->cfg.gc_interval = minfo->cfg.gc_interval;
+ hinfo->cfg.expire = minfo->cfg.expire;
+
+ if (family == AF_INET)
+ hinfo->cfg.srcmask = hinfo->cfg.dstmask = 32;
+ else
+ hinfo->cfg.srcmask = hinfo->cfg.dstmask = 128;
+
hinfo->cfg.size = size;
if (!hinfo->cfg.max)
hinfo->cfg.max = 8 * hinfo->cfg.size;
@@ -246,6 +258,70 @@ static int htable_create(struct xt_hashlimit_info *minfo, int family)
return 0;
}
+static int htable_create(struct xt_hashlimit_mtinfo1 *minfo,
+ unsigned int family)
+{
+ struct xt_hashlimit_htable *hinfo;
+ unsigned int size;
+ unsigned int i;
+
+ if (minfo->cfg.size) {
+ size = minfo->cfg.size;
+ } else {
+ size = (num_physpages << PAGE_SHIFT) / 16384 /
+ sizeof(struct list_head);
+ if (num_physpages > 1024 * 1024 * 1024 / PAGE_SIZE)
+ size = 8192;
+ if (size < 16)
+ size = 16;
+ }
+ /* FIXME: don't use vmalloc() here or anywhere else -HW */
+ hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) +
+ sizeof(struct list_head) * size);
+ if (hinfo == NULL) {
+ printk(KERN_ERR "xt_hashlimit: unable to create hashtable\n");
+ return -1;
+ }
+ minfo->hinfo = hinfo;
+
+ /* copy match config into hashtable config */
+ memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
+ hinfo->cfg.size = size;
+ if (hinfo->cfg.max == 0)
+ hinfo->cfg.max = 8 * hinfo->cfg.size;
+ else if (hinfo->cfg.max < hinfo->cfg.size)
+ hinfo->cfg.max = hinfo->cfg.size;
+
+ for (i = 0; i < hinfo->cfg.size; i++)
+ INIT_HLIST_HEAD(&hinfo->hash[i]);
+
+ atomic_set(&hinfo->use, 1);
+ hinfo->count = 0;
+ hinfo->family = family;
+ hinfo->rnd_initialized = 0;
+ spin_lock_init(&hinfo->lock);
+
+ hinfo->pde = create_proc_entry(minfo->name, 0,
+ family == AF_INET ? hashlimit_procdir4 :
+ hashlimit_procdir6);
+ if (hinfo->pde == NULL) {
+ vfree(hinfo);
+ return -1;
+ }
+ hinfo->pde->proc_fops = &dl_file_ops;
+ hinfo->pde->data = hinfo;
+
+ setup_timer(&hinfo->timer, htable_gc, (unsigned long)hinfo);
+ hinfo->timer.expires = jiffies + msecs_to_jiffies(hinfo->cfg.gc_interval);
+ add_timer(&hinfo->timer);
+
+ spin_lock_bh(&hashlimit_lock);
+ hlist_add_head(&hinfo->node, &hashlimit_htables);
+ spin_unlock_bh(&hashlimit_lock);
+
+ return 0;
+}
+
static bool select_all(const struct xt_hashlimit_htable *ht,
const struct dsthash_ent *he)
{
@@ -388,6 +464,48 @@ static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
dh->rateinfo.prev = now;
}
+static inline __be32 maskl(__be32 a, unsigned int l)
+{
+ return htonl(ntohl(a) & ~(~(u_int32_t)0 >> l));
+}
+
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+static void hashlimit_ipv6_mask(__be32 *i, unsigned int p)
+{
+ switch (p) {
+ case 0:
+ i[0] = i[1] = 0;
+ i[2] = i[3] = 0;
+ break;
+ case 1 ... 31:
+ i[0] = maskl(i[0], p);
+ i[1] = i[2] = i[3] = 0;
+ break;
+ case 32:
+ i[1] = i[2] = i[3] = 0;
+ break;
+ case 33 ... 63:
+ i[1] = maskl(i[1], p - 32);
+ i[2] = i[3] = 0;
+ break;
+ case 64:
+ i[2] = i[3] = 0;
+ break;
+ case 65 ... 95:
+ i[2] = maskl(i[2], p - 64);
+ i[3] = 0;
+ case 96:
+ i[3] = 0;
+ break;
+ case 97 ... 127:
+ i[3] = maskl(i[3], p - 96);
+ break;
+ case 128:
+ break;
+ }
+}
+#endif
+
static int
hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
struct dsthash_dst *dst,
@@ -401,9 +519,11 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
switch (hinfo->family) {
case AF_INET:
if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP)
- dst->addr.ip.dst = ip_hdr(skb)->daddr;
+ dst->ip.dst = maskl(ip_hdr(skb)->daddr,
+ hinfo->cfg.dstmask);
if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP)
- dst->addr.ip.src = ip_hdr(skb)->saddr;
+ dst->ip.src = maskl(ip_hdr(skb)->saddr,
+ hinfo->cfg.srcmask);
if (!(hinfo->cfg.mode &
(XT_HASHLIMIT_HASH_DPT | XT_HASHLIMIT_HASH_SPT)))
@@ -412,12 +532,16 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
break;
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
case AF_INET6:
- if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP)
- memcpy(&dst->addr.ip6.dst, &ipv6_hdr(skb)->daddr,
- sizeof(dst->addr.ip6.dst));
- if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP)
- memcpy(&dst->addr.ip6.src, &ipv6_hdr(skb)->saddr,
- sizeof(dst->addr.ip6.src));
+ if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP) {
+ memcpy(&dst->ip6.dst, &ipv6_hdr(skb)->daddr,
+ sizeof(dst->ip6.dst));
+ hashlimit_ipv6_mask(dst->ip6.dst, hinfo->cfg.dstmask);
+ }
+ if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP) {
+ memcpy(&dst->ip6.src, &ipv6_hdr(skb)->saddr,
+ sizeof(dst->ip6.src));
+ hashlimit_ipv6_mask(dst->ip6.src, hinfo->cfg.srcmask);
+ }
if (!(hinfo->cfg.mode &
(XT_HASHLIMIT_HASH_DPT | XT_HASHLIMIT_HASH_SPT)))
@@ -457,10 +581,10 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
}
static bool
-hashlimit_mt(const struct sk_buff *skb, const struct net_device *in,
- const struct net_device *out, const struct xt_match *match,
- const void *matchinfo, int offset, unsigned int protoff,
- bool *hotdrop)
+hashlimit_mt_v0(const struct sk_buff *skb, const struct net_device *in,
+ const struct net_device *out, const struct xt_match *match,
+ const void *matchinfo, int offset, unsigned int protoff,
+ bool *hotdrop)
{
const struct xt_hashlimit_info *r =
((const struct xt_hashlimit_info *)matchinfo)->u.master;
@@ -512,9 +636,62 @@ hotdrop:
}
static bool
-hashlimit_mt_check(const char *tablename, const void *inf,
- const struct xt_match *match, void *matchinfo,
- unsigned int hook_mask)
+hashlimit_mt(const struct sk_buff *skb, const struct net_device *in,
+ const struct net_device *out, const struct xt_match *match,
+ const void *matchinfo, int offset, unsigned int protoff,
+ bool *hotdrop)
+{
+ const struct xt_hashlimit_mtinfo1 *info = matchinfo;
+ struct xt_hashlimit_htable *hinfo = info->hinfo;
+ unsigned long now = jiffies;
+ struct dsthash_ent *dh;
+ struct dsthash_dst dst;
+
+ if (hashlimit_init_dst(hinfo, &dst, skb, protoff) < 0)
+ goto hotdrop;
+
+ spin_lock_bh(&hinfo->lock);
+ dh = dsthash_find(hinfo, &dst);
+ if (dh == NULL) {
+ dh = dsthash_alloc_init(hinfo, &dst);
+ if (dh == NULL) {
+ spin_unlock_bh(&hinfo->lock);
+ goto hotdrop;
+ }
+
+ dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire);
+ dh->rateinfo.prev = jiffies;
+ dh->rateinfo.credit = user2credits(hinfo->cfg.avg *
+ hinfo->cfg.burst);
+ dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg *
+ hinfo->cfg.burst);
+ dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
+ } else {
+ /* update expiration timeout */
+ dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire);
+ rateinfo_recalc(dh, now);
+ }
+
+ if (dh->rateinfo.credit >= dh->rateinfo.cost) {
+ /* below the limit */
+ dh->rateinfo.credit -= dh->rateinfo.cost;
+ spin_unlock_bh(&hinfo->lock);
+ return !(info->cfg.mode & XT_HASHLIMIT_INVERT);
+ }
+
+ spin_unlock_bh(&hinfo->lock);
+ /* default match is underlimit - so over the limit, we need to invert */
+ return info->cfg.mode & XT_HASHLIMIT_INVERT;
+
+ hotdrop:
+ *hotdrop = true;
+ return false;
+}
+
+static bool
+hashlimit_mt_check_v0(const char *tablename, const void *inf,
+ const struct xt_match *match, void *matchinfo,
+ unsigned int hook_mask)
{
struct xt_hashlimit_info *r = matchinfo;
@@ -546,7 +723,7 @@ hashlimit_mt_check(const char *tablename, const void *inf,
* create duplicate proc files. -HW */
mutex_lock(&hlimit_mutex);
r->hinfo = htable_find_get(r->name, match->family);
- if (!r->hinfo && htable_create(r, match->family) != 0) {
+ if (!r->hinfo && htable_create_v0(r, match->family) != 0) {
mutex_unlock(&hlimit_mutex);
return false;
}
@@ -557,14 +734,68 @@ hashlimit_mt_check(const char *tablename, const void *inf,
return true;
}
+static bool
+hashlimit_mt_check(const char *tablename, const void *inf,
+ const struct xt_match *match, void *matchinfo,
+ unsigned int hook_mask)
+{
+ struct xt_hashlimit_mtinfo1 *info = matchinfo;
+
+ /* Check for overflow. */
+ if (info->cfg.burst == 0 ||
+ user2credits(info->cfg.avg * info->cfg.burst) <
+ user2credits(info->cfg.avg)) {
+ printk(KERN_ERR "xt_hashlimit: overflow, try lower: %u/%u\n",
+ info->cfg.avg, info->cfg.burst);
+ return false;
+ }
+ if (info->cfg.gc_interval == 0 || info->cfg.expire == 0)
+ return false;
+ if (info->name[sizeof(info->name)-1] != '\0')
+ return false;
+ if (match->family == AF_INET) {
+ if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32)
+ return false;
+ } else {
+ if (info->cfg.srcmask > 128 || info->cfg.dstmask > 128)
+ return false;
+ }
+
+ /* This is the best we've got: We cannot release and re-grab lock,
+ * since checkentry() is called before x_tables.c grabs xt_mutex.
+ * We also cannot grab the hashtable spinlock, since htable_create will
+ * call vmalloc, and that can sleep. And we cannot just re-search
+ * the list of htable's in htable_create(), since then we would
+ * create duplicate proc files. -HW */
+ mutex_lock(&hlimit_mutex);
+ info->hinfo = htable_find_get(info->name, match->family);
+ if (!info->hinfo && htable_create(info, match->family) != 0) {
+ mutex_unlock(&hlimit_mutex);
+ return false;
+ }
+ mutex_unlock(&hlimit_mutex);
+
+ /* Ugly hack: For SMP, we only want to use one set */
+ info->master = info;
+ return true;
+}
+
static void
-hashlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
+hashlimit_mt_destroy_v0(const struct xt_match *match, void *matchinfo)
{
const struct xt_hashlimit_info *r = matchinfo;
htable_put(r->hinfo);
}
+static void
+hashlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
+{
+ const struct xt_hashlimit_mtinfo1 *info = matchinfo;
+
+ htable_put(info->hinfo);
+}
+
#ifdef CONFIG_COMPAT
struct compat_xt_hashlimit_info {
char name[IFNAMSIZ];
@@ -592,38 +823,60 @@ static int hashlimit_mt_compat_to_user(void __user *dst, void *src)
static struct xt_match hashlimit_mt_reg[] __read_mostly = {
{
.name = "hashlimit",
+ .revision = 0,
.family = AF_INET,
- .match = hashlimit_mt,
+ .match = hashlimit_mt_v0,
.matchsize = sizeof(struct xt_hashlimit_info),
#ifdef CONFIG_COMPAT
.compatsize = sizeof(struct compat_xt_hashlimit_info),
.compat_from_user = hashlimit_mt_compat_from_user,
.compat_to_user = hashlimit_mt_compat_to_user,
#endif
- .checkentry = hashlimit_mt_check,
- .destroy = hashlimit_mt_destroy,
+ .checkentry = hashlimit_mt_check_v0,
+ .destroy = hashlimit_mt_destroy_v0,
.me = THIS_MODULE
},
+ {
+ .name = "hashlimit",
+ .revision = 1,
+ .family = AF_INET,
+ .match = hashlimit_mt,
+ .matchsize = sizeof(struct xt_hashlimit_mtinfo1),
+ .checkentry = hashlimit_mt_check,
+ .destroy = hashlimit_mt_destroy,
+ .me = THIS_MODULE,
+ },
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
{
.name = "hashlimit",
.family = AF_INET6,
- .match = hashlimit_mt,
+ .match = hashlimit_mt_v0,
.matchsize = sizeof(struct xt_hashlimit_info),
#ifdef CONFIG_COMPAT
.compatsize = sizeof(struct compat_xt_hashlimit_info),
.compat_from_user = hashlimit_mt_compat_from_user,
.compat_to_user = hashlimit_mt_compat_to_user,
#endif
- .checkentry = hashlimit_mt_check,
- .destroy = hashlimit_mt_destroy,
+ .checkentry = hashlimit_mt_check_v0,
+ .destroy = hashlimit_mt_destroy_v0,
.me = THIS_MODULE
},
+ {
+ .name = "hashlimit",
+ .revision = 1,
+ .family = AF_INET6,
+ .match = hashlimit_mt,
+ .matchsize = sizeof(struct xt_hashlimit_mtinfo1),
+ .checkentry = hashlimit_mt_check,
+ .destroy = hashlimit_mt_destroy,
+ .me = THIS_MODULE,
+ },
#endif
};
/* PROC stuff */
static void *dl_seq_start(struct seq_file *s, loff_t *pos)
+ __acquires(htable->lock)
{
struct proc_dir_entry *pde = s->private;
struct xt_hashlimit_htable *htable = pde->data;
@@ -656,6 +909,7 @@ static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
}
static void dl_seq_stop(struct seq_file *s, void *v)
+ __releases(htable->lock)
{
struct proc_dir_entry *pde = s->private;
struct xt_hashlimit_htable *htable = pde->data;
@@ -676,9 +930,9 @@ static int dl_seq_real_show(struct dsthash_ent *ent, int family,
return seq_printf(s, "%ld %u.%u.%u.%u:%u->"
"%u.%u.%u.%u:%u %u %u %u\n",
(long)(ent->expires - jiffies)/HZ,
- NIPQUAD(ent->dst.addr.ip.src),
+ NIPQUAD(ent->dst.ip.src),
ntohs(ent->dst.src_port),
- NIPQUAD(ent->dst.addr.ip.dst),
+ NIPQUAD(ent->dst.ip.dst),
ntohs(ent->dst.dst_port),
ent->rateinfo.credit, ent->rateinfo.credit_cap,
ent->rateinfo.cost);
@@ -687,9 +941,9 @@ static int dl_seq_real_show(struct dsthash_ent *ent, int family,
return seq_printf(s, "%ld " NIP6_FMT ":%u->"
NIP6_FMT ":%u %u %u %u\n",
(long)(ent->expires - jiffies)/HZ,
- NIP6(*(struct in6_addr *)&ent->dst.addr.ip6.src),
+ NIP6(*(struct in6_addr *)&ent->dst.ip6.src),
ntohs(ent->dst.src_port),
- NIP6(*(struct in6_addr *)&ent->dst.addr.ip6.dst),
+ NIP6(*(struct in6_addr *)&ent->dst.ip6.dst),
ntohs(ent->dst.dst_port),
ent->rateinfo.credit, ent->rateinfo.credit_cap,
ent->rateinfo.cost);
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
index dbea0e0893f..01035fc0e14 100644
--- a/net/netfilter/xt_iprange.c
+++ b/net/netfilter/xt_iprange.c
@@ -101,7 +101,7 @@ iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b)
int r;
for (i = 0; i < 4; ++i) {
- r = a->s6_addr32[i] - b->s6_addr32[i];
+ r = (__force u32)a->s6_addr32[i] - (__force u32)b->s6_addr32[i];
if (r != 0)
return r;
}
diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
index d382f9cc38b..9059c16144c 100644
--- a/net/netfilter/xt_owner.c
+++ b/net/netfilter/xt_owner.c
@@ -4,8 +4,8 @@
*
* (C) 2000 Marc Boucher <marc@mbsi.ca>
*
- * Copyright © CC Computer Consultants GmbH, 2007
- * Contact: <jengelh@computergmbh.de>
+ * Copyright © CC Computer Consultants GmbH, 2007 - 2008
+ * <jengelh@computergmbh.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -102,13 +102,15 @@ owner_mt(const struct sk_buff *skb, const struct net_device *in,
(XT_OWNER_UID | XT_OWNER_GID)) == 0;
if (info->match & XT_OWNER_UID)
- if ((filp->f_uid != info->uid) ^
- !!(info->invert & XT_OWNER_UID))
+ if ((filp->f_uid >= info->uid_min &&
+ filp->f_uid <= info->uid_max) ^
+ !(info->invert & XT_OWNER_UID))
return false;
if (info->match & XT_OWNER_GID)
- if ((filp->f_gid != info->gid) ^
- !!(info->invert & XT_OWNER_GID))
+ if ((filp->f_gid >= info->gid_min &&
+ filp->f_gid <= info->gid_max) ^
+ !(info->invert & XT_OWNER_GID))
return false;
return true;
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 6b178e1247b..ff9fb6ba0c5 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1344,6 +1344,22 @@ static void netlink_data_ready(struct sock *sk, int len)
* queueing.
*/
+static void __netlink_release(struct sock *sk)
+{
+ /*
+ * Last sock_put should drop referrence to sk->sk_net. It has already
+ * been dropped in netlink_kernel_create. Taking referrence to stopping
+ * namespace is not an option.
+ * Take referrence to a socket to remove it from netlink lookup table
+ * _alive_ and after that destroy it in the context of init_net.
+ */
+
+ sock_hold(sk);
+ sock_release(sk->sk_socket);
+ sk->sk_net = get_net(&init_net);
+ sock_put(sk);
+}
+
struct sock *
netlink_kernel_create(struct net *net, int unit, unsigned int groups,
void (*input)(struct sk_buff *skb),
@@ -1362,8 +1378,18 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
return NULL;
- if (__netlink_create(net, sock, cb_mutex, unit) < 0)
- goto out_sock_release;
+ /*
+ * We have to just have a reference on the net from sk, but don't
+ * get_net it. Besides, we cannot get and then put the net here.
+ * So we create one inside init_net and the move it to net.
+ */
+
+ if (__netlink_create(&init_net, sock, cb_mutex, unit) < 0)
+ goto out_sock_release_nosk;
+
+ sk = sock->sk;
+ put_net(sk->sk_net);
+ sk->sk_net = net;
if (groups < 32)
groups = 32;
@@ -1372,7 +1398,6 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
if (!listeners)
goto out_sock_release;
- sk = sock->sk;
sk->sk_data_ready = netlink_data_ready;
if (input)
nlk_sk(sk)->netlink_rcv = input;
@@ -1395,14 +1420,14 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
nl_table[unit].registered++;
}
netlink_table_ungrab();
-
- /* Do not hold an extra referrence to a namespace as this socket is
- * internal to a namespace and does not prevent it to stop. */
- put_net(net);
return sk;
out_sock_release:
kfree(listeners);
+ __netlink_release(sk);
+ return NULL;
+
+out_sock_release_nosk:
sock_release(sock);
return NULL;
}
@@ -1415,18 +1440,7 @@ netlink_kernel_release(struct sock *sk)
if (sk == NULL || sk->sk_socket == NULL)
return;
- /*
- * Last sock_put should drop referrence to sk->sk_net. It has already
- * been dropped in netlink_kernel_create. Taking referrence to stopping
- * namespace is not an option.
- * Take referrence to a socket to remove it from netlink lookup table
- * _alive_ and after that destroy it in the context of init_net.
- */
- sock_hold(sk);
- sock_release(sk->sk_socket);
-
- sk->sk_net = get_net(&init_net);
- sock_put(sk);
+ __netlink_release(sk);
}
EXPORT_SYMBOL(netlink_kernel_release);
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index d1e9d68f8ba..e4b051dbed6 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -84,6 +84,7 @@ static void rfkill_schedule_toggle(struct rfkill_task *task)
static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN);
static DEFINE_RFKILL_TASK(rfkill_bt, RFKILL_TYPE_BLUETOOTH);
static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB);
+static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
static void rfkill_event(struct input_handle *handle, unsigned int type,
unsigned int code, int down)
@@ -99,6 +100,9 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
case KEY_UWB:
rfkill_schedule_toggle(&rfkill_uwb);
break;
+ case KEY_WIMAX:
+ rfkill_schedule_toggle(&rfkill_wimax);
+ break;
default:
break;
}
@@ -159,6 +163,11 @@ static const struct input_device_id rfkill_ids[] = {
.evbit = { BIT_MASK(EV_KEY) },
.keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },
},
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+ .evbit = { BIT_MASK(EV_KEY) },
+ .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
+ },
{ }
};
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index d06d338812e..6562f868e82 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -126,6 +126,9 @@ static ssize_t rfkill_type_show(struct device *dev,
case RFKILL_TYPE_UWB:
type = "ultrawideband";
break;
+ case RFKILL_TYPE_WIMAX:
+ type = "wimax";
+ break;
default:
BUG();
}
diff --git a/net/rxrpc/ar-call.c b/net/rxrpc/ar-call.c
index 3c04b00dab7..d9231245a79 100644
--- a/net/rxrpc/ar-call.c
+++ b/net/rxrpc/ar-call.c
@@ -15,7 +15,7 @@
#include <net/af_rxrpc.h>
#include "ar-internal.h"
-const char *rxrpc_call_states[] = {
+const char *const rxrpc_call_states[] = {
[RXRPC_CALL_CLIENT_SEND_REQUEST] = "ClSndReq",
[RXRPC_CALL_CLIENT_AWAIT_REPLY] = "ClAwtRpl",
[RXRPC_CALL_CLIENT_RECV_REPLY] = "ClRcvRpl",
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 58aaf892238..1aaa2e804b0 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -565,9 +565,9 @@ extern void __exit rxrpc_destroy_all_peers(void);
/*
* ar-proc.c
*/
-extern const char *rxrpc_call_states[];
-extern struct file_operations rxrpc_call_seq_fops;
-extern struct file_operations rxrpc_connection_seq_fops;
+extern const char *const rxrpc_call_states[];
+extern const struct file_operations rxrpc_call_seq_fops;
+extern const struct file_operations rxrpc_connection_seq_fops;
/*
* ar-recvmsg.c
diff --git a/net/rxrpc/ar-proc.c b/net/rxrpc/ar-proc.c
index 2e83ce325d1..83eda247fe4 100644
--- a/net/rxrpc/ar-proc.c
+++ b/net/rxrpc/ar-proc.c
@@ -14,7 +14,7 @@
#include <net/af_rxrpc.h>
#include "ar-internal.h"
-static const char *rxrpc_conn_states[] = {
+static const char *const rxrpc_conn_states[] = {
[RXRPC_CONN_UNUSED] = "Unused ",
[RXRPC_CONN_CLIENT] = "Client ",
[RXRPC_CONN_SERVER_UNSECURED] = "SvUnsec ",
@@ -98,7 +98,7 @@ static int rxrpc_call_seq_open(struct inode *inode, struct file *file)
return seq_open(file, &rxrpc_call_seq_ops);
}
-struct file_operations rxrpc_call_seq_fops = {
+const struct file_operations rxrpc_call_seq_fops = {
.owner = THIS_MODULE,
.open = rxrpc_call_seq_open,
.read = seq_read,
@@ -183,7 +183,7 @@ static int rxrpc_connection_seq_open(struct inode *inode, struct file *file)
return seq_open(file, &rxrpc_connection_seq_ops);
}
-struct file_operations rxrpc_connection_seq_fops = {
+const struct file_operations rxrpc_connection_seq_fops = {
.owner = THIS_MODULE,
.open = rxrpc_connection_seq_open,
.read = seq_read,
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 87af7c913d8..82adfe6447d 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -198,7 +198,7 @@ config NET_SCH_NETEM
config NET_SCH_INGRESS
tristate "Ingress Qdisc"
- depends on NET_CLS_ACT || NETFILTER
+ depends on NET_CLS_ACT
---help---
Say Y here if you want to use classifiers for incoming packets.
If unsure, say Y.
@@ -307,6 +307,17 @@ config NET_CLS_RSVP6
To compile this code as a module, choose M here: the
module will be called cls_rsvp6.
+config NET_CLS_FLOW
+ tristate "Flow classifier"
+ select NET_CLS
+ ---help---
+ If you say Y here, you will be able to classify packets based on
+ a configurable combination of packet keys. This is mostly useful
+ in combination with SFQ.
+
+ To compile this code as a module, choose M here: the
+ module will be called cls_flow.
+
config NET_EMATCH
bool "Extended Matches"
select NET_CLS
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 81ecbe8e7dc..1d2b0f7df84 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_NET_CLS_RSVP) += cls_rsvp.o
obj-$(CONFIG_NET_CLS_TCINDEX) += cls_tcindex.o
obj-$(CONFIG_NET_CLS_RSVP6) += cls_rsvp6.o
obj-$(CONFIG_NET_CLS_BASIC) += cls_basic.o
+obj-$(CONFIG_NET_CLS_FLOW) += cls_flow.o
obj-$(CONFIG_NET_EMATCH) += ematch.o
obj-$(CONFIG_NET_EMATCH_CMP) += em_cmp.o
obj-$(CONFIG_NET_EMATCH_NBYTE) += em_nbyte.o
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 3377ca0d0a0..0fbedcabf11 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -482,7 +482,7 @@ EXPORT_SYMBOL(tcf_exts_destroy);
int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
struct nlattr *rate_tlv, struct tcf_exts *exts,
- struct tcf_ext_map *map)
+ const struct tcf_ext_map *map)
{
memset(exts, 0, sizeof(*exts));
@@ -535,7 +535,7 @@ void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
EXPORT_SYMBOL(tcf_exts_change);
int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
- struct tcf_ext_map *map)
+ const struct tcf_ext_map *map)
{
#ifdef CONFIG_NET_CLS_ACT
if (map->action && exts->action) {
@@ -571,7 +571,7 @@ EXPORT_SYMBOL(tcf_exts_dump);
int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
- struct tcf_ext_map *map)
+ const struct tcf_ext_map *map)
{
#ifdef CONFIG_NET_CLS_ACT
if (exts->action)
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index bfb4342ea88..956915c217d 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -35,7 +35,7 @@ struct basic_filter
struct list_head link;
};
-static struct tcf_ext_map basic_ext_map = {
+static const struct tcf_ext_map basic_ext_map = {
.action = TCA_BASIC_ACT,
.police = TCA_BASIC_POLICE
};
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
new file mode 100644
index 00000000000..5a7f6a3060f
--- /dev/null
+++ b/net/sched/cls_flow.c
@@ -0,0 +1,660 @@
+/*
+ * net/sched/cls_flow.c Generic flow classifier
+ *
+ * Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/jhash.h>
+#include <linux/random.h>
+#include <linux/pkt_cls.h>
+#include <linux/skbuff.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+
+#include <net/pkt_cls.h>
+#include <net/ip.h>
+#include <net/route.h>
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+#include <net/netfilter/nf_conntrack.h>
+#endif
+
+struct flow_head {
+ struct list_head filters;
+};
+
+struct flow_filter {
+ struct list_head list;
+ struct tcf_exts exts;
+ struct tcf_ematch_tree ematches;
+ u32 handle;
+
+ u32 nkeys;
+ u32 keymask;
+ u32 mode;
+ u32 mask;
+ u32 xor;
+ u32 rshift;
+ u32 addend;
+ u32 divisor;
+ u32 baseclass;
+};
+
+static u32 flow_hashrnd __read_mostly;
+static int flow_hashrnd_initted __read_mostly;
+
+static const struct tcf_ext_map flow_ext_map = {
+ .action = TCA_FLOW_ACT,
+ .police = TCA_FLOW_POLICE,
+};
+
+static inline u32 addr_fold(void *addr)
+{
+ unsigned long a = (unsigned long)addr;
+
+ return (a & 0xFFFFFFFF) ^ (BITS_PER_LONG > 32 ? a >> 32 : 0);
+}
+
+static u32 flow_get_src(const struct sk_buff *skb)
+{
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP):
+ return ntohl(ip_hdr(skb)->saddr);
+ case __constant_htons(ETH_P_IPV6):
+ return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]);
+ default:
+ return addr_fold(skb->sk);
+ }
+}
+
+static u32 flow_get_dst(const struct sk_buff *skb)
+{
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP):
+ return ntohl(ip_hdr(skb)->daddr);
+ case __constant_htons(ETH_P_IPV6):
+ return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]);
+ default:
+ return addr_fold(skb->dst) ^ (__force u16)skb->protocol;
+ }
+}
+
+static u32 flow_get_proto(const struct sk_buff *skb)
+{
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP):
+ return ip_hdr(skb)->protocol;
+ case __constant_htons(ETH_P_IPV6):
+ return ipv6_hdr(skb)->nexthdr;
+ default:
+ return 0;
+ }
+}
+
+static int has_ports(u8 protocol)
+{
+ switch (protocol) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ case IPPROTO_UDPLITE:
+ case IPPROTO_SCTP:
+ case IPPROTO_DCCP:
+ case IPPROTO_ESP:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static u32 flow_get_proto_src(const struct sk_buff *skb)
+{
+ u32 res = 0;
+
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP): {
+ struct iphdr *iph = ip_hdr(skb);
+
+ if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
+ has_ports(iph->protocol))
+ res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4));
+ break;
+ }
+ case __constant_htons(ETH_P_IPV6): {
+ struct ipv6hdr *iph = ipv6_hdr(skb);
+
+ if (has_ports(iph->nexthdr))
+ res = ntohs(*(__be16 *)&iph[1]);
+ break;
+ }
+ default:
+ res = addr_fold(skb->sk);
+ }
+
+ return res;
+}
+
+static u32 flow_get_proto_dst(const struct sk_buff *skb)
+{
+ u32 res = 0;
+
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP): {
+ struct iphdr *iph = ip_hdr(skb);
+
+ if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
+ has_ports(iph->protocol))
+ res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2));
+ break;
+ }
+ case __constant_htons(ETH_P_IPV6): {
+ struct ipv6hdr *iph = ipv6_hdr(skb);
+
+ if (has_ports(iph->nexthdr))
+ res = ntohs(*(__be16 *)((void *)&iph[1] + 2));
+ break;
+ }
+ default:
+ res = addr_fold(skb->dst) ^ (__force u16)skb->protocol;
+ }
+
+ return res;
+}
+
+static u32 flow_get_iif(const struct sk_buff *skb)
+{
+ return skb->iif;
+}
+
+static u32 flow_get_priority(const struct sk_buff *skb)
+{
+ return skb->priority;
+}
+
+static u32 flow_get_mark(const struct sk_buff *skb)
+{
+ return skb->mark;
+}
+
+static u32 flow_get_nfct(const struct sk_buff *skb)
+{
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ return addr_fold(skb->nfct);
+#else
+ return 0;
+#endif
+}
+
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+#define CTTUPLE(skb, member) \
+({ \
+ enum ip_conntrack_info ctinfo; \
+ struct nf_conn *ct = nf_ct_get(skb, &ctinfo); \
+ if (ct == NULL) \
+ goto fallback; \
+ ct->tuplehash[CTINFO2DIR(ctinfo)].tuple.member; \
+})
+#else
+#define CTTUPLE(skb, member) \
+({ \
+ goto fallback; \
+ 0; \
+})
+#endif
+
+static u32 flow_get_nfct_src(const struct sk_buff *skb)
+{
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP):
+ return ntohl(CTTUPLE(skb, src.u3.ip));
+ case __constant_htons(ETH_P_IPV6):
+ return ntohl(CTTUPLE(skb, src.u3.ip6[3]));
+ }
+fallback:
+ return flow_get_src(skb);
+}
+
+static u32 flow_get_nfct_dst(const struct sk_buff *skb)
+{
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP):
+ return ntohl(CTTUPLE(skb, dst.u3.ip));
+ case __constant_htons(ETH_P_IPV6):
+ return ntohl(CTTUPLE(skb, dst.u3.ip6[3]));
+ }
+fallback:
+ return flow_get_dst(skb);
+}
+
+static u32 flow_get_nfct_proto_src(const struct sk_buff *skb)
+{
+ return ntohs(CTTUPLE(skb, src.u.all));
+fallback:
+ return flow_get_proto_src(skb);
+}
+
+static u32 flow_get_nfct_proto_dst(const struct sk_buff *skb)
+{
+ return ntohs(CTTUPLE(skb, dst.u.all));
+fallback:
+ return flow_get_proto_dst(skb);
+}
+
+static u32 flow_get_rtclassid(const struct sk_buff *skb)
+{
+#ifdef CONFIG_NET_CLS_ROUTE
+ if (skb->dst)
+ return skb->dst->tclassid;
+#endif
+ return 0;
+}
+
+static u32 flow_get_skuid(const struct sk_buff *skb)
+{
+ if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file)
+ return skb->sk->sk_socket->file->f_uid;
+ return 0;
+}
+
+static u32 flow_get_skgid(const struct sk_buff *skb)
+{
+ if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file)
+ return skb->sk->sk_socket->file->f_gid;
+ return 0;
+}
+
+static u32 flow_key_get(const struct sk_buff *skb, int key)
+{
+ switch (key) {
+ case FLOW_KEY_SRC:
+ return flow_get_src(skb);
+ case FLOW_KEY_DST:
+ return flow_get_dst(skb);
+ case FLOW_KEY_PROTO:
+ return flow_get_proto(skb);
+ case FLOW_KEY_PROTO_SRC:
+ return flow_get_proto_src(skb);
+ case FLOW_KEY_PROTO_DST:
+ return flow_get_proto_dst(skb);
+ case FLOW_KEY_IIF:
+ return flow_get_iif(skb);
+ case FLOW_KEY_PRIORITY:
+ return flow_get_priority(skb);
+ case FLOW_KEY_MARK:
+ return flow_get_mark(skb);
+ case FLOW_KEY_NFCT:
+ return flow_get_nfct(skb);
+ case FLOW_KEY_NFCT_SRC:
+ return flow_get_nfct_src(skb);
+ case FLOW_KEY_NFCT_DST:
+ return flow_get_nfct_dst(skb);
+ case FLOW_KEY_NFCT_PROTO_SRC:
+ return flow_get_nfct_proto_src(skb);
+ case FLOW_KEY_NFCT_PROTO_DST:
+ return flow_get_nfct_proto_dst(skb);
+ case FLOW_KEY_RTCLASSID:
+ return flow_get_rtclassid(skb);
+ case FLOW_KEY_SKUID:
+ return flow_get_skuid(skb);
+ case FLOW_KEY_SKGID:
+ return flow_get_skgid(skb);
+ default:
+ WARN_ON(1);
+ return 0;
+ }
+}
+
+static int flow_classify(struct sk_buff *skb, struct tcf_proto *tp,
+ struct tcf_result *res)
+{
+ struct flow_head *head = tp->root;
+ struct flow_filter *f;
+ u32 keymask;
+ u32 classid;
+ unsigned int n, key;
+ int r;
+
+ list_for_each_entry(f, &head->filters, list) {
+ u32 keys[f->nkeys];
+
+ if (!tcf_em_tree_match(skb, &f->ematches, NULL))
+ continue;
+
+ keymask = f->keymask;
+
+ for (n = 0; n < f->nkeys; n++) {
+ key = ffs(keymask) - 1;
+ keymask &= ~(1 << key);
+ keys[n] = flow_key_get(skb, key);
+ }
+
+ if (f->mode == FLOW_MODE_HASH)
+ classid = jhash2(keys, f->nkeys, flow_hashrnd);
+ else {
+ classid = keys[0];
+ classid = (classid & f->mask) ^ f->xor;
+ classid = (classid >> f->rshift) + f->addend;
+ }
+
+ if (f->divisor)
+ classid %= f->divisor;
+
+ res->class = 0;
+ res->classid = TC_H_MAKE(f->baseclass, f->baseclass + classid);
+
+ r = tcf_exts_exec(skb, &f->exts, res);
+ if (r < 0)
+ continue;
+ return r;
+ }
+ return -1;
+}
+
+static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = {
+ [TCA_FLOW_KEYS] = { .type = NLA_U32 },
+ [TCA_FLOW_MODE] = { .type = NLA_U32 },
+ [TCA_FLOW_BASECLASS] = { .type = NLA_U32 },
+ [TCA_FLOW_RSHIFT] = { .type = NLA_U32 },
+ [TCA_FLOW_ADDEND] = { .type = NLA_U32 },
+ [TCA_FLOW_MASK] = { .type = NLA_U32 },
+ [TCA_FLOW_XOR] = { .type = NLA_U32 },
+ [TCA_FLOW_DIVISOR] = { .type = NLA_U32 },
+ [TCA_FLOW_ACT] = { .type = NLA_NESTED },
+ [TCA_FLOW_POLICE] = { .type = NLA_NESTED },
+ [TCA_FLOW_EMATCHES] = { .type = NLA_NESTED },
+};
+
+static int flow_change(struct tcf_proto *tp, unsigned long base,
+ u32 handle, struct nlattr **tca,
+ unsigned long *arg)
+{
+ struct flow_head *head = tp->root;
+ struct flow_filter *f;
+ struct nlattr *opt = tca[TCA_OPTIONS];
+ struct nlattr *tb[TCA_FLOW_MAX + 1];
+ struct tcf_exts e;
+ struct tcf_ematch_tree t;
+ unsigned int nkeys = 0;
+ u32 baseclass = 0;
+ u32 keymask = 0;
+ u32 mode;
+ int err;
+
+ if (opt == NULL)
+ return -EINVAL;
+
+ err = nla_parse_nested(tb, TCA_FLOW_MAX, opt, flow_policy);
+ if (err < 0)
+ return err;
+
+ if (tb[TCA_FLOW_BASECLASS]) {
+ baseclass = nla_get_u32(tb[TCA_FLOW_BASECLASS]);
+ if (TC_H_MIN(baseclass) == 0)
+ return -EINVAL;
+ }
+
+ if (tb[TCA_FLOW_KEYS]) {
+ keymask = nla_get_u32(tb[TCA_FLOW_KEYS]);
+ if (fls(keymask) - 1 > FLOW_KEY_MAX)
+ return -EOPNOTSUPP;
+
+ nkeys = hweight32(keymask);
+ if (nkeys == 0)
+ return -EINVAL;
+ }
+
+ err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map);
+ if (err < 0)
+ return err;
+
+ err = tcf_em_tree_validate(tp, tb[TCA_FLOW_EMATCHES], &t);
+ if (err < 0)
+ goto err1;
+
+ f = (struct flow_filter *)*arg;
+ if (f != NULL) {
+ err = -EINVAL;
+ if (f->handle != handle && handle)
+ goto err2;
+
+ mode = f->mode;
+ if (tb[TCA_FLOW_MODE])
+ mode = nla_get_u32(tb[TCA_FLOW_MODE]);
+ if (mode != FLOW_MODE_HASH && nkeys > 1)
+ goto err2;
+ } else {
+ err = -EINVAL;
+ if (!handle)
+ goto err2;
+ if (!tb[TCA_FLOW_KEYS])
+ goto err2;
+
+ mode = FLOW_MODE_MAP;
+ if (tb[TCA_FLOW_MODE])
+ mode = nla_get_u32(tb[TCA_FLOW_MODE]);
+ if (mode != FLOW_MODE_HASH && nkeys > 1)
+ goto err2;
+
+ if (TC_H_MAJ(baseclass) == 0)
+ baseclass = TC_H_MAKE(tp->q->handle, baseclass);
+ if (TC_H_MIN(baseclass) == 0)
+ baseclass = TC_H_MAKE(baseclass, 1);
+
+ err = -ENOBUFS;
+ f = kzalloc(sizeof(*f), GFP_KERNEL);
+ if (f == NULL)
+ goto err2;
+
+ f->handle = handle;
+ f->mask = ~0U;
+ }
+
+ tcf_exts_change(tp, &f->exts, &e);
+ tcf_em_tree_change(tp, &f->ematches, &t);
+
+ tcf_tree_lock(tp);
+
+ if (tb[TCA_FLOW_KEYS]) {
+ f->keymask = keymask;
+ f->nkeys = nkeys;
+ }
+
+ f->mode = mode;
+
+ if (tb[TCA_FLOW_MASK])
+ f->mask = nla_get_u32(tb[TCA_FLOW_MASK]);
+ if (tb[TCA_FLOW_XOR])
+ f->xor = nla_get_u32(tb[TCA_FLOW_XOR]);
+ if (tb[TCA_FLOW_RSHIFT])
+ f->rshift = nla_get_u32(tb[TCA_FLOW_RSHIFT]);
+ if (tb[TCA_FLOW_ADDEND])
+ f->addend = nla_get_u32(tb[TCA_FLOW_ADDEND]);
+
+ if (tb[TCA_FLOW_DIVISOR])
+ f->divisor = nla_get_u32(tb[TCA_FLOW_DIVISOR]);
+ if (baseclass)
+ f->baseclass = baseclass;
+
+ if (*arg == 0)
+ list_add_tail(&f->list, &head->filters);
+
+ tcf_tree_unlock(tp);
+
+ *arg = (unsigned long)f;
+ return 0;
+
+err2:
+ tcf_em_tree_destroy(tp, &t);
+err1:
+ tcf_exts_destroy(tp, &e);
+ return err;
+}
+
+static void flow_destroy_filter(struct tcf_proto *tp, struct flow_filter *f)
+{
+ tcf_exts_destroy(tp, &f->exts);
+ tcf_em_tree_destroy(tp, &f->ematches);
+ kfree(f);
+}
+
+static int flow_delete(struct tcf_proto *tp, unsigned long arg)
+{
+ struct flow_filter *f = (struct flow_filter *)arg;
+
+ tcf_tree_lock(tp);
+ list_del(&f->list);
+ tcf_tree_unlock(tp);
+ flow_destroy_filter(tp, f);
+ return 0;
+}
+
+static int flow_init(struct tcf_proto *tp)
+{
+ struct flow_head *head;
+
+ if (!flow_hashrnd_initted) {
+ get_random_bytes(&flow_hashrnd, 4);
+ flow_hashrnd_initted = 1;
+ }
+
+ head = kzalloc(sizeof(*head), GFP_KERNEL);
+ if (head == NULL)
+ return -ENOBUFS;
+ INIT_LIST_HEAD(&head->filters);
+ tp->root = head;
+ return 0;
+}
+
+static void flow_destroy(struct tcf_proto *tp)
+{
+ struct flow_head *head = tp->root;
+ struct flow_filter *f, *next;
+
+ list_for_each_entry_safe(f, next, &head->filters, list) {
+ list_del(&f->list);
+ flow_destroy_filter(tp, f);
+ }
+ kfree(head);
+}
+
+static unsigned long flow_get(struct tcf_proto *tp, u32 handle)
+{
+ struct flow_head *head = tp->root;
+ struct flow_filter *f;
+
+ list_for_each_entry(f, &head->filters, list)
+ if (f->handle == handle)
+ return (unsigned long)f;
+ return 0;
+}
+
+static void flow_put(struct tcf_proto *tp, unsigned long f)
+{
+ return;
+}
+
+static int flow_dump(struct tcf_proto *tp, unsigned long fh,
+ struct sk_buff *skb, struct tcmsg *t)
+{
+ struct flow_filter *f = (struct flow_filter *)fh;
+ struct nlattr *nest;
+
+ if (f == NULL)
+ return skb->len;
+
+ t->tcm_handle = f->handle;
+
+ nest = nla_nest_start(skb, TCA_OPTIONS);
+ if (nest == NULL)
+ goto nla_put_failure;
+
+ NLA_PUT_U32(skb, TCA_FLOW_KEYS, f->keymask);
+ NLA_PUT_U32(skb, TCA_FLOW_MODE, f->mode);
+
+ if (f->mask != ~0 || f->xor != 0) {
+ NLA_PUT_U32(skb, TCA_FLOW_MASK, f->mask);
+ NLA_PUT_U32(skb, TCA_FLOW_XOR, f->xor);
+ }
+ if (f->rshift)
+ NLA_PUT_U32(skb, TCA_FLOW_RSHIFT, f->rshift);
+ if (f->addend)
+ NLA_PUT_U32(skb, TCA_FLOW_ADDEND, f->addend);
+
+ if (f->divisor)
+ NLA_PUT_U32(skb, TCA_FLOW_DIVISOR, f->divisor);
+ if (f->baseclass)
+ NLA_PUT_U32(skb, TCA_FLOW_BASECLASS, f->baseclass);
+
+ if (tcf_exts_dump(skb, &f->exts, &flow_ext_map) < 0)
+ goto nla_put_failure;
+
+ if (f->ematches.hdr.nmatches &&
+ tcf_em_tree_dump(skb, &f->ematches, TCA_FLOW_EMATCHES) < 0)
+ goto nla_put_failure;
+
+ nla_nest_end(skb, nest);
+
+ if (tcf_exts_dump_stats(skb, &f->exts, &flow_ext_map) < 0)
+ goto nla_put_failure;
+
+ return skb->len;
+
+nla_put_failure:
+ nlmsg_trim(skb, nest);
+ return -1;
+}
+
+static void flow_walk(struct tcf_proto *tp, struct tcf_walker *arg)
+{
+ struct flow_head *head = tp->root;
+ struct flow_filter *f;
+
+ list_for_each_entry(f, &head->filters, list) {
+ if (arg->count < arg->skip)
+ goto skip;
+ if (arg->fn(tp, (unsigned long)f, arg) < 0) {
+ arg->stop = 1;
+ break;
+ }
+skip:
+ arg->count++;
+ }
+}
+
+static struct tcf_proto_ops cls_flow_ops __read_mostly = {
+ .kind = "flow",
+ .classify = flow_classify,
+ .init = flow_init,
+ .destroy = flow_destroy,
+ .change = flow_change,
+ .delete = flow_delete,
+ .get = flow_get,
+ .put = flow_put,
+ .dump = flow_dump,
+ .walk = flow_walk,
+ .owner = THIS_MODULE,
+};
+
+static int __init cls_flow_init(void)
+{
+ return register_tcf_proto_ops(&cls_flow_ops);
+}
+
+static void __exit cls_flow_exit(void)
+{
+ unregister_tcf_proto_ops(&cls_flow_ops);
+}
+
+module_init(cls_flow_init);
+module_exit(cls_flow_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_DESCRIPTION("TC flow classifier");
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 436a6e7c438..b0f90e593af 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -47,7 +47,7 @@ struct fw_filter
struct tcf_exts exts;
};
-static struct tcf_ext_map fw_ext_map = {
+static const struct tcf_ext_map fw_ext_map = {
.action = TCA_FW_ACT,
.police = TCA_FW_POLICE
};
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index f7e7d3955d2..784dcb870b9 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -62,7 +62,7 @@ struct route4_filter
#define ROUTE4_FAILURE ((struct route4_filter*)(-1L))
-static struct tcf_ext_map route_ext_map = {
+static const struct tcf_ext_map route_ext_map = {
.police = TCA_ROUTE4_POLICE,
.action = TCA_ROUTE4_ACT
};
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index ee60b2d1705..7a7bff5ded2 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -55,7 +55,7 @@ struct tcindex_data {
int fall_through; /* 0: only classify if explicit match */
};
-static struct tcf_ext_map tcindex_ext_map = {
+static const struct tcf_ext_map tcindex_ext_map = {
.police = TCA_TCINDEX_POLICE,
.action = TCA_TCINDEX_ACT
};
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index e8a77568912..b18fa95ef24 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -82,7 +82,7 @@ struct tc_u_common
u32 hgenerator;
};
-static struct tcf_ext_map u32_ext_map = {
+static const struct tcf_ext_map u32_ext_map = {
.action = TCA_U32_ACT,
.police = TCA_U32_POLICE
};
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index 3f72d528273..274b1ddb160 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -12,18 +12,10 @@
#include <linux/list.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
-#include <linux/netfilter_ipv4.h>
-#include <linux/netfilter_ipv6.h>
-#include <linux/netfilter.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
-/* Thanks to Doron Oz for this hack */
-#if !defined(CONFIG_NET_CLS_ACT) && defined(CONFIG_NETFILTER)
-static int nf_registered;
-#endif
-
struct ingress_qdisc_data {
struct tcf_proto *filter_list;
};
@@ -84,11 +76,6 @@ static int ingress_enqueue(struct sk_buff *skb, struct Qdisc *sch)
result = tc_classify(skb, p->filter_list, &res);
- /*
- * Unlike normal "enqueue" functions, ingress_enqueue returns a
- * firewall FW_* code.
- */
-#ifdef CONFIG_NET_CLS_ACT
sch->bstats.packets++;
sch->bstats.bytes += skb->len;
switch (result) {
@@ -107,71 +94,10 @@ static int ingress_enqueue(struct sk_buff *skb, struct Qdisc *sch)
result = TC_ACT_OK;
break;
}
-#else
- result = NF_ACCEPT;
- sch->bstats.packets++;
- sch->bstats.bytes += skb->len;
-#endif
return result;
}
-#if !defined(CONFIG_NET_CLS_ACT) && defined(CONFIG_NETFILTER)
-static unsigned int ing_hook(unsigned int hook, struct sk_buff *skb,
- const struct net_device *indev,
- const struct net_device *outdev,
- int (*okfn)(struct sk_buff *))
-{
-
- struct Qdisc *q;
- struct net_device *dev = skb->dev;
- int fwres = NF_ACCEPT;
-
- if (dev->qdisc_ingress) {
- spin_lock(&dev->ingress_lock);
- if ((q = dev->qdisc_ingress) != NULL)
- fwres = q->enqueue(skb, q);
- spin_unlock(&dev->ingress_lock);
- }
-
- return fwres;
-}
-
-/* after ipt_filter */
-static struct nf_hook_ops ing_ops[] __read_mostly = {
- {
- .hook = ing_hook,
- .owner = THIS_MODULE,
- .pf = PF_INET,
- .hooknum = NF_INET_PRE_ROUTING,
- .priority = NF_IP_PRI_FILTER + 1,
- },
- {
- .hook = ing_hook,
- .owner = THIS_MODULE,
- .pf = PF_INET6,
- .hooknum = NF_INET_PRE_ROUTING,
- .priority = NF_IP6_PRI_FILTER + 1,
- },
-};
-#endif
-
-static int ingress_init(struct Qdisc *sch, struct nlattr *opt)
-{
-#if !defined(CONFIG_NET_CLS_ACT) && defined(CONFIG_NETFILTER)
- printk("Ingress scheduler: Classifier actions prefered over netfilter\n");
-
- if (!nf_registered) {
- if (nf_register_hooks(ing_ops, ARRAY_SIZE(ing_ops)) < 0) {
- printk("ingress qdisc registration error \n");
- return -EINVAL;
- }
- nf_registered++;
- }
-#endif
- return 0;
-}
-
/* ------------------------------------------------------------- */
static void ingress_destroy(struct Qdisc *sch)
@@ -213,7 +139,6 @@ static struct Qdisc_ops ingress_qdisc_ops __read_mostly = {
.id = "ingress",
.priv_size = sizeof(struct ingress_qdisc_data),
.enqueue = ingress_enqueue,
- .init = ingress_init,
.destroy = ingress_destroy,
.dump = ingress_dump,
.owner = THIS_MODULE,
@@ -227,10 +152,6 @@ static int __init ingress_module_init(void)
static void __exit ingress_module_exit(void)
{
unregister_qdisc(&ingress_qdisc_ops);
-#if !defined(CONFIG_NET_CLS_ACT) && defined(CONFIG_NETFILTER)
- if (nf_registered)
- nf_unregister_hooks(ing_ops, ARRAY_SIZE(ing_ops));
-#endif
}
module_init(ingress_module_init)
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 91af539ab6e..a20e2ef7704 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -95,6 +95,7 @@ struct sfq_sched_data
int limit;
/* Variables */
+ struct tcf_proto *filter_list;
struct timer_list perturb_timer;
u32 perturbation;
sfq_index tail; /* Index of current slot in round */
@@ -155,6 +156,39 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
return sfq_fold_hash(q, h, h2);
}
+static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
+ int *qerr)
+{
+ struct sfq_sched_data *q = qdisc_priv(sch);
+ struct tcf_result res;
+ int result;
+
+ if (TC_H_MAJ(skb->priority) == sch->handle &&
+ TC_H_MIN(skb->priority) > 0 &&
+ TC_H_MIN(skb->priority) <= SFQ_HASH_DIVISOR)
+ return TC_H_MIN(skb->priority);
+
+ if (!q->filter_list)
+ return sfq_hash(q, skb) + 1;
+
+ *qerr = NET_XMIT_BYPASS;
+ result = tc_classify(skb, q->filter_list, &res);
+ if (result >= 0) {
+#ifdef CONFIG_NET_CLS_ACT
+ switch (result) {
+ case TC_ACT_STOLEN:
+ case TC_ACT_QUEUED:
+ *qerr = NET_XMIT_SUCCESS;
+ case TC_ACT_SHOT:
+ return 0;
+ }
+#endif
+ if (TC_H_MIN(res.classid) <= SFQ_HASH_DIVISOR)
+ return TC_H_MIN(res.classid);
+ }
+ return 0;
+}
+
static inline void sfq_link(struct sfq_sched_data *q, sfq_index x)
{
sfq_index p, n;
@@ -245,8 +279,18 @@ static int
sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
{
struct sfq_sched_data *q = qdisc_priv(sch);
- unsigned hash = sfq_hash(q, skb);
+ unsigned int hash;
sfq_index x;
+ int ret;
+
+ hash = sfq_classify(skb, sch, &ret);
+ if (hash == 0) {
+ if (ret == NET_XMIT_BYPASS)
+ sch->qstats.drops++;
+ kfree_skb(skb);
+ return ret;
+ }
+ hash--;
x = q->ht[hash];
if (x == SFQ_DEPTH) {
@@ -289,8 +333,18 @@ static int
sfq_requeue(struct sk_buff *skb, struct Qdisc *sch)
{
struct sfq_sched_data *q = qdisc_priv(sch);
- unsigned hash = sfq_hash(q, skb);
+ unsigned int hash;
sfq_index x;
+ int ret;
+
+ hash = sfq_classify(skb, sch, &ret);
+ if (hash == 0) {
+ if (ret == NET_XMIT_BYPASS)
+ sch->qstats.drops++;
+ kfree_skb(skb);
+ return ret;
+ }
+ hash--;
x = q->ht[hash];
if (x == SFQ_DEPTH) {
@@ -465,6 +519,8 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt)
static void sfq_destroy(struct Qdisc *sch)
{
struct sfq_sched_data *q = qdisc_priv(sch);
+
+ tcf_destroy_chain(q->filter_list);
del_timer(&q->perturb_timer);
}
@@ -490,9 +546,79 @@ nla_put_failure:
return -1;
}
+static int sfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+ struct nlattr **tca, unsigned long *arg)
+{
+ return -EOPNOTSUPP;
+}
+
+static unsigned long sfq_get(struct Qdisc *sch, u32 classid)
+{
+ return 0;
+}
+
+static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl)
+{
+ struct sfq_sched_data *q = qdisc_priv(sch);
+
+ if (cl)
+ return NULL;
+ return &q->filter_list;
+}
+
+static int sfq_dump_class(struct Qdisc *sch, unsigned long cl,
+ struct sk_buff *skb, struct tcmsg *tcm)
+{
+ tcm->tcm_handle |= TC_H_MIN(cl);
+ return 0;
+}
+
+static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
+ struct gnet_dump *d)
+{
+ struct sfq_sched_data *q = qdisc_priv(sch);
+ sfq_index idx = q->ht[cl-1];
+ struct gnet_stats_queue qs = { .qlen = q->qs[idx].qlen };
+ struct tc_sfq_xstats xstats = { .allot = q->allot[idx] };
+
+ if (gnet_stats_copy_queue(d, &qs) < 0)
+ return -1;
+ return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
+}
+
+static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
+{
+ struct sfq_sched_data *q = qdisc_priv(sch);
+ unsigned int i;
+
+ if (arg->stop)
+ return;
+
+ for (i = 0; i < SFQ_HASH_DIVISOR; i++) {
+ if (q->ht[i] == SFQ_DEPTH ||
+ arg->count < arg->skip) {
+ arg->count++;
+ continue;
+ }
+ if (arg->fn(sch, i + 1, arg) < 0) {
+ arg->stop = 1;
+ break;
+ }
+ arg->count++;
+ }
+}
+
+static const struct Qdisc_class_ops sfq_class_ops = {
+ .get = sfq_get,
+ .change = sfq_change_class,
+ .tcf_chain = sfq_find_tcf,
+ .dump = sfq_dump_class,
+ .dump_stats = sfq_dump_class_stats,
+ .walk = sfq_walk,
+};
+
static struct Qdisc_ops sfq_qdisc_ops __read_mostly = {
- .next = NULL,
- .cl_ops = NULL,
+ .cl_ops = &sfq_class_ops,
.id = "sfq",
.priv_size = sizeof(struct sfq_sched_data),
.enqueue = sfq_enqueue,
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 1411c7b1fbd..0444fd0f0d2 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -71,7 +71,7 @@ struct teql_sched_data
#define NEXT_SLAVE(q) (((struct teql_sched_data*)qdisc_priv(q))->next)
-#define FMASK (IFF_BROADCAST|IFF_POINTOPOINT|IFF_BROADCAST)
+#define FMASK (IFF_BROADCAST|IFF_POINTOPOINT)
/* "teql*" qdisc routines */
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index dd98763c8b0..77383e9b398 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2056,7 +2056,7 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
break;
case SCTP_PARAM_HMAC_ALGO:
- if (!sctp_auth_enable)
+ if (sctp_auth_enable)
break;
/* Fall Through */
fallthrough:
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 07fad7ccf83..339ca4a8e89 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1652,7 +1652,7 @@ static int __init x25_init(void)
register_netdevice_notifier(&x25_dev_notifier);
- printk(KERN_INFO "X.25 for Linux. Version 0.2 for Linux 2.1.15\n");
+ printk(KERN_INFO "X.25 for Linux Version 0.2\n");
#ifdef CONFIG_SYSCTL
x25_register_sysctl();
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index b5c5347aed6..6cc15250de6 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -28,6 +28,105 @@
* that instantiated crypto transforms have correct parameters for IPsec
* purposes.
*/
+static struct xfrm_algo_desc aead_list[] = {
+{
+ .name = "rfc4106(gcm(aes))",
+
+ .uinfo = {
+ .aead = {
+ .icv_truncbits = 64,
+ }
+ },
+
+ .desc = {
+ .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8,
+ .sadb_alg_ivlen = 8,
+ .sadb_alg_minbits = 128,
+ .sadb_alg_maxbits = 256
+ }
+},
+{
+ .name = "rfc4106(gcm(aes))",
+
+ .uinfo = {
+ .aead = {
+ .icv_truncbits = 96,
+ }
+ },
+
+ .desc = {
+ .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12,
+ .sadb_alg_ivlen = 8,
+ .sadb_alg_minbits = 128,
+ .sadb_alg_maxbits = 256
+ }
+},
+{
+ .name = "rfc4106(gcm(aes))",
+
+ .uinfo = {
+ .aead = {
+ .icv_truncbits = 128,
+ }
+ },
+
+ .desc = {
+ .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16,
+ .sadb_alg_ivlen = 8,
+ .sadb_alg_minbits = 128,
+ .sadb_alg_maxbits = 256
+ }
+},
+{
+ .name = "rfc4309(ccm(aes))",
+
+ .uinfo = {
+ .aead = {
+ .icv_truncbits = 64,
+ }
+ },
+
+ .desc = {
+ .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8,
+ .sadb_alg_ivlen = 8,
+ .sadb_alg_minbits = 128,
+ .sadb_alg_maxbits = 256
+ }
+},
+{
+ .name = "rfc4309(ccm(aes))",
+
+ .uinfo = {
+ .aead = {
+ .icv_truncbits = 96,
+ }
+ },
+
+ .desc = {
+ .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12,
+ .sadb_alg_ivlen = 8,
+ .sadb_alg_minbits = 128,
+ .sadb_alg_maxbits = 256
+ }
+},
+{
+ .name = "rfc4309(ccm(aes))",
+
+ .uinfo = {
+ .aead = {
+ .icv_truncbits = 128,
+ }
+ },
+
+ .desc = {
+ .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16,
+ .sadb_alg_ivlen = 8,
+ .sadb_alg_minbits = 128,
+ .sadb_alg_maxbits = 256
+ }
+},
+};
+
static struct xfrm_algo_desc aalg_list[] = {
{
.name = "hmac(digest_null)",
@@ -332,6 +431,11 @@ static struct xfrm_algo_desc calg_list[] = {
},
};
+static inline int aead_entries(void)
+{
+ return ARRAY_SIZE(aead_list);
+}
+
static inline int aalg_entries(void)
{
return ARRAY_SIZE(aalg_list);
@@ -354,25 +458,32 @@ struct xfrm_algo_list {
u32 mask;
};
+static const struct xfrm_algo_list xfrm_aead_list = {
+ .algs = aead_list,
+ .entries = ARRAY_SIZE(aead_list),
+ .type = CRYPTO_ALG_TYPE_AEAD,
+ .mask = CRYPTO_ALG_TYPE_MASK,
+};
+
static const struct xfrm_algo_list xfrm_aalg_list = {
.algs = aalg_list,
.entries = ARRAY_SIZE(aalg_list),
.type = CRYPTO_ALG_TYPE_HASH,
- .mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC,
+ .mask = CRYPTO_ALG_TYPE_HASH_MASK,
};
static const struct xfrm_algo_list xfrm_ealg_list = {
.algs = ealg_list,
.entries = ARRAY_SIZE(ealg_list),
.type = CRYPTO_ALG_TYPE_BLKCIPHER,
- .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
+ .mask = CRYPTO_ALG_TYPE_BLKCIPHER_MASK,
};
static const struct xfrm_algo_list xfrm_calg_list = {
.algs = calg_list,
.entries = ARRAY_SIZE(calg_list),
.type = CRYPTO_ALG_TYPE_COMPRESS,
- .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
+ .mask = CRYPTO_ALG_TYPE_MASK,
};
static struct xfrm_algo_desc *xfrm_find_algo(
@@ -461,6 +572,33 @@ struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
}
EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
+struct xfrm_aead_name {
+ const char *name;
+ int icvbits;
+};
+
+static int xfrm_aead_name_match(const struct xfrm_algo_desc *entry,
+ const void *data)
+{
+ const struct xfrm_aead_name *aead = data;
+ const char *name = aead->name;
+
+ return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
+ !strcmp(name, entry->name);
+}
+
+struct xfrm_algo_desc *xfrm_aead_get_byname(char *name, int icv_len, int probe)
+{
+ struct xfrm_aead_name data = {
+ .name = name,
+ .icvbits = icv_len,
+ };
+
+ return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data,
+ probe);
+}
+EXPORT_SYMBOL_GPL(xfrm_aead_get_byname);
+
struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
{
if (idx >= aalg_entries())
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 039e7019c48..4d6ebc633a9 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -81,7 +81,6 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
*seq = *(__be32*)(skb_transport_header(skb) + offset_seq);
return 0;
}
-EXPORT_SYMBOL(xfrm_parse_spi);
int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
{
@@ -160,12 +159,12 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
}
if ((x->encap ? x->encap->encap_type : 0) != encap_type) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID);
+ XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH);
goto drop_unlock;
}
if (x->props.replay_window && xfrm_replay_check(x, skb, seq)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINSEQOUTOFWINDOW);
+ XFRM_INC_STATS(LINUX_MIB_XFRMINSTATESEQERROR);
goto drop_unlock;
}
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index f4a1047a557..fc690368325 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -64,6 +64,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
XFRM_SKB_CB(skb)->seq = ++x->replay.oseq;
if (unlikely(x->replay.oseq == 0)) {
+ XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATESEQERROR);
x->replay.oseq--;
xfrm_audit_state_replay_overflow(x, skb);
err = -EOVERFLOW;
diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c
index 31d035415ec..2b0db13f0cd 100644
--- a/net/xfrm/xfrm_proc.c
+++ b/net/xfrm/xfrm_proc.c
@@ -22,7 +22,7 @@ static struct snmp_mib xfrm_mib_list[] = {
SNMP_MIB_ITEM("XfrmInNoStates", LINUX_MIB_XFRMINNOSTATES),
SNMP_MIB_ITEM("XfrmInStateProtoError", LINUX_MIB_XFRMINSTATEPROTOERROR),
SNMP_MIB_ITEM("XfrmInStateModeError", LINUX_MIB_XFRMINSTATEMODEERROR),
- SNMP_MIB_ITEM("XfrmInSeqOutOfWindow", LINUX_MIB_XFRMINSEQOUTOFWINDOW),
+ SNMP_MIB_ITEM("XfrmInStateSeqError", LINUX_MIB_XFRMINSTATESEQERROR),
SNMP_MIB_ITEM("XfrmInStateExpired", LINUX_MIB_XFRMINSTATEEXPIRED),
SNMP_MIB_ITEM("XfrmInStateMismatch", LINUX_MIB_XFRMINSTATEMISMATCH),
SNMP_MIB_ITEM("XfrmInStateInvalid", LINUX_MIB_XFRMINSTATEINVALID),
@@ -36,6 +36,7 @@ static struct snmp_mib xfrm_mib_list[] = {
SNMP_MIB_ITEM("XfrmOutNoStates", LINUX_MIB_XFRMOUTNOSTATES),
SNMP_MIB_ITEM("XfrmOutStateProtoError", LINUX_MIB_XFRMOUTSTATEPROTOERROR),
SNMP_MIB_ITEM("XfrmOutStateModeError", LINUX_MIB_XFRMOUTSTATEMODEERROR),
+ SNMP_MIB_ITEM("XfrmOutStateSeqError", LINUX_MIB_XFRMOUTSTATESEQERROR),
SNMP_MIB_ITEM("XfrmOutStateExpired", LINUX_MIB_XFRMOUTSTATEEXPIRED),
SNMP_MIB_ITEM("XfrmOutPolBlock", LINUX_MIB_XFRMOUTPOLBLOCK),
SNMP_MIB_ITEM("XfrmOutPolDead", LINUX_MIB_XFRMOUTPOLDEAD),
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 3003503d0c9..3ff76e84d54 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -216,10 +216,10 @@ static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo)
write_unlock_bh(&xfrm_state_afinfo_lock);
}
-int xfrm_register_type(struct xfrm_type *type, unsigned short family)
+int xfrm_register_type(const struct xfrm_type *type, unsigned short family)
{
struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
- struct xfrm_type **typemap;
+ const struct xfrm_type **typemap;
int err = 0;
if (unlikely(afinfo == NULL))
@@ -235,10 +235,10 @@ int xfrm_register_type(struct xfrm_type *type, unsigned short family)
}
EXPORT_SYMBOL(xfrm_register_type);
-int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
+int xfrm_unregister_type(const struct xfrm_type *type, unsigned short family)
{
struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
- struct xfrm_type **typemap;
+ const struct xfrm_type **typemap;
int err = 0;
if (unlikely(afinfo == NULL))
@@ -254,11 +254,11 @@ int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
}
EXPORT_SYMBOL(xfrm_unregister_type);
-static struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
+static const struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
{
struct xfrm_state_afinfo *afinfo;
- struct xfrm_type **typemap;
- struct xfrm_type *type;
+ const struct xfrm_type **typemap;
+ const struct xfrm_type *type;
int modload_attempted = 0;
retry:
@@ -281,7 +281,7 @@ retry:
return type;
}
-static void xfrm_put_type(struct xfrm_type *type)
+static void xfrm_put_type(const struct xfrm_type *type)
{
module_put(type->owner);
}
@@ -1645,7 +1645,6 @@ err:
xfrm_audit_state_replay(x, skb, net_seq);
return -EINVAL;
}
-EXPORT_SYMBOL(xfrm_replay_check);
void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
{
@@ -1667,7 +1666,6 @@ void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
if (xfrm_aevent_is_on())
xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
}
-EXPORT_SYMBOL(xfrm_replay_advance);
static LIST_HEAD(xfrm_km_list);
static DEFINE_RWLOCK(xfrm_km_lock);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index e0ccdf26781..78338079b7f 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -31,6 +31,11 @@
#include <linux/in6.h>
#endif
+static inline int aead_len(struct xfrm_algo_aead *alg)
+{
+ return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
+}
+
static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type)
{
struct nlattr *rt = attrs[type];
@@ -68,6 +73,22 @@ static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type)
return 0;
}
+static int verify_aead(struct nlattr **attrs)
+{
+ struct nlattr *rt = attrs[XFRMA_ALG_AEAD];
+ struct xfrm_algo_aead *algp;
+
+ if (!rt)
+ return 0;
+
+ algp = nla_data(rt);
+ if (nla_len(rt) < aead_len(algp))
+ return -EINVAL;
+
+ algp->alg_name[CRYPTO_MAX_ALG_NAME - 1] = '\0';
+ return 0;
+}
+
static void verify_one_addr(struct nlattr **attrs, enum xfrm_attr_type_t type,
xfrm_address_t **addrp)
{
@@ -119,20 +140,28 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
switch (p->id.proto) {
case IPPROTO_AH:
if (!attrs[XFRMA_ALG_AUTH] ||
+ attrs[XFRMA_ALG_AEAD] ||
attrs[XFRMA_ALG_CRYPT] ||
attrs[XFRMA_ALG_COMP])
goto out;
break;
case IPPROTO_ESP:
- if ((!attrs[XFRMA_ALG_AUTH] &&
- !attrs[XFRMA_ALG_CRYPT]) ||
- attrs[XFRMA_ALG_COMP])
+ if (attrs[XFRMA_ALG_COMP])
+ goto out;
+ if (!attrs[XFRMA_ALG_AUTH] &&
+ !attrs[XFRMA_ALG_CRYPT] &&
+ !attrs[XFRMA_ALG_AEAD])
+ goto out;
+ if ((attrs[XFRMA_ALG_AUTH] ||
+ attrs[XFRMA_ALG_CRYPT]) &&
+ attrs[XFRMA_ALG_AEAD])
goto out;
break;
case IPPROTO_COMP:
if (!attrs[XFRMA_ALG_COMP] ||
+ attrs[XFRMA_ALG_AEAD] ||
attrs[XFRMA_ALG_AUTH] ||
attrs[XFRMA_ALG_CRYPT])
goto out;
@@ -143,6 +172,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
case IPPROTO_ROUTING:
if (attrs[XFRMA_ALG_COMP] ||
attrs[XFRMA_ALG_AUTH] ||
+ attrs[XFRMA_ALG_AEAD] ||
attrs[XFRMA_ALG_CRYPT] ||
attrs[XFRMA_ENCAP] ||
attrs[XFRMA_SEC_CTX] ||
@@ -155,6 +185,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
goto out;
}
+ if ((err = verify_aead(attrs)))
+ goto out;
if ((err = verify_one_alg(attrs, XFRMA_ALG_AUTH)))
goto out;
if ((err = verify_one_alg(attrs, XFRMA_ALG_CRYPT)))
@@ -208,6 +240,31 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
return 0;
}
+static int attach_aead(struct xfrm_algo_aead **algpp, u8 *props,
+ struct nlattr *rta)
+{
+ struct xfrm_algo_aead *p, *ualg;
+ struct xfrm_algo_desc *algo;
+
+ if (!rta)
+ return 0;
+
+ ualg = nla_data(rta);
+
+ algo = xfrm_aead_get_byname(ualg->alg_name, ualg->alg_icv_len, 1);
+ if (!algo)
+ return -ENOSYS;
+ *props = algo->desc.sadb_alg_id;
+
+ p = kmemdup(ualg, aead_len(ualg), GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+
+ strcpy(p->alg_name, algo->name);
+ *algpp = p;
+ return 0;
+}
+
static inline int xfrm_user_sec_ctx_size(struct xfrm_sec_ctx *xfrm_ctx)
{
int len = 0;
@@ -286,6 +343,9 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
copy_from_user_state(x, p);
+ if ((err = attach_aead(&x->aead, &x->props.ealgo,
+ attrs[XFRMA_ALG_AEAD])))
+ goto error;
if ((err = attach_one_algo(&x->aalg, &x->props.aalgo,
xfrm_aalg_get_byname,
attrs[XFRMA_ALG_AUTH])))
@@ -510,6 +570,8 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
if (x->lastused)
NLA_PUT_U64(skb, XFRMA_LASTUSED, x->lastused);
+ if (x->aead)
+ NLA_PUT(skb, XFRMA_ALG_AEAD, aead_len(x->aead), x->aead);
if (x->aalg)
NLA_PUT(skb, XFRMA_ALG_AUTH, xfrm_alg_len(x->aalg), x->aalg);
if (x->ealg)
@@ -1808,6 +1870,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
#undef XMSGSIZE
static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
+ [XFRMA_ALG_AEAD] = { .len = sizeof(struct xfrm_algo_aead) },
[XFRMA_ALG_AUTH] = { .len = sizeof(struct xfrm_algo) },
[XFRMA_ALG_CRYPT] = { .len = sizeof(struct xfrm_algo) },
[XFRMA_ALG_COMP] = { .len = sizeof(struct xfrm_algo) },
@@ -1972,6 +2035,8 @@ static int xfrm_notify_sa_flush(struct km_event *c)
static inline size_t xfrm_sa_len(struct xfrm_state *x)
{
size_t l = 0;
+ if (x->aead)
+ l += nla_total_size(aead_len(x->aead));
if (x->aalg)
l += nla_total_size(xfrm_alg_len(x->aalg));
if (x->ealg)
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index f96dec1f925..880d455aa65 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2692,7 +2692,6 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
netlbl_sid_to_secattr_failure:
POLICY_RDUNLOCK;
- netlbl_secattr_destroy(secattr);
return rc;
}
#endif /* CONFIG_NETLABEL */