Commit cb23832e authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (26 commits)
  decnet: Fix compiler warning in dn_dev.c
  IPV6: Fix default gateway criteria wrt. HIGH/LOW preference radv option
  net/802/fc.c: Fix compilation warnings
  netns: correct mib stats in ip6_route_me_harder()
  netns: fix net_generic array leak
  rt2x00: fix regression introduced by "mac80211: free up 2 bytes in skb->cb"
  rtl8187: Add USB ID for Belkin F5D7050 with RTL8187B chip
  p54usb: Device ID updates
  mac80211: fixme for kernel-doc
  ath9k/mac80211: disallow fragmentation in ath9k, report to userspace
  libertas : Remove unused variable warning for "old_channel" from cmd.c
  mac80211: Fix scan RX processing oops
  orinoco: fix unsafe locking in spectrum_cs_suspend
  orinoco: fix unsafe locking in orinoco_cs_resume
  cfg80211: fix debugfs error handling
  mac80211: fix debugfs netdev rename
  iwlwifi: fix ct kill configuration for 5350
  mac80211: fix HT information element parsing
  p54: Fix compilation problem on PPC
  mac80211: fix debugfs lockup
  ...
parents 8ef50901 8fa0b315
...@@ -146,8 +146,8 @@ WARNING: ...@@ -146,8 +146,8 @@ WARNING:
When polling a connected pipe socket for writability, there is an When polling a connected pipe socket for writability, there is an
intrinsic race condition whereby writability might be lost between the intrinsic race condition whereby writability might be lost between the
polling and the writing system calls. In this case, the socket will polling and the writing system calls. In this case, the socket will
block until write because possible again, unless non-blocking mode block until write becomes possible again, unless non-blocking mode
becomes enabled. is enabled.
The pipe protocol provides two socket options at the SOL_PNPIPE level: The pipe protocol provides two socket options at the SOL_PNPIPE level:
......
...@@ -1640,6 +1640,11 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, ...@@ -1640,6 +1640,11 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
return ret; return ret;
} }
static int ath9k_no_fragmentation(struct ieee80211_hw *hw, u32 value)
{
return -EOPNOTSUPP;
}
static struct ieee80211_ops ath9k_ops = { static struct ieee80211_ops ath9k_ops = {
.tx = ath9k_tx, .tx = ath9k_tx,
.start = ath9k_start, .start = ath9k_start,
...@@ -1664,7 +1669,8 @@ static struct ieee80211_ops ath9k_ops = { ...@@ -1664,7 +1669,8 @@ static struct ieee80211_ops ath9k_ops = {
.get_tsf = ath9k_get_tsf, .get_tsf = ath9k_get_tsf,
.reset_tsf = ath9k_reset_tsf, .reset_tsf = ath9k_reset_tsf,
.tx_last_beacon = NULL, .tx_last_beacon = NULL,
.ampdu_action = ath9k_ampdu_action .ampdu_action = ath9k_ampdu_action,
.set_frag_threshold = ath9k_no_fragmentation,
}; };
static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
......
...@@ -833,12 +833,12 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) ...@@ -833,12 +833,12 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
case CSR_HW_REV_TYPE_5100: case CSR_HW_REV_TYPE_5100:
case CSR_HW_REV_TYPE_5300: case CSR_HW_REV_TYPE_5300:
/* 5X00 wants in Celsius */ case CSR_HW_REV_TYPE_5350:
/* 5X00 and 5350 wants in Celsius */
priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD; priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
break; break;
case CSR_HW_REV_TYPE_5150: case CSR_HW_REV_TYPE_5150:
case CSR_HW_REV_TYPE_5350: /* 5150 wants in Kelvin */
/* 5X50 wants in Kelvin */
priv->hw_params.ct_kill_threshold = priv->hw_params.ct_kill_threshold =
CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD); CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
break; break;
......
...@@ -2422,7 +2422,7 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta, ...@@ -2422,7 +2422,7 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
void *priv_sta) void *priv_sta)
{ {
struct iwl_lq_sta *lq_sta = priv_sta; struct iwl_lq_sta *lq_sta = priv_sta;
struct iwl_priv *priv = priv_r; struct iwl_priv *priv __maybe_unused = priv_r;
IWL_DEBUG_RATE("enter\n"); IWL_DEBUG_RATE("enter\n");
kfree(lq_sta); kfree(lq_sta);
......
...@@ -823,7 +823,9 @@ int lbs_update_channel(struct lbs_private *priv) ...@@ -823,7 +823,9 @@ int lbs_update_channel(struct lbs_private *priv)
int lbs_set_channel(struct lbs_private *priv, u8 channel) int lbs_set_channel(struct lbs_private *priv, u8 channel)
{ {
struct cmd_ds_802_11_rf_channel cmd; struct cmd_ds_802_11_rf_channel cmd;
#ifdef DEBUG
u8 old_channel = priv->curbssparams.channel; u8 old_channel = priv->curbssparams.channel;
#endif
int ret = 0; int ret = 0;
lbs_deb_enter(LBS_DEB_CMD); lbs_deb_enter(LBS_DEB_CMD);
......
...@@ -378,6 +378,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link) ...@@ -378,6 +378,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
struct orinoco_private *priv = netdev_priv(dev); struct orinoco_private *priv = netdev_priv(dev);
struct orinoco_pccard *card = priv->card; struct orinoco_pccard *card = priv->card;
int err = 0; int err = 0;
unsigned long flags;
if (! test_bit(0, &card->hard_reset_in_progress)) { if (! test_bit(0, &card->hard_reset_in_progress)) {
err = orinoco_reinit_firmware(dev); err = orinoco_reinit_firmware(dev);
...@@ -387,7 +388,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link) ...@@ -387,7 +388,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
return -EIO; return -EIO;
} }
spin_lock(&priv->lock); spin_lock_irqsave(&priv->lock, flags);
netif_device_attach(dev); netif_device_attach(dev);
priv->hw_unavailable--; priv->hw_unavailable--;
...@@ -399,7 +400,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link) ...@@ -399,7 +400,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
dev->name, err); dev->name, err);
} }
spin_unlock(&priv->lock); spin_unlock_irqrestore(&priv->lock, flags);
} }
return err; return err;
......
...@@ -479,7 +479,6 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) ...@@ -479,7 +479,6 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
printk(KERN_ERR "p54: eeprom parse failed!\n"); printk(KERN_ERR "p54: eeprom parse failed!\n");
return err; return err;
} }
EXPORT_SYMBOL_GPL(p54_parse_eeprom);
static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi) static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
{ {
......
...@@ -39,6 +39,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { ...@@ -39,6 +39,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
{USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */ {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */
{USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */ {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
{USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
{USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
{USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
{USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
{USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
...@@ -63,8 +64,8 @@ static struct usb_device_id p54u_table[] __devinitdata = { ...@@ -63,8 +64,8 @@ static struct usb_device_id p54u_table[] __devinitdata = {
{USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */ {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */
{USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */ {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
{USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */ {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
{USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
{USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */ {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */
{USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */
{USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */ {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */
{USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
{USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
......
...@@ -374,7 +374,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) ...@@ -374,7 +374,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
struct txentry_desc txdesc; struct txentry_desc txdesc;
struct skb_frame_desc *skbdesc; struct skb_frame_desc *skbdesc;
unsigned int iv_len; unsigned int iv_len = 0;
if (unlikely(rt2x00queue_full(queue))) if (unlikely(rt2x00queue_full(queue)))
return -EINVAL; return -EINVAL;
...@@ -395,6 +395,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) ...@@ -395,6 +395,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
entry->skb = skb; entry->skb = skb;
rt2x00queue_create_tx_descriptor(entry, &txdesc); rt2x00queue_create_tx_descriptor(entry, &txdesc);
if (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)
iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
/* /*
* All information is retreived from the skb->cb array, * All information is retreived from the skb->cb array,
* now we should claim ownership of the driver part of that * now we should claim ownership of the driver part of that
...@@ -410,9 +413,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) ...@@ -410,9 +413,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
* the frame so we can provide it to the driver seperately. * the frame so we can provide it to the driver seperately.
*/ */
if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags) && !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
(IEEE80211_SKB_CB(skb)->control.hw_key != NULL)) {
iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
rt2x00crypto_tx_remove_iv(skb, iv_len); rt2x00crypto_tx_remove_iv(skb, iv_len);
} }
......
...@@ -33,10 +33,13 @@ MODULE_LICENSE("GPL"); ...@@ -33,10 +33,13 @@ MODULE_LICENSE("GPL");
static struct usb_device_id rtl8187_table[] __devinitdata = { static struct usb_device_id rtl8187_table[] __devinitdata = {
/* Asus */ /* Asus */
{USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187},
/* Belkin */
{USB_DEVICE(0x050d, 0x705e), .driver_info = DEVICE_RTL8187B},
/* Realtek */ /* Realtek */
{USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187}, {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187},
{USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B}, {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
{USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B}, {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B},
{USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B},
/* Netgear */ /* Netgear */
{USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187}, {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
{USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187}, {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
......
...@@ -426,10 +426,11 @@ spectrum_cs_suspend(struct pcmcia_device *link) ...@@ -426,10 +426,11 @@ spectrum_cs_suspend(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
struct orinoco_private *priv = netdev_priv(dev); struct orinoco_private *priv = netdev_priv(dev);
unsigned long flags;
int err = 0; int err = 0;
/* Mark the device as stopped, to block IO until later */ /* Mark the device as stopped, to block IO until later */
spin_lock(&priv->lock); spin_lock_irqsave(&priv->lock, flags);
err = __orinoco_down(dev); err = __orinoco_down(dev);
if (err) if (err)
...@@ -439,7 +440,7 @@ spectrum_cs_suspend(struct pcmcia_device *link) ...@@ -439,7 +440,7 @@ spectrum_cs_suspend(struct pcmcia_device *link)
netif_device_detach(dev); netif_device_detach(dev);
priv->hw_unavailable++; priv->hw_unavailable++;
spin_unlock(&priv->lock); spin_unlock_irqrestore(&priv->lock, flags);
return err; return err;
} }
......
...@@ -40,16 +40,18 @@ struct icmp6hdr { ...@@ -40,16 +40,18 @@ struct icmp6hdr {
struct icmpv6_nd_ra { struct icmpv6_nd_ra {
__u8 hop_limit; __u8 hop_limit;
#if defined(__LITTLE_ENDIAN_BITFIELD) #if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 reserved:4, __u8 reserved:3,
router_pref:2, router_pref:2,
home_agent:1,
other:1, other:1,
managed:1; managed:1;
#elif defined(__BIG_ENDIAN_BITFIELD) #elif defined(__BIG_ENDIAN_BITFIELD)
__u8 managed:1, __u8 managed:1,
other:1, other:1,
home_agent:1,
router_pref:2, router_pref:2,
reserved:4; reserved:3;
#else #else
#error "Please fix <asm/byteorder.h>" #error "Please fix <asm/byteorder.h>"
#endif #endif
......
...@@ -78,6 +78,9 @@ extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, ...@@ -78,6 +78,9 @@ extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group,
int echo); int echo);
extern int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags); extern int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags);
extern void nfnl_lock(void);
extern void nfnl_unlock(void);
#define MODULE_ALIAS_NFNL_SUBSYS(subsys) \ #define MODULE_ALIAS_NFNL_SUBSYS(subsys) \
MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys)) MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys))
......
...@@ -645,7 +645,8 @@ enum ieee80211_key_flags { ...@@ -645,7 +645,8 @@ enum ieee80211_key_flags {
* - Temporal Encryption Key (128 bits) * - Temporal Encryption Key (128 bits)
* - Temporal Authenticator Tx MIC Key (64 bits) * - Temporal Authenticator Tx MIC Key (64 bits)
* - Temporal Authenticator Rx MIC Key (64 bits) * - Temporal Authenticator Rx MIC Key (64 bits)
* * @icv_len: FIXME
* @iv_len: FIXME
*/ */
struct ieee80211_key_conf { struct ieee80211_key_conf {
enum ieee80211_key_alg alg; enum ieee80211_key_alg alg;
......
...@@ -25,4 +25,12 @@ static inline int nf_nat_initialized(struct nf_conn *ct, ...@@ -25,4 +25,12 @@ static inline int nf_nat_initialized(struct nf_conn *ct,
else else
return test_bit(IPS_DST_NAT_DONE_BIT, &ct->status); return test_bit(IPS_DST_NAT_DONE_BIT, &ct->status);
} }
struct nlattr;
extern int
(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
enum nf_nat_manip_type manip,
struct nlattr *attr);
#endif /* _NF_NAT_CORE_H */ #endif /* _NF_NAT_CORE_H */
...@@ -82,13 +82,13 @@ static int fc_header(struct sk_buff *skb, struct net_device *dev, ...@@ -82,13 +82,13 @@ static int fc_header(struct sk_buff *skb, struct net_device *dev,
static int fc_rebuild_header(struct sk_buff *skb) static int fc_rebuild_header(struct sk_buff *skb)
{ {
#ifdef CONFIG_INET
struct fch_hdr *fch=(struct fch_hdr *)skb->data; struct fch_hdr *fch=(struct fch_hdr *)skb->data;
struct fcllc *fcllc=(struct fcllc *)(skb->data+sizeof(struct fch_hdr)); struct fcllc *fcllc=(struct fcllc *)(skb->data+sizeof(struct fch_hdr));
if(fcllc->ethertype != htons(ETH_P_IP)) { if(fcllc->ethertype != htons(ETH_P_IP)) {
printk("fc_rebuild_header: Don't know how to resolve type %04X addresses ?\n", ntohs(fcllc->ethertype)); printk("fc_rebuild_header: Don't know how to resolve type %04X addresses ?\n", ntohs(fcllc->ethertype));
return 0; return 0;
} }
#ifdef CONFIG_INET
return arp_find(fch->daddr, skb); return arp_find(fch->daddr, skb);
#else #else
return 0; return 0;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
menuconfig BRIDGE_NF_EBTABLES menuconfig BRIDGE_NF_EBTABLES
tristate "Ethernet Bridge tables (ebtables) support" tristate "Ethernet Bridge tables (ebtables) support"
depends on BRIDGE && BRIDGE_NETFILTER
select NETFILTER_XTABLES select NETFILTER_XTABLES
help help
ebtables is a general, extensible frame/packet identification ebtables is a general, extensible frame/packet identification
......
...@@ -96,7 +96,7 @@ static void net_free(struct net *net) ...@@ -96,7 +96,7 @@ static void net_free(struct net *net)
return; return;
} }
#endif #endif
kfree(net->gen);
kmem_cache_free(net_cachep, net); kmem_cache_free(net_cachep, net);
} }
......
...@@ -152,7 +152,7 @@ static struct dn_dev_parms dn_dev_list[] = { ...@@ -152,7 +152,7 @@ static struct dn_dev_parms dn_dev_list[] = {
#define DN_DEV_LIST_SIZE ARRAY_SIZE(dn_dev_list) #define DN_DEV_LIST_SIZE ARRAY_SIZE(dn_dev_list)
#define DN_DEV_PARMS_OFFSET(x) ((int) ((char *) &((struct dn_dev_parms *)0)->x)) #define DN_DEV_PARMS_OFFSET(x) offsetof(struct dn_dev_parms, x)
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
......
...@@ -41,12 +41,13 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, ...@@ -41,12 +41,13 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
int (*okfn)(struct sk_buff *)) int (*okfn)(struct sk_buff *))
{ {
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
#if !defined(CONFIG_NF_NAT) && !defined(CONFIG_NF_NAT_MODULE)
/* Previously seen (loopback)? Ignore. Do this before /* Previously seen (loopback)? Ignore. Do this before
fragment check. */ fragment check. */
if (skb->nfct) if (skb->nfct)
return NF_ACCEPT; return NF_ACCEPT;
#endif #endif
#endif
/* Gather fragments. */ /* Gather fragments. */
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
if (nf_ct_ipv4_gather_frags(skb, if (nf_ct_ipv4_gather_frags(skb,
......
...@@ -584,6 +584,98 @@ static struct nf_ct_ext_type nat_extend __read_mostly = { ...@@ -584,6 +584,98 @@ static struct nf_ct_ext_type nat_extend __read_mostly = {
.flags = NF_CT_EXT_F_PREALLOC, .flags = NF_CT_EXT_F_PREALLOC,
}; };
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_conntrack.h>
static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = {
[CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 },
[CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 },
};
static int nfnetlink_parse_nat_proto(struct nlattr *attr,
const struct nf_conn *ct,
struct nf_nat_range *range)
{
struct nlattr *tb[CTA_PROTONAT_MAX+1];
const struct nf_nat_protocol *npt;
int err;
err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
if (err < 0)
return err;
npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
if (npt->nlattr_to_range)
err = npt->nlattr_to_range(tb, range);
nf_nat_proto_put(npt);
return err;
}
static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
[CTA_NAT_MINIP] = { .type = NLA_U32 },
[CTA_NAT_MAXIP] = { .type = NLA_U32 },
};
static int
nfnetlink_parse_nat(struct nlattr *nat,
const struct nf_conn *ct, struct nf_nat_range *range)
{
struct nlattr *tb[CTA_NAT_MAX+1];
int err;
memset(range, 0, sizeof(*range));
err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
if (err < 0)
return err;
if (tb[CTA_NAT_MINIP])
range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
if (!tb[CTA_NAT_MAXIP])
range->max_ip = range->min_ip;
else
range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
if (range->min_ip)
range->flags |= IP_NAT_RANGE_MAP_IPS;
if (!tb[CTA_NAT_PROTO])
return 0;
err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
if (err < 0)
return err;
return 0;
}
static int
nfnetlink_parse_nat_setup(struct nf_conn *ct,
enum nf_nat_manip_type manip,
struct nlattr *attr)
{
struct nf_nat_range range;
if (nfnetlink_parse_nat(attr, ct, &range) < 0)
return -EINVAL;
if (nf_nat_initialized(ct, manip))
return -EEXIST;
return nf_nat_setup_info(ct, &range, manip);
}
#else
static int
nfnetlink_parse_nat_setup(struct nf_conn *ct,
enum nf_nat_manip_type manip,
struct nlattr *attr)
{
return -EOPNOTSUPP;
}
#endif
static int __net_init nf_nat_net_init(struct net *net) static int __net_init nf_nat_net_init(struct net *net)
{ {
net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
...@@ -654,6 +746,9 @@ static int __init nf_nat_init(void) ...@@ -654,6 +746,9 @@ static int __init nf_nat_init(void)
BUG_ON(nf_nat_seq_adjust_hook != NULL); BUG_ON(nf_nat_seq_adjust_hook != NULL);
rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust); rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
rcu_assign_pointer(nfnetlink_parse_nat_setup_hook,
nfnetlink_parse_nat_setup);
return 0; return 0;
cleanup_extend: cleanup_extend:
...@@ -667,10 +762,12 @@ static void __exit nf_nat_cleanup(void) ...@@ -667,10 +762,12 @@ static void __exit nf_nat_cleanup(void)
nf_ct_l3proto_put(l3proto); nf_ct_l3proto_put(l3proto);
nf_ct_extend_unregister(&nat_extend); nf_ct_extend_unregister(&nat_extend);
rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL);
synchronize_net(); synchronize_net();
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("nf-nat-ipv4");
module_init(nf_nat_init); module_init(nf_nat_init);
module_exit(nf_nat_cleanup); module_exit(nf_nat_cleanup);
...@@ -1199,7 +1199,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) ...@@ -1199,7 +1199,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
} }
neigh->flags |= NTF_ROUTER; neigh->flags |= NTF_ROUTER;
} else if (rt) { } else if (rt) {
rt->rt6i_flags |= (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref); rt->rt6i_flags = (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
} }
if (rt) if (rt)
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
int ip6_route_me_harder(struct sk_buff *skb) int ip6_route_me_harder(struct sk_buff *skb)
{ {
struct net *net = dev_net(skb->dst->dev);
struct ipv6hdr *iph = ipv6_hdr(skb); struct ipv6hdr *iph = ipv6_hdr(skb);
struct dst_entry *dst; struct dst_entry *dst;
struct flowi fl = { struct flowi fl = {
...@@ -23,7 +24,7 @@ int ip6_route_me_harder(struct sk_buff *skb) ...@@ -23,7 +24,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
.saddr = iph->saddr, } }, .saddr = iph->saddr, } },
}; };
dst = ip6_route_output(dev_net(skb->dst->dev), skb->sk, &fl); dst = ip6_route_output(net, skb->sk, &fl);
#ifdef CONFIG_XFRM #ifdef CONFIG_XFRM
if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
...@@ -33,8 +34,7 @@ int ip6_route_me_harder(struct sk_buff *skb) ...@@ -33,8 +34,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
#endif #endif
if (dst->error) { if (dst->error) {
IP6_INC_STATS(&init_net, ip6_dst_idev(dst), IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
IPSTATS_MIB_OUTNOROUTES);
LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
dst_release(dst); dst_release(dst);
return -EINVAL; return -EINVAL;
......
...@@ -545,8 +545,12 @@ static int netdev_notify(struct notifier_block *nb, ...@@ -545,8 +545,12 @@ static int netdev_notify(struct notifier_block *nb,
sdata = IEEE80211_DEV_TO_SUB_IF(dev); sdata = IEEE80211_DEV_TO_SUB_IF(dev);
sprintf(buf, "netdev:%s", dev->name);
dir = sdata->debugfsdir; dir = sdata->debugfsdir;
if (!dir)
return 0;
sprintf(buf, "netdev:%s", dev->name);
if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs " printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs "
"dir to %s\n", buf); "dir to %s\n", buf);
......
...@@ -249,11 +249,22 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) ...@@ -249,11 +249,22 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
DECLARE_MAC_BUF(mbuf); DECLARE_MAC_BUF(mbuf);
u8 *mac; u8 *mac;
sta->debugfs.add_has_run = true;
if (!stations_dir) if (!stations_dir)
return; return;
mac = print_mac(mbuf, sta->sta.addr); mac = print_mac(mbuf, sta->sta.addr);
/*
* This might fail due to a race condition:
* When mac80211 unlinks a station, the debugfs entries
* remain, but it is already possible to link a new
* station with the same address which triggers adding
* it to debugfs; therefore, if the old station isn't
* destroyed quickly enough the old station's debugfs
* dir might still be around.
*/
sta->debugfs.dir = debugfs_create_dir(mac, stations_dir); sta->debugfs.dir = debugfs_create_dir(mac, stations_dir);
if (!sta->debugfs.dir) if (!sta->debugfs.dir)
return; return;
......
...@@ -816,8 +816,8 @@ struct ieee802_11_elems { ...@@ -816,8 +816,8 @@ struct ieee802_11_elems {
u8 *ext_supp_rates; u8 *ext_supp_rates;
u8 *wmm_info; u8 *wmm_info;
u8 *wmm_param; u8 *wmm_param;
u8 *ht_cap_elem; struct ieee80211_ht_cap *ht_cap_elem;
u8 *ht_info_elem; struct ieee80211_ht_addt_info *ht_info_elem;
u8 *mesh_config; u8 *mesh_config;
u8 *mesh_id; u8 *mesh_id;
u8 *peer_link; u8 *peer_link;
...@@ -844,8 +844,6 @@ struct ieee802_11_elems { ...@@ -844,8 +844,6 @@ struct ieee802_11_elems {
u8 ext_supp_rates_len; u8 ext_supp_rates_len;
u8 wmm_info_len; u8 wmm_info_len;
u8 wmm_param_len; u8 wmm_param_len;
u8 ht_cap_elem_len;
u8 ht_info_elem_len;
u8 mesh_config_len; u8 mesh_config_len;
u8 mesh_id_len; u8 mesh_id_len;
u8 peer_link_len; u8 peer_link_len;
......
...@@ -1348,10 +1348,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, ...@@ -1348,10 +1348,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
(ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
struct ieee80211_ht_bss_info bss_info; struct ieee80211_ht_bss_info bss_info;
ieee80211_ht_cap_ie_to_ht_info( ieee80211_ht_cap_ie_to_ht_info(
(struct ieee80211_ht_cap *)
elems.ht_cap_elem, &sta->sta.ht_info); elems.ht_cap_elem, &sta->sta.ht_info);
ieee80211_ht_addt_info_ie_to_ht_bss_info( ieee80211_ht_addt_info_ie_to_ht_bss_info(
(struct ieee80211_ht_addt_info *)
elems.ht_info_elem, &bss_info); elems.ht_info_elem, &bss_info);
ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info); ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info);
} }
...@@ -1709,7 +1707,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, ...@@ -1709,7 +1707,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
struct ieee80211_ht_bss_info bss_info; struct ieee80211_ht_bss_info bss_info;
ieee80211_ht_addt_info_ie_to_ht_bss_info( ieee80211_ht_addt_info_ie_to_ht_bss_info(
(struct ieee80211_ht_addt_info *)
elems.ht_info_elem, &bss_info); elems.ht_info_elem, &bss_info);
changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf, changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf,
&bss_info); &bss_info);
......
...@@ -388,6 +388,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, ...@@ -388,6 +388,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
bss = ieee80211_bss_info_update(sdata->local, rx_status, bss = ieee80211_bss_info_update(sdata->local, rx_status,
mgmt, skb->len, &elems, mgmt, skb->len, &elems,
freq, beacon); freq, beacon);
if (bss)
ieee80211_rx_bss_put(sdata->local, bss); ieee80211_rx_bss_put(sdata->local, bss);
dev_kfree_skb(skb); dev_kfree_skb(skb);
......
...@@ -635,7 +635,12 @@ static void sta_info_debugfs_add_work(struct work_struct *work) ...@@ -635,7 +635,12 @@ static void sta_info_debugfs_add_work(struct work_struct *work)
spin_lock_irqsave(&local->sta_lock, flags); spin_lock_irqsave(&local->sta_lock, flags);
list_for_each_entry(tmp, &local->sta_list, list) { list_for_each_entry(tmp, &local->sta_list, list) {
if (!tmp->debugfs.dir) { /*
* debugfs.add_has_run will be set by
* ieee80211_sta_debugfs_add regardless
* of what else it does.
*/
if (!tmp->debugfs.add_has_run) {
sta = tmp; sta = tmp;
__sta_info_pin(sta); __sta_info_pin(sta);
break; break;
......
...@@ -300,6 +300,7 @@ struct sta_info { ...@@ -300,6 +300,7 @@ struct sta_info {
struct dentry *inactive_ms; struct dentry *inactive_ms;
struct dentry *last_seq_ctrl; struct dentry *last_seq_ctrl;
struct dentry *agg_status; struct dentry *agg_status;
bool add_has_run;
} debugfs; } debugfs;
#endif #endif
......
...@@ -529,12 +529,12 @@ void ieee802_11_parse_elems(u8 *start, size_t len, ...@@ -529,12 +529,12 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
elems->ext_supp_rates_len = elen; elems->ext_supp_rates_len = elen;
break; break;
case WLAN_EID_HT_CAPABILITY: case WLAN_EID_HT_CAPABILITY:
elems->ht_cap_elem = pos; if (elen >= sizeof(struct ieee80211_ht_cap))
elems->ht_cap_elem_len = elen; elems->ht_cap_elem = (void *)pos;
break; break;
case WLAN_EID_HT_EXTRA_INFO: case WLAN_EID_HT_EXTRA_INFO:
elems->ht_info_elem = pos; if (elen >= sizeof(struct ieee80211_ht_addt_info))
elems->ht_info_elem_len = elen; elems->ht_info_elem = (void *)pos;
break; break;
case WLAN_EID_MESH_ID: case WLAN_EID_MESH_ID:
elems->mesh_id = pos; elems->mesh_id = pos;
......
...@@ -775,7 +775,7 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev, ...@@ -775,7 +775,7 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev,
* configure it here */ * configure it here */
if (local->ops->set_frag_threshold) if (local->ops->set_frag_threshold)
local->ops->set_frag_threshold( return local->ops->set_frag_threshold(
local_to_hw(local), local_to_hw(local),
local->fragmentation_threshold); local->fragmentation_threshold);
......
...@@ -38,9 +38,16 @@ ...@@ -38,9 +38,16 @@
#include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_extend.h> #include <net/netfilter/nf_conntrack_extend.h>
#include <net/netfilter/nf_conntrack_acct.h> #include <net/netfilter/nf_conntrack_acct.h>
#include <net/netfilter/nf_nat.h>
#define NF_CONNTRACK_VERSION "0.5.0" #define NF_CONNTRACK_VERSION "0.5.0"
unsigned int
(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
enum nf_nat_manip_type manip,
struct nlattr *attr) __read_mostly;
EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
DEFINE_SPINLOCK(nf_conntrack_lock); DEFINE_SPINLOCK(nf_conntrack_lock);
EXPORT_SYMBOL_GPL(nf_conntrack_lock); EXPORT_SYMBOL_GPL(nf_conntrack_lock);
......
...@@ -689,71 +689,6 @@ ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple, ...@@ -689,71 +689,6 @@ ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple,
return 0; return 0;
} }
#ifdef CONFIG_NF_NAT_NEEDED
static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = {
[CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 },
[CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 },
};
static int nfnetlink_parse_nat_proto(struct nlattr *attr,
const struct nf_conn *ct,
struct nf_nat_range *range)
{
struct nlattr *tb[CTA_PROTONAT_MAX+1];
const struct nf_nat_protocol *npt;
int err;
err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
if (err < 0)
return err;
npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
if (npt->nlattr_to_range)
err = npt->nlattr_to_range(tb, range);
nf_nat_proto_put(npt);
return err;
}
static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
[CTA_NAT_MINIP] = { .type = NLA_U32 },
[CTA_NAT_MAXIP] = { .type = NLA_U32 },
};
static inline int
nfnetlink_parse_nat(struct nlattr *nat,
const struct nf_conn *ct, struct nf_nat_range *range)
{
struct nlattr *tb[CTA_NAT_MAX+1];
int err;
memset(range, 0, sizeof(*range));
err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
if (err < 0)
return err;
if (tb[CTA_NAT_MINIP])
range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
if (!tb[CTA_NAT_MAXIP])
range->max_ip = range->min_ip;
else
range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
if (range->min_ip)
range->flags |= IP_NAT_RANGE_MAP_IPS;
if (!tb[CTA_NAT_PROTO])
return 0;
err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
if (err < 0)
return err;
return 0;
}
#endif
static inline int static inline int
ctnetlink_parse_help(struct nlattr *attr, char **helper_name) ctnetlink_parse_help(struct nlattr *attr, char **helper_name)
{ {
...@@ -878,6 +813,34 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, ...@@ -878,6 +813,34 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
return err; return err;
} }
static int
ctnetlink_parse_nat_setup(struct nf_conn *ct,
enum nf_nat_manip_type manip,
struct nlattr *attr)
{
typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup;
parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook);
if (!parse_nat_setup) {
#ifdef CONFIG_KMOD
rcu_read_unlock();
nfnl_unlock();
if (request_module("nf-nat-ipv4") < 0) {
nfnl_lock();
rcu_read_lock();
return -EOPNOTSUPP;
}
nfnl_lock();
rcu_read_lock();
if (nfnetlink_parse_nat_setup_hook)
return -EAGAIN;
#endif
return -EOPNOTSUPP;
}
return parse_nat_setup(ct, manip, attr);
}
static int static int
ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[]) ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
{ {
...@@ -897,31 +860,6 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[]) ...@@ -897,31 +860,6 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
/* ASSURED bit can only be set */ /* ASSURED bit can only be set */
return -EBUSY; return -EBUSY;
if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
#ifndef CONFIG_NF_NAT_NEEDED
return -EOPNOTSUPP;
#else
struct nf_nat_range range;
if (cda[CTA_NAT_DST]) {
if (nfnetlink_parse_nat(cda[CTA_NAT_DST], ct,
&range) < 0)
return -EINVAL;
if (nf_nat_initialized(ct, IP_NAT_MANIP_DST))
return -EEXIST;
nf_nat_setup_info(ct, &range, IP_NAT_MANIP_DST);
}
if (cda[CTA_NAT_SRC]) {
if (nfnetlink_parse_nat(cda[CTA_NAT_SRC], ct,
&range) < 0)
return -EINVAL;
if (nf_nat_initialized(ct, IP_NAT_MANIP_SRC))
return -EEXIST;
nf_nat_setup_info(ct, &range, IP_NAT_MANIP_SRC);
}
#endif
}
/* Be careful here, modifying NAT bits can screw up things, /* Be careful here, modifying NAT bits can screw up things,
* so don't let users modify them directly if they don't pass * so don't let users modify them directly if they don't pass
* nf_nat_range. */ * nf_nat_range. */
...@@ -929,6 +867,31 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[]) ...@@ -929,6 +867,31 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
return 0; return 0;
} }
static int
ctnetlink_change_nat(struct nf_conn *ct, struct nlattr *cda[])
{
#ifdef CONFIG_NF_NAT_NEEDED
int ret;
if (cda[CTA_NAT_DST]) {
ret = ctnetlink_parse_nat_setup(ct,
IP_NAT_MANIP_DST,
cda[CTA_NAT_DST]);
if (ret < 0)
return ret;
}
if (cda[CTA_NAT_SRC]) {
ret = ctnetlink_parse_nat_setup(ct,
IP_NAT_MANIP_SRC,
cda[CTA_NAT_SRC]);
if (ret < 0)
return ret;
}
return 0;
#else
return -EOPNOTSUPP;
#endif
}
static inline int static inline int
ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[]) ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
...@@ -1157,6 +1120,14 @@ ctnetlink_create_conntrack(struct nlattr *cda[], ...@@ -1157,6 +1120,14 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
} }
} }
if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
err = ctnetlink_change_nat(ct, cda);
if (err < 0) {
rcu_read_unlock();
goto err;
}
}
if (cda[CTA_PROTOINFO]) { if (cda[CTA_PROTOINFO]) {
err = ctnetlink_change_protoinfo(ct, cda); err = ctnetlink_change_protoinfo(ct, cda);
if (err < 0) { if (err < 0) {
......
...@@ -44,15 +44,17 @@ static struct sock *nfnl = NULL; ...@@ -44,15 +44,17 @@ static struct sock *nfnl = NULL;
static const struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT]; static const struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT];
static DEFINE_MUTEX(nfnl_mutex); static DEFINE_MUTEX(nfnl_mutex);
static inline void nfnl_lock(void) void nfnl_lock(void)
{ {
mutex_lock(&nfnl_mutex); mutex_lock(&nfnl_mutex);
} }
EXPORT_SYMBOL_GPL(nfnl_lock);
static inline void nfnl_unlock(void) void nfnl_unlock(void)
{ {
mutex_unlock(&nfnl_mutex); mutex_unlock(&nfnl_mutex);
} }
EXPORT_SYMBOL_GPL(nfnl_unlock);
int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n) int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n)
{ {
...@@ -132,6 +134,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -132,6 +134,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return 0; return 0;
type = nlh->nlmsg_type; type = nlh->nlmsg_type;
replay:
ss = nfnetlink_get_subsys(type); ss = nfnetlink_get_subsys(type);
if (!ss) { if (!ss) {
#ifdef CONFIG_KMOD #ifdef CONFIG_KMOD
...@@ -165,7 +168,10 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -165,7 +168,10 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
} else } else
return -EINVAL; return -EINVAL;
return nc->call(nfnl, skb, nlh, cda); err = nc->call(nfnl, skb, nlh, cda);
if (err == -EAGAIN)
goto replay;
return err;
} }
} }
......
...@@ -184,7 +184,8 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, ...@@ -184,7 +184,8 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
if (result) if (result)
goto out_unlock; goto out_unlock;
if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent, if (rdev->wiphy.debugfsdir &&
!debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
rdev->wiphy.debugfsdir, rdev->wiphy.debugfsdir,
rdev->wiphy.debugfsdir->d_parent, rdev->wiphy.debugfsdir->d_parent,
newname)) newname))
...@@ -317,6 +318,8 @@ int wiphy_register(struct wiphy *wiphy) ...@@ -317,6 +318,8 @@ int wiphy_register(struct wiphy *wiphy)
drv->wiphy.debugfsdir = drv->wiphy.debugfsdir =
debugfs_create_dir(wiphy_name(&drv->wiphy), debugfs_create_dir(wiphy_name(&drv->wiphy),
ieee80211_debugfs_dir); ieee80211_debugfs_dir);
if (IS_ERR(drv->wiphy.debugfsdir))
drv->wiphy.debugfsdir = NULL;
res = 0; res = 0;
out_unlock: out_unlock:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment