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 ...
This commit is contained in:
commit
cb23832e39
36 changed files with 268 additions and 137 deletions
|
@ -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,
|
||||||
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 = {
|
||||||
.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)
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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 = {
|
||||||
{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 = {
|
||||||
{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)
|
||||||
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)
|
||||||
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)
|
||||||
* 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");
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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 {
|
||||||
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,
|
||||||
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 {
|
||||||
* - 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,
|
||||||
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,
|
||||||
|
|
||||||
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 @@
|
||||||
|
|
||||||
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)
|
||||||
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[] = {
|
||||||
|
|
||||||
#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,
|
||||||
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 = {
|
||||||
.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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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 @@
|
||||||
|
|
||||||
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)
|
||||||
.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)
|
||||||
#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,
|
||||||
|
|
||||||
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)
|
||||||
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 {
|
||||||
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 {
|
||||||
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,
|
||||||
(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,
|
||||||
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,
|
||||||
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)
|
||||||
|
|
||||||
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 {
|
||||||
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,
|
||||||
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,
|
||||||
* 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 @@
|
||||||
#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,
|
||||||
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 @@ out:
|
||||||
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[])
|
||||||
/* 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[])
|
||||||
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[],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
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)
|
||||||
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)
|
||||||
} 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,
|
||||||
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)
|
||||||
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:
|
||||||
|
|
Loading…
Add table
Reference in a new issue