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

Pull networking merge from David Miller:
 "1) Move ixgbe driver over to purely page based buffering on receive.
     From Alexander Duyck.

  2) Add receive packet steering support to e1000e, from Bruce Allan.

  3) Convert TCP MD5 support over to RCU, from Eric Dumazet.

  4) Reduce cpu usage in handling out-of-order TCP packets on modern
     systems, also from Eric Dumazet.

  5) Support the IP{,V6}_UNICAST_IF socket options, making the wine
     folks happy, from Erich Hoover.

  6) Support VLAN trunking from guests in hyperv driver, from Haiyang
     Zhang.

  7) Support byte-queue-limtis in r8169, from Igor Maravic.

  8) Outline code intended for IP_RECVTOS in IP_PKTOPTIONS existed but
     was never properly implemented, Jiri Benc fixed that.

  9) 64-bit statistics support in r8169 and 8139too, from Junchang Wang.

  10) Support kernel side dump filtering by ctmark in netfilter
      ctnetlink, from Pablo Neira Ayuso.

  11) Support byte-queue-limits in gianfar driver, from Paul Gortmaker.

  12) Add new peek socket options to assist with socket migration, from
      Pavel Emelyanov.

  13) Add sch_plug packet scheduler whose queue is controlled by
      userland daemons using explicit freeze and release commands.  From
      Shriram Rajagopalan.

  14) Fix FCOE checksum offload handling on transmit, from Yi Zou."

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1846 commits)
  Fix pppol2tp getsockname()
  Remove printk from rds_sendmsg
  ipv6: fix incorrent ipv6 ipsec packet fragment
  cpsw: Hook up default ndo_change_mtu.
  net: qmi_wwan: fix build error due to cdc-wdm dependecy
  netdev: driver: ethernet: Add TI CPSW driver
  netdev: driver: ethernet: add cpsw address lookup engine support
  phy: add am79c874 PHY support
  mlx4_core: fix race on comm channel
  bonding: send igmp report for its master
  fs_enet: Add MPC5125 FEC support and PHY interface selection
  net: bpf_jit: fix BPF_S_LDX_B_MSH compilation
  net: update the usage of CHECKSUM_UNNECESSARY
  fcoe: use CHECKSUM_UNNECESSARY instead of CHECKSUM_PARTIAL on tx
  net: do not do gso for CHECKSUM_UNNECESSARY in netif_needs_gso
  ixgbe: Fix issues with SR-IOV loopback when flow control is disabled
  net/hyperv: Fix the code handling tx busy
  ixgbe: fix namespace issues when FCoE/DCB is not enabled
  rtlwifi: Remove unused ETH_ADDR_LEN defines
  igbvf: Use ETH_ALEN
  ...

Fix up fairly trivial conflicts in drivers/isdn/gigaset/interface.c and
drivers/net/usb/{Kconfig,qmi_wwan.c} as per David.
This commit is contained in:
Linus Torvalds
2012-03-20 21:04:47 -07:00
1687 changed files with 123578 additions and 96539 deletions

View File

@@ -330,6 +330,8 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
struct atmarp_entry *entry;
struct neighbour *n;
struct atm_vcc *vcc;
struct rtable *rt;
__be32 *daddr;
int old;
unsigned long flags;
@@ -340,7 +342,12 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
dev->stats.tx_dropped++;
return NETDEV_TX_OK;
}
n = dst_get_neighbour_noref(dst);
rt = (struct rtable *) dst;
if (rt->rt_gateway)
daddr = &rt->rt_gateway;
else
daddr = &ip_hdr(skb)->daddr;
n = dst_neigh_lookup(dst, daddr);
if (!n) {
pr_err("NO NEIGHBOUR !\n");
dev_kfree_skb(skb);
@@ -360,7 +367,7 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
dev_kfree_skb(skb);
dev->stats.tx_dropped++;
}
return NETDEV_TX_OK;
goto out_release_neigh;
}
pr_debug("neigh %p, vccs %p\n", entry, entry->vccs);
ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc;
@@ -379,14 +386,14 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
old = xchg(&entry->vccs->xoff, 1); /* assume XOFF ... */
if (old) {
pr_warning("XOFF->XOFF transition\n");
return NETDEV_TX_OK;
goto out_release_neigh;
}
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
vcc->send(vcc, skb);
if (atm_may_send(vcc, 0)) {
entry->vccs->xoff = 0;
return NETDEV_TX_OK;
goto out_release_neigh;
}
spin_lock_irqsave(&clip_priv->xoff_lock, flags);
netif_stop_queue(dev); /* XOFF -> throttle immediately */
@@ -398,6 +405,8 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
of the brief netif_stop_queue. If this isn't true or if it
changes, use netif_wake_queue instead. */
spin_unlock_irqrestore(&clip_priv->xoff_lock, flags);
out_release_neigh:
neigh_release(n);
return NETDEV_TX_OK;
}

View File

@@ -44,7 +44,7 @@
#include <linux/atmdev.h>
#include <linux/capability.h>
#include <linux/ppp_defs.h>
#include <linux/if_ppp.h>
#include <linux/ppp-ioctl.h>
#include <linux/ppp_channel.h>
#include <linux/atmppp.h>

View File

@@ -1,5 +1,5 @@
#
# Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
# Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
#
# Marek Lindner, Simon Wunderlich
#

View File

@@ -1,7 +1,7 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2011-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
* Marek Lindner
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -19,17 +19,9 @@
*
*/
#ifndef _NET_BATMAN_ADV_OGM_H_
#define _NET_BATMAN_ADV_OGM_H_
#ifndef _NET_BATMAN_ADV_BAT_ALGO_H_
#define _NET_BATMAN_ADV_BAT_ALGO_H_
#include "main.h"
int bat_iv_init(void);
void bat_ogm_init(struct hard_iface *hard_iface);
void bat_ogm_init_primary(struct hard_iface *hard_iface);
void bat_ogm_update_mac(struct hard_iface *hard_iface);
void bat_ogm_schedule(struct hard_iface *hard_iface, int tt_num_changes);
void bat_ogm_emit(struct forw_packet *forw_packet);
void bat_ogm_receive(const struct ethhdr *ethhdr, unsigned char *packet_buff,
int packet_len, struct hard_iface *if_incoming);
#endif /* _NET_BATMAN_ADV_OGM_H_ */
#endif /* _NET_BATMAN_ADV_BAT_ALGO_H_ */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*
@@ -221,6 +221,11 @@ static void debug_log_cleanup(struct bat_priv *bat_priv)
}
#endif
static int bat_algorithms_open(struct inode *inode, struct file *file)
{
return single_open(file, bat_algo_seq_print_text, NULL);
}
static int originators_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
@@ -274,6 +279,7 @@ struct bat_debuginfo bat_debuginfo_##_name = { \
} \
};
static BAT_DEBUGINFO(routing_algos, S_IRUGO, bat_algorithms_open);
static BAT_DEBUGINFO(originators, S_IRUGO, originators_open);
static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open);
static BAT_DEBUGINFO(softif_neigh, S_IRUGO, softif_neigh_open);
@@ -293,9 +299,25 @@ static struct bat_debuginfo *mesh_debuginfos[] = {
void debugfs_init(void)
{
struct bat_debuginfo *bat_debug;
struct dentry *file;
bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL);
if (bat_debugfs == ERR_PTR(-ENODEV))
bat_debugfs = NULL;
if (!bat_debugfs)
goto out;
bat_debug = &bat_debuginfo_routing_algos;
file = debugfs_create_file(bat_debug->attr.name,
S_IFREG | bat_debug->attr.mode,
bat_debugfs, NULL, &bat_debug->fops);
if (!file)
pr_err("Can't add debugfs file: %s\n", bat_debug->attr.name);
out:
return;
}
void debugfs_destroy(void)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*
@@ -20,7 +20,6 @@
*/
#include "main.h"
#include "bat_ogm.h"
#include "translation-table.h"
#include "ring_buffer.h"
#include "originator.h"
@@ -29,8 +28,9 @@
#include "gateway_client.h"
#include "hard-interface.h"
#include "send.h"
#include "bat_algo.h"
void bat_ogm_init(struct hard_iface *hard_iface)
static void bat_iv_ogm_init(struct hard_iface *hard_iface)
{
struct batman_ogm_packet *batman_ogm_packet;
@@ -38,25 +38,25 @@ void bat_ogm_init(struct hard_iface *hard_iface)
hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC);
batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
batman_ogm_packet->packet_type = BAT_OGM;
batman_ogm_packet->version = COMPAT_VERSION;
batman_ogm_packet->header.packet_type = BAT_OGM;
batman_ogm_packet->header.version = COMPAT_VERSION;
batman_ogm_packet->header.ttl = 2;
batman_ogm_packet->flags = NO_FLAGS;
batman_ogm_packet->ttl = 2;
batman_ogm_packet->tq = TQ_MAX_VALUE;
batman_ogm_packet->tt_num_changes = 0;
batman_ogm_packet->ttvn = 0;
}
void bat_ogm_init_primary(struct hard_iface *hard_iface)
static void bat_iv_ogm_init_primary(struct hard_iface *hard_iface)
{
struct batman_ogm_packet *batman_ogm_packet;
batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
batman_ogm_packet->flags = PRIMARIES_FIRST_HOP;
batman_ogm_packet->ttl = TTL;
batman_ogm_packet->header.ttl = TTL;
}
void bat_ogm_update_mac(struct hard_iface *hard_iface)
static void bat_iv_ogm_update_mac(struct hard_iface *hard_iface)
{
struct batman_ogm_packet *batman_ogm_packet;
@@ -68,7 +68,7 @@ void bat_ogm_update_mac(struct hard_iface *hard_iface)
}
/* when do we schedule our own ogm to be sent */
static unsigned long bat_ogm_emit_send_time(const struct bat_priv *bat_priv)
static unsigned long bat_iv_ogm_emit_send_time(const struct bat_priv *bat_priv)
{
return jiffies + msecs_to_jiffies(
atomic_read(&bat_priv->orig_interval) -
@@ -76,7 +76,7 @@ static unsigned long bat_ogm_emit_send_time(const struct bat_priv *bat_priv)
}
/* when do we schedule a ogm packet to be sent */
static unsigned long bat_ogm_fwd_send_time(void)
static unsigned long bat_iv_ogm_fwd_send_time(void)
{
return jiffies + msecs_to_jiffies(random32() % (JITTER/2));
}
@@ -89,8 +89,8 @@ static uint8_t hop_penalty(uint8_t tq, const struct bat_priv *bat_priv)
}
/* is there another aggregated packet here? */
static int bat_ogm_aggr_packet(int buff_pos, int packet_len,
int tt_num_changes)
static int bat_iv_ogm_aggr_packet(int buff_pos, int packet_len,
int tt_num_changes)
{
int next_buff_pos = buff_pos + BATMAN_OGM_LEN + tt_len(tt_num_changes);
@@ -99,8 +99,8 @@ static int bat_ogm_aggr_packet(int buff_pos, int packet_len,
}
/* send a batman ogm to a given interface */
static void bat_ogm_send_to_if(struct forw_packet *forw_packet,
struct hard_iface *hard_iface)
static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet,
struct hard_iface *hard_iface)
{
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
char *fwd_str;
@@ -117,8 +117,8 @@ static void bat_ogm_send_to_if(struct forw_packet *forw_packet,
batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data;
/* adjust all flags and log packets */
while (bat_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
batman_ogm_packet->tt_num_changes)) {
while (bat_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
batman_ogm_packet->tt_num_changes)) {
/* we might have aggregated direct link packets with an
* ordinary base packet */
@@ -132,12 +132,11 @@ static void bat_ogm_send_to_if(struct forw_packet *forw_packet,
"Sending own" :
"Forwarding"));
bat_dbg(DBG_BATMAN, bat_priv,
"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d,"
" IDF %s, ttvn %d) on interface %s [%pM]\n",
"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n",
fwd_str, (packet_num > 0 ? "aggregated " : ""),
batman_ogm_packet->orig,
ntohl(batman_ogm_packet->seqno),
batman_ogm_packet->tq, batman_ogm_packet->ttl,
batman_ogm_packet->tq, batman_ogm_packet->header.ttl,
(batman_ogm_packet->flags & DIRECTLINK ?
"on" : "off"),
batman_ogm_packet->ttvn, hard_iface->net_dev->name,
@@ -157,7 +156,7 @@ static void bat_ogm_send_to_if(struct forw_packet *forw_packet,
}
/* send a batman ogm packet */
void bat_ogm_emit(struct forw_packet *forw_packet)
static void bat_iv_ogm_emit(struct forw_packet *forw_packet)
{
struct hard_iface *hard_iface;
struct net_device *soft_iface;
@@ -171,8 +170,7 @@ void bat_ogm_emit(struct forw_packet *forw_packet)
directlink = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0);
if (!forw_packet->if_incoming) {
pr_err("Error - can't forward packet: incoming iface not "
"specified\n");
pr_err("Error - can't forward packet: incoming iface not specified\n");
goto out;
}
@@ -188,17 +186,16 @@ void bat_ogm_emit(struct forw_packet *forw_packet)
/* multihomed peer assumed */
/* non-primary OGMs are only broadcasted on their interface */
if ((directlink && (batman_ogm_packet->ttl == 1)) ||
if ((directlink && (batman_ogm_packet->header.ttl == 1)) ||
(forw_packet->own && (forw_packet->if_incoming != primary_if))) {
/* FIXME: what about aggregated packets ? */
bat_dbg(DBG_BATMAN, bat_priv,
"%s packet (originator %pM, seqno %d, TTL %d) "
"on interface %s [%pM]\n",
"%s packet (originator %pM, seqno %d, TTL %d) on interface %s [%pM]\n",
(forw_packet->own ? "Sending own" : "Forwarding"),
batman_ogm_packet->orig,
ntohl(batman_ogm_packet->seqno),
batman_ogm_packet->ttl,
batman_ogm_packet->header.ttl,
forw_packet->if_incoming->net_dev->name,
forw_packet->if_incoming->net_dev->dev_addr);
@@ -216,7 +213,7 @@ void bat_ogm_emit(struct forw_packet *forw_packet)
if (hard_iface->soft_iface != soft_iface)
continue;
bat_ogm_send_to_if(forw_packet, hard_iface);
bat_iv_ogm_send_to_if(forw_packet, hard_iface);
}
rcu_read_unlock();
@@ -226,13 +223,13 @@ out:
}
/* return true if new_packet can be aggregated with forw_packet */
static bool bat_ogm_can_aggregate(const struct batman_ogm_packet
static bool bat_iv_ogm_can_aggregate(const struct batman_ogm_packet
*new_batman_ogm_packet,
struct bat_priv *bat_priv,
int packet_len, unsigned long send_time,
bool directlink,
const struct hard_iface *if_incoming,
const struct forw_packet *forw_packet)
struct bat_priv *bat_priv,
int packet_len, unsigned long send_time,
bool directlink,
const struct hard_iface *if_incoming,
const struct forw_packet *forw_packet)
{
struct batman_ogm_packet *batman_ogm_packet;
int aggregated_bytes = forw_packet->packet_len + packet_len;
@@ -272,7 +269,7 @@ static bool bat_ogm_can_aggregate(const struct batman_ogm_packet
* are flooded through the net */
if ((!directlink) &&
(!(batman_ogm_packet->flags & DIRECTLINK)) &&
(batman_ogm_packet->ttl != 1) &&
(batman_ogm_packet->header.ttl != 1) &&
/* own packets originating non-primary
* interfaces leave only that interface */
@@ -285,7 +282,7 @@ static bool bat_ogm_can_aggregate(const struct batman_ogm_packet
/* if the incoming packet is sent via this one
* interface only - we still can aggregate */
if ((directlink) &&
(new_batman_ogm_packet->ttl == 1) &&
(new_batman_ogm_packet->header.ttl == 1) &&
(forw_packet->if_incoming == if_incoming) &&
/* packets from direct neighbors or
@@ -306,11 +303,11 @@ out:
}
/* create a new aggregated packet and add this packet to it */
static void bat_ogm_aggregate_new(const unsigned char *packet_buff,
int packet_len, unsigned long send_time,
bool direct_link,
struct hard_iface *if_incoming,
int own_packet)
static void bat_iv_ogm_aggregate_new(const unsigned char *packet_buff,
int packet_len, unsigned long send_time,
bool direct_link,
struct hard_iface *if_incoming,
int own_packet)
{
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct forw_packet *forw_packet_aggr;
@@ -385,9 +382,9 @@ out:
}
/* aggregate a new packet into the existing ogm packet */
static void bat_ogm_aggregate(struct forw_packet *forw_packet_aggr,
const unsigned char *packet_buff,
int packet_len, bool direct_link)
static void bat_iv_ogm_aggregate(struct forw_packet *forw_packet_aggr,
const unsigned char *packet_buff,
int packet_len, bool direct_link)
{
unsigned char *skb_buff;
@@ -402,10 +399,10 @@ static void bat_ogm_aggregate(struct forw_packet *forw_packet_aggr,
(1 << forw_packet_aggr->num_packets);
}
static void bat_ogm_queue_add(struct bat_priv *bat_priv,
unsigned char *packet_buff,
int packet_len, struct hard_iface *if_incoming,
int own_packet, unsigned long send_time)
static void bat_iv_ogm_queue_add(struct bat_priv *bat_priv,
unsigned char *packet_buff,
int packet_len, struct hard_iface *if_incoming,
int own_packet, unsigned long send_time)
{
/**
* _aggr -> pointer to the packet we want to aggregate with
@@ -425,11 +422,11 @@ static void bat_ogm_queue_add(struct bat_priv *bat_priv,
if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) {
hlist_for_each_entry(forw_packet_pos, tmp_node,
&bat_priv->forw_bat_list, list) {
if (bat_ogm_can_aggregate(batman_ogm_packet,
bat_priv, packet_len,
send_time, direct_link,
if_incoming,
forw_packet_pos)) {
if (bat_iv_ogm_can_aggregate(batman_ogm_packet,
bat_priv, packet_len,
send_time, direct_link,
if_incoming,
forw_packet_pos)) {
forw_packet_aggr = forw_packet_pos;
break;
}
@@ -451,27 +448,27 @@ static void bat_ogm_queue_add(struct bat_priv *bat_priv,
(atomic_read(&bat_priv->aggregated_ogms)))
send_time += msecs_to_jiffies(MAX_AGGREGATION_MS);
bat_ogm_aggregate_new(packet_buff, packet_len,
send_time, direct_link,
if_incoming, own_packet);
bat_iv_ogm_aggregate_new(packet_buff, packet_len,
send_time, direct_link,
if_incoming, own_packet);
} else {
bat_ogm_aggregate(forw_packet_aggr, packet_buff, packet_len,
direct_link);
bat_iv_ogm_aggregate(forw_packet_aggr, packet_buff,
packet_len, direct_link);
spin_unlock_bh(&bat_priv->forw_bat_list_lock);
}
}
static void bat_ogm_forward(struct orig_node *orig_node,
const struct ethhdr *ethhdr,
struct batman_ogm_packet *batman_ogm_packet,
int directlink, struct hard_iface *if_incoming)
static void bat_iv_ogm_forward(struct orig_node *orig_node,
const struct ethhdr *ethhdr,
struct batman_ogm_packet *batman_ogm_packet,
int directlink, struct hard_iface *if_incoming)
{
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct neigh_node *router;
uint8_t in_tq, in_ttl, tq_avg = 0;
uint8_t tt_num_changes;
if (batman_ogm_packet->ttl <= 1) {
if (batman_ogm_packet->header.ttl <= 1) {
bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n");
return;
}
@@ -479,10 +476,10 @@ static void bat_ogm_forward(struct orig_node *orig_node,
router = orig_node_get_router(orig_node);
in_tq = batman_ogm_packet->tq;
in_ttl = batman_ogm_packet->ttl;
in_ttl = batman_ogm_packet->header.ttl;
tt_num_changes = batman_ogm_packet->tt_num_changes;
batman_ogm_packet->ttl--;
batman_ogm_packet->header.ttl--;
memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
/* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
@@ -494,7 +491,8 @@ static void bat_ogm_forward(struct orig_node *orig_node,
batman_ogm_packet->tq = router->tq_avg;
if (router->last_ttl)
batman_ogm_packet->ttl = router->last_ttl - 1;
batman_ogm_packet->header.ttl =
router->last_ttl - 1;
}
tq_avg = router->tq_avg;
@@ -507,10 +505,9 @@ static void bat_ogm_forward(struct orig_node *orig_node,
batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv);
bat_dbg(DBG_BATMAN, bat_priv,
"Forwarding packet: tq_orig: %i, tq_avg: %i, "
"tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n",
"Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n",
in_tq, tq_avg, batman_ogm_packet->tq, in_ttl - 1,
batman_ogm_packet->ttl);
batman_ogm_packet->header.ttl);
batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno);
batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc);
@@ -522,12 +519,13 @@ static void bat_ogm_forward(struct orig_node *orig_node,
else
batman_ogm_packet->flags &= ~DIRECTLINK;
bat_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet,
BATMAN_OGM_LEN + tt_len(tt_num_changes),
if_incoming, 0, bat_ogm_fwd_send_time());
bat_iv_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet,
BATMAN_OGM_LEN + tt_len(tt_num_changes),
if_incoming, 0, bat_iv_ogm_fwd_send_time());
}
void bat_ogm_schedule(struct hard_iface *hard_iface, int tt_num_changes)
static void bat_iv_ogm_schedule(struct hard_iface *hard_iface,
int tt_num_changes)
{
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct batman_ogm_packet *batman_ogm_packet;
@@ -564,21 +562,22 @@ void bat_ogm_schedule(struct hard_iface *hard_iface, int tt_num_changes)
atomic_inc(&hard_iface->seqno);
slide_own_bcast_window(hard_iface);
bat_ogm_queue_add(bat_priv, hard_iface->packet_buff,
hard_iface->packet_len, hard_iface, 1,
bat_ogm_emit_send_time(bat_priv));
bat_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff,
hard_iface->packet_len, hard_iface, 1,
bat_iv_ogm_emit_send_time(bat_priv));
if (primary_if)
hardif_free_ref(primary_if);
}
static void bat_ogm_orig_update(struct bat_priv *bat_priv,
struct orig_node *orig_node,
const struct ethhdr *ethhdr,
const struct batman_ogm_packet
static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv,
struct orig_node *orig_node,
const struct ethhdr *ethhdr,
const struct batman_ogm_packet
*batman_ogm_packet,
struct hard_iface *if_incoming,
const unsigned char *tt_buff, int is_duplicate)
struct hard_iface *if_incoming,
const unsigned char *tt_buff,
int is_duplicate)
{
struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
struct neigh_node *router = NULL;
@@ -586,8 +585,8 @@ static void bat_ogm_orig_update(struct bat_priv *bat_priv,
struct hlist_node *node;
uint8_t bcast_own_sum_orig, bcast_own_sum_neigh;
bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): "
"Searching and updating originator entry of received packet\n");
bat_dbg(DBG_BATMAN, bat_priv,
"update_originator(): Searching and updating originator entry of received packet\n");
rcu_read_lock();
hlist_for_each_entry_rcu(tmp_neigh_node, node,
@@ -642,8 +641,8 @@ static void bat_ogm_orig_update(struct bat_priv *bat_priv,
spin_unlock_bh(&neigh_node->tq_lock);
if (!is_duplicate) {
orig_node->last_ttl = batman_ogm_packet->ttl;
neigh_node->last_ttl = batman_ogm_packet->ttl;
orig_node->last_ttl = batman_ogm_packet->header.ttl;
neigh_node->last_ttl = batman_ogm_packet->header.ttl;
}
bonding_candidate_add(orig_node, neigh_node);
@@ -683,7 +682,7 @@ update_tt:
/* I have to check for transtable changes only if the OGM has been
* sent through a primary interface */
if (((batman_ogm_packet->orig != ethhdr->h_source) &&
(batman_ogm_packet->ttl > 2)) ||
(batman_ogm_packet->header.ttl > 2)) ||
(batman_ogm_packet->flags & PRIMARIES_FIRST_HOP))
tt_update_orig(bat_priv, orig_node, tt_buff,
batman_ogm_packet->tt_num_changes,
@@ -713,10 +712,10 @@ out:
neigh_node_free_ref(router);
}
static int bat_ogm_calc_tq(struct orig_node *orig_node,
struct orig_node *orig_neigh_node,
struct batman_ogm_packet *batman_ogm_packet,
struct hard_iface *if_incoming)
static int bat_iv_ogm_calc_tq(struct orig_node *orig_node,
struct orig_node *orig_neigh_node,
struct batman_ogm_packet *batman_ogm_packet,
struct hard_iface *if_incoming)
{
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct neigh_node *neigh_node = NULL, *tmp_neigh_node;
@@ -780,8 +779,7 @@ static int bat_ogm_calc_tq(struct orig_node *orig_node,
* information */
tq_own = (TQ_MAX_VALUE * total_count) / neigh_rq_count;
/*
* 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
/* 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
* affect the nearly-symmetric links only a little, but
* punishes asymmetric links more. This will give a value
* between 0 and TQ_MAX_VALUE
@@ -799,10 +797,7 @@ static int bat_ogm_calc_tq(struct orig_node *orig_node,
(TQ_MAX_VALUE * TQ_MAX_VALUE));
bat_dbg(DBG_BATMAN, bat_priv,
"bidirectional: "
"orig = %-15pM neigh = %-15pM => own_bcast = %2i, "
"real recv = %2i, local tq: %3i, asym_penalty: %3i, "
"total tq: %3i\n",
"bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n",
orig_node->orig, orig_neigh_node->orig, total_count,
neigh_rq_count, tq_own, tq_asym_penalty, batman_ogm_packet->tq);
@@ -825,10 +820,10 @@ out:
* -1 the packet is old and has been received while the seqno window
* was protected. Caller should drop it.
*/
static int bat_ogm_update_seqnos(const struct ethhdr *ethhdr,
const struct batman_ogm_packet
static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
const struct batman_ogm_packet
*batman_ogm_packet,
const struct hard_iface *if_incoming)
const struct hard_iface *if_incoming)
{
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct orig_node *orig_node;
@@ -890,10 +885,10 @@ out:
return ret;
}
static void bat_ogm_process(const struct ethhdr *ethhdr,
struct batman_ogm_packet *batman_ogm_packet,
const unsigned char *tt_buff,
struct hard_iface *if_incoming)
static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
struct batman_ogm_packet *batman_ogm_packet,
const unsigned char *tt_buff,
struct hard_iface *if_incoming)
{
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct hard_iface *hard_iface;
@@ -918,7 +913,7 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
* packet in an aggregation. Here we expect that the padding
* is always zero (or not 0x01)
*/
if (batman_ogm_packet->packet_type != BAT_OGM)
if (batman_ogm_packet->header.packet_type != BAT_OGM)
return;
/* could be changed by schedule_own_packet() */
@@ -930,16 +925,14 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
batman_ogm_packet->orig) ? 1 : 0);
bat_dbg(DBG_BATMAN, bat_priv,
"Received BATMAN packet via NB: %pM, IF: %s [%pM] "
"(from OG: %pM, via prev OG: %pM, seqno %d, ttvn %u, "
"crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n",
"Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %d, ttvn %u, crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n",
ethhdr->h_source, if_incoming->net_dev->name,
if_incoming->net_dev->dev_addr, batman_ogm_packet->orig,
batman_ogm_packet->prev_sender, batman_ogm_packet->seqno,
batman_ogm_packet->ttvn, batman_ogm_packet->tt_crc,
batman_ogm_packet->tt_num_changes, batman_ogm_packet->tq,
batman_ogm_packet->ttl, batman_ogm_packet->version,
has_directlink_flag);
batman_ogm_packet->header.ttl,
batman_ogm_packet->header.version, has_directlink_flag);
rcu_read_lock();
list_for_each_entry_rcu(hard_iface, &hardif_list, list) {
@@ -966,25 +959,24 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
}
rcu_read_unlock();
if (batman_ogm_packet->version != COMPAT_VERSION) {
if (batman_ogm_packet->header.version != COMPAT_VERSION) {
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: incompatible batman version (%i)\n",
batman_ogm_packet->version);
batman_ogm_packet->header.version);
return;
}
if (is_my_addr) {
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: received my own broadcast (sender: %pM"
")\n",
"Drop packet: received my own broadcast (sender: %pM)\n",
ethhdr->h_source);
return;
}
if (is_broadcast) {
bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
"ignoring all packets with broadcast source addr (sender: %pM"
")\n", ethhdr->h_source);
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: ignoring all packets with broadcast source addr (sender: %pM)\n",
ethhdr->h_source);
return;
}
@@ -1014,16 +1006,16 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock);
}
bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
"originator packet from myself (via neighbor)\n");
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: originator packet from myself (via neighbor)\n");
orig_node_free_ref(orig_neigh_node);
return;
}
if (is_my_oldorig) {
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: ignoring all rebroadcast echos (sender: "
"%pM)\n", ethhdr->h_source);
"Drop packet: ignoring all rebroadcast echos (sender: %pM)\n",
ethhdr->h_source);
return;
}
@@ -1031,13 +1023,13 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
if (!orig_node)
return;
is_duplicate = bat_ogm_update_seqnos(ethhdr, batman_ogm_packet,
if_incoming);
is_duplicate = bat_iv_ogm_update_seqnos(ethhdr, batman_ogm_packet,
if_incoming);
if (is_duplicate == -1) {
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: packet within seqno protection time "
"(sender: %pM)\n", ethhdr->h_source);
"Drop packet: packet within seqno protection time (sender: %pM)\n",
ethhdr->h_source);
goto out;
}
@@ -1058,8 +1050,8 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
batman_ogm_packet->prev_sender)) &&
(compare_eth(router->addr, router_router->addr))) {
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: ignoring all rebroadcast packets that "
"may make me loop (sender: %pM)\n", ethhdr->h_source);
"Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n",
ethhdr->h_source);
goto out;
}
@@ -1081,8 +1073,8 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
goto out_neigh;
}
is_bidirectional = bat_ogm_calc_tq(orig_node, orig_neigh_node,
batman_ogm_packet, if_incoming);
is_bidirectional = bat_iv_ogm_calc_tq(orig_node, orig_neigh_node,
batman_ogm_packet, if_incoming);
bonding_save_primary(orig_node, orig_neigh_node, batman_ogm_packet);
@@ -1091,20 +1083,20 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
if (is_bidirectional &&
(!is_duplicate ||
((orig_node->last_real_seqno == batman_ogm_packet->seqno) &&
(orig_node->last_ttl - 3 <= batman_ogm_packet->ttl))))
bat_ogm_orig_update(bat_priv, orig_node, ethhdr,
batman_ogm_packet, if_incoming,
tt_buff, is_duplicate);
(orig_node->last_ttl - 3 <= batman_ogm_packet->header.ttl))))
bat_iv_ogm_orig_update(bat_priv, orig_node, ethhdr,
batman_ogm_packet, if_incoming,
tt_buff, is_duplicate);
/* is single hop (direct) neighbor */
if (is_single_hop_neigh) {
/* mark direct link on incoming interface */
bat_ogm_forward(orig_node, ethhdr, batman_ogm_packet,
1, if_incoming);
bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet,
1, if_incoming);
bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
"rebroadcast neighbor packet with direct link flag\n");
bat_dbg(DBG_BATMAN, bat_priv,
"Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
goto out_neigh;
}
@@ -1123,7 +1115,8 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
bat_dbg(DBG_BATMAN, bat_priv,
"Forwarding packet: rebroadcast originator packet\n");
bat_ogm_forward(orig_node, ethhdr, batman_ogm_packet, 0, if_incoming);
bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet,
0, if_incoming);
out_neigh:
if ((orig_neigh_node) && (!is_single_hop_neigh))
@@ -1139,13 +1132,17 @@ out:
orig_node_free_ref(orig_node);
}
void bat_ogm_receive(const struct ethhdr *ethhdr, unsigned char *packet_buff,
int packet_len, struct hard_iface *if_incoming)
static void bat_iv_ogm_receive(struct hard_iface *if_incoming,
struct sk_buff *skb)
{
struct batman_ogm_packet *batman_ogm_packet;
int buff_pos = 0;
unsigned char *tt_buff;
struct ethhdr *ethhdr;
int buff_pos = 0, packet_len;
unsigned char *tt_buff, *packet_buff;
packet_len = skb_headlen(skb);
ethhdr = (struct ethhdr *)skb_mac_header(skb);
packet_buff = skb->data;
batman_ogm_packet = (struct batman_ogm_packet *)packet_buff;
/* unpack the aggregated packets and process them one by one */
@@ -1157,14 +1154,29 @@ void bat_ogm_receive(const struct ethhdr *ethhdr, unsigned char *packet_buff,
tt_buff = packet_buff + buff_pos + BATMAN_OGM_LEN;
bat_ogm_process(ethhdr, batman_ogm_packet,
tt_buff, if_incoming);
bat_iv_ogm_process(ethhdr, batman_ogm_packet,
tt_buff, if_incoming);
buff_pos += BATMAN_OGM_LEN +
tt_len(batman_ogm_packet->tt_num_changes);
batman_ogm_packet = (struct batman_ogm_packet *)
(packet_buff + buff_pos);
} while (bat_ogm_aggr_packet(buff_pos, packet_len,
batman_ogm_packet->tt_num_changes));
} while (bat_iv_ogm_aggr_packet(buff_pos, packet_len,
batman_ogm_packet->tt_num_changes));
}
static struct bat_algo_ops batman_iv __read_mostly = {
.name = "BATMAN IV",
.bat_ogm_init = bat_iv_ogm_init,
.bat_ogm_init_primary = bat_iv_ogm_init_primary,
.bat_ogm_update_mac = bat_iv_ogm_update_mac,
.bat_ogm_schedule = bat_iv_ogm_schedule,
.bat_ogm_emit = bat_iv_ogm_emit,
.bat_ogm_receive = bat_iv_ogm_receive,
};
int __init bat_iv_init(void)
{
return bat_algo_register(&batman_iv);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*
@@ -255,8 +255,8 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
buff[count - 1] = '\0';
bat_info(net_dev,
"Invalid parameter for 'vis mode' setting received: "
"%s\n", buff);
"Invalid parameter for 'vis mode' setting received: %s\n",
buff);
return -EINVAL;
}
@@ -272,6 +272,13 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
return count;
}
static ssize_t show_bat_algo(struct kobject *kobj, struct attribute *attr,
char *buff)
{
struct bat_priv *bat_priv = kobj_to_batpriv(kobj);
return sprintf(buff, "%s\n", bat_priv->bat_algo_ops->name);
}
static void post_gw_deselect(struct net_device *net_dev)
{
struct bat_priv *bat_priv = netdev_priv(net_dev);
@@ -314,17 +321,17 @@ static ssize_t store_gw_mode(struct kobject *kobj, struct attribute *attr,
gw_mode_tmp = GW_MODE_OFF;
if (strncmp(buff, GW_MODE_CLIENT_NAME,
strlen(GW_MODE_CLIENT_NAME)) == 0)
strlen(GW_MODE_CLIENT_NAME)) == 0)
gw_mode_tmp = GW_MODE_CLIENT;
if (strncmp(buff, GW_MODE_SERVER_NAME,
strlen(GW_MODE_SERVER_NAME)) == 0)
strlen(GW_MODE_SERVER_NAME)) == 0)
gw_mode_tmp = GW_MODE_SERVER;
if (gw_mode_tmp < 0) {
bat_info(net_dev,
"Invalid parameter for 'gw mode' setting received: "
"%s\n", buff);
"Invalid parameter for 'gw mode' setting received: %s\n",
buff);
return -EINVAL;
}
@@ -382,6 +389,7 @@ BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu);
BAT_ATTR_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
static BAT_ATTR(routing_algo, S_IRUGO, show_bat_algo, NULL);
static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode);
BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL);
BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL);
@@ -399,6 +407,7 @@ static struct bat_attribute *mesh_attrs[] = {
&bat_attr_fragmentation,
&bat_attr_ap_isolation,
&bat_attr_vis_mode,
&bat_attr_routing_algo,
&bat_attr_gw_mode,
&bat_attr_orig_interval,
&bat_attr_hop_penalty,
@@ -493,8 +502,8 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
buff[count - 1] = '\0';
if (strlen(buff) >= IFNAMSIZ) {
pr_err("Invalid parameter for 'mesh_iface' setting received: "
"interface name too long '%s'\n", buff);
pr_err("Invalid parameter for 'mesh_iface' setting received: interface name too long '%s'\n",
buff);
hardif_free_ref(hard_iface);
return -EINVAL;
}
@@ -668,8 +677,8 @@ out:
hardif_free_ref(primary_if);
if (ret)
bat_dbg(DBG_BATMAN, bat_priv, "Impossible to send "
"uevent for (%s,%s,%s) event (err: %d)\n",
bat_dbg(DBG_BATMAN, bat_priv,
"Impossible to send uevent for (%s,%s,%s) event (err: %d)\n",
uev_type_str[type], uev_action_str[action],
(action == UEV_DEL ? "NULL" : data), ret);
return ret;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2006-2012 B.A.T.M.A.N. contributors:
*
* Simon Wunderlich, Marek Lindner
*
@@ -154,8 +154,8 @@ int bit_get_packet(void *priv, unsigned long *seq_bits,
/* sequence number is much newer, probably missed a lot of packets */
if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE)
&& (seq_num_diff < EXPECTED_SEQNO_RANGE)) {
if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE) &&
(seq_num_diff < EXPECTED_SEQNO_RANGE)) {
bat_dbg(DBG_BATMAN, bat_priv,
"We missed a lot of packets (%i) !\n",
seq_num_diff - 1);
@@ -170,8 +170,8 @@ int bit_get_packet(void *priv, unsigned long *seq_bits,
* packet should be dropped without calling this function if the
* seqno window is protected. */
if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
|| (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) ||
(seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
bat_dbg(DBG_BATMAN, bat_priv,
"Other host probably restarted!\n");

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2006-2012 B.A.T.M.A.N. contributors:
*
* Simon Wunderlich, Marek Lindner
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2009-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*
@@ -224,16 +224,13 @@ void gw_election(struct bat_priv *bat_priv)
} else if ((!curr_gw) && (next_gw)) {
bat_dbg(DBG_BATMAN, bat_priv,
"Adding route to gateway %pM (gw_flags: %i, tq: %i)\n",
next_gw->orig_node->orig,
next_gw->orig_node->gw_flags,
next_gw->orig_node->orig, next_gw->orig_node->gw_flags,
router->tq_avg);
throw_uevent(bat_priv, UEV_GW, UEV_ADD, gw_addr);
} else {
bat_dbg(DBG_BATMAN, bat_priv,
"Changing route to gateway %pM "
"(gw_flags: %i, tq: %i)\n",
next_gw->orig_node->orig,
next_gw->orig_node->gw_flags,
"Changing route to gateway %pM (gw_flags: %i, tq: %i)\n",
next_gw->orig_node->orig, next_gw->orig_node->gw_flags,
router->tq_avg);
throw_uevent(bat_priv, UEV_GW, UEV_CHANGE, gw_addr);
}
@@ -287,8 +284,7 @@ void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node)
goto out;
bat_dbg(DBG_BATMAN, bat_priv,
"Restarting gateway selection: better gateway found (tq curr: "
"%i, tq new: %i)\n",
"Restarting gateway selection: better gateway found (tq curr: %i, tq new: %i)\n",
gw_tq_avg, orig_tq_avg);
deselect:
@@ -352,8 +348,7 @@ void gw_node_update(struct bat_priv *bat_priv,
continue;
bat_dbg(DBG_BATMAN, bat_priv,
"Gateway class of originator %pM changed from "
"%i to %i\n",
"Gateway class of originator %pM changed from %i to %i\n",
orig_node->orig, gw_node->orig_node->gw_flags,
new_gwflags);
@@ -396,7 +391,7 @@ void gw_node_purge(struct bat_priv *bat_priv)
{
struct gw_node *gw_node, *curr_gw;
struct hlist_node *node, *node_tmp;
unsigned long timeout = 2 * PURGE_TIMEOUT * HZ;
unsigned long timeout = msecs_to_jiffies(2 * PURGE_TIMEOUT);
int do_deselect = 0;
curr_gw = gw_get_selected_gw_node(bat_priv);
@@ -474,23 +469,23 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset)
primary_if = primary_if_get_selected(bat_priv);
if (!primary_if) {
ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
"specify interfaces to enable it\n",
ret = seq_printf(seq,
"BATMAN mesh %s disabled - please specify interfaces to enable it\n",
net_dev->name);
goto out;
}
if (primary_if->if_status != IF_ACTIVE) {
ret = seq_printf(seq, "BATMAN mesh %s disabled - "
"primary interface not active\n",
ret = seq_printf(seq,
"BATMAN mesh %s disabled - primary interface not active\n",
net_dev->name);
goto out;
}
seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... "
"[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
"Gateway", "#", TQ_MAX_VALUE, "Nexthop",
"outgoingIF", SOURCE_VERSION, primary_if->net_dev->name,
seq_printf(seq,
" %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
"Gateway", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF",
SOURCE_VERSION, primary_if->net_dev->name,
primary_if->net_dev->dev_addr, net_dev->name);
rcu_read_lock();
@@ -629,7 +624,7 @@ bool gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
/* check for bootp port */
if ((ntohs(ethhdr->h_proto) == ETH_P_IP) &&
(ntohs(udphdr->dest) != 67))
(ntohs(udphdr->dest) != 67))
return false;
if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) &&

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2009-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2009-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*
@@ -93,7 +93,7 @@ static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff,
multi = 1024;
if ((strnicmp(tmp_ptr, "kbit", 4) == 0) ||
(multi > 1))
(multi > 1))
*tmp_ptr = '\0';
}
@@ -118,15 +118,15 @@ static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff,
multi = 1024;
if ((strnicmp(tmp_ptr, "kbit", 4) == 0) ||
(multi > 1))
(multi > 1))
*tmp_ptr = '\0';
}
ret = kstrtol(slash_ptr + 1, 10, &lup);
if (ret) {
bat_err(net_dev,
"Upload speed of gateway mode invalid: "
"%s\n", slash_ptr + 1);
"Upload speed of gateway mode invalid: %s\n",
slash_ptr + 1);
return false;
}
@@ -163,8 +163,8 @@ ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count)
gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, &down, &up);
gw_deselect(bat_priv);
bat_info(net_dev, "Changing gateway bandwidth from: '%i' to: '%ld' "
"(propagating: %d%s/%d%s)\n",
bat_info(net_dev,
"Changing gateway bandwidth from: '%i' to: '%ld' (propagating: %d%s/%d%s)\n",
atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp,
(down > 2048 ? down / 1024 : down),
(down > 2048 ? "MBit" : "KBit"),

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2009-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*
@@ -28,7 +28,6 @@
#include "bat_sysfs.h"
#include "originator.h"
#include "hash.h"
#include "bat_ogm.h"
#include <linux/if_arp.h>
@@ -147,7 +146,7 @@ static void primary_if_select(struct bat_priv *bat_priv,
if (!new_hard_iface)
return;
bat_ogm_init_primary(new_hard_iface);
bat_priv->bat_algo_ops->bat_ogm_init_primary(new_hard_iface);
primary_if_update_addr(bat_priv);
}
@@ -176,11 +175,9 @@ static void check_known_mac_addr(const struct net_device *net_dev)
net_dev->dev_addr))
continue;
pr_warning("The newly added mac address (%pM) already exists "
"on: %s\n", net_dev->dev_addr,
hard_iface->net_dev->name);
pr_warning("It is strongly recommended to keep mac addresses "
"unique to avoid problems!\n");
pr_warning("The newly added mac address (%pM) already exists on: %s\n",
net_dev->dev_addr, hard_iface->net_dev->name);
pr_warning("It is strongly recommended to keep mac addresses unique to avoid problems!\n");
}
rcu_read_unlock();
}
@@ -233,7 +230,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface)
bat_priv = netdev_priv(hard_iface->soft_iface);
bat_ogm_update_mac(hard_iface);
bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface);
hard_iface->if_status = IF_TO_BE_ACTIVATED;
/**
@@ -281,6 +278,11 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
if (!atomic_inc_not_zero(&hard_iface->refcount))
goto out;
/* hard-interface is part of a bridge */
if (hard_iface->net_dev->priv_flags & IFF_BRIDGE_PORT)
pr_err("You are about to enable batman-adv on '%s' which already is part of a bridge. Unless you know exactly what you are doing this is probably wrong and won't work the way you think it would.\n",
hard_iface->net_dev->name);
soft_iface = dev_get_by_name(&init_net, iface_name);
if (!soft_iface) {
@@ -296,8 +298,7 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
}
if (!softif_is_valid(soft_iface)) {
pr_err("Can't create batman mesh interface %s: "
"already exists as regular interface\n",
pr_err("Can't create batman mesh interface %s: already exists as regular interface\n",
soft_iface->name);
dev_put(soft_iface);
ret = -EINVAL;
@@ -307,11 +308,12 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
hard_iface->soft_iface = soft_iface;
bat_priv = netdev_priv(hard_iface->soft_iface);
bat_ogm_init(hard_iface);
bat_priv->bat_algo_ops->bat_ogm_init(hard_iface);
if (!hard_iface->packet_buff) {
bat_err(hard_iface->soft_iface, "Can't add interface packet "
"(%s): out of memory\n", hard_iface->net_dev->name);
bat_err(hard_iface->soft_iface,
"Can't add interface packet (%s): out of memory\n",
hard_iface->net_dev->name);
ret = -ENOMEM;
goto err;
}
@@ -334,29 +336,22 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
if (atomic_read(&bat_priv->fragmentation) && hard_iface->net_dev->mtu <
ETH_DATA_LEN + BAT_HEADER_LEN)
bat_info(hard_iface->soft_iface,
"The MTU of interface %s is too small (%i) to handle "
"the transport of batman-adv packets. Packets going "
"over this interface will be fragmented on layer2 "
"which could impact the performance. Setting the MTU "
"to %zi would solve the problem.\n",
hard_iface->net_dev->name, hard_iface->net_dev->mtu,
ETH_DATA_LEN + BAT_HEADER_LEN);
"The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to %zi would solve the problem.\n",
hard_iface->net_dev->name, hard_iface->net_dev->mtu,
ETH_DATA_LEN + BAT_HEADER_LEN);
if (!atomic_read(&bat_priv->fragmentation) && hard_iface->net_dev->mtu <
ETH_DATA_LEN + BAT_HEADER_LEN)
bat_info(hard_iface->soft_iface,
"The MTU of interface %s is too small (%i) to handle "
"the transport of batman-adv packets. If you experience"
" problems getting traffic through try increasing the "
"MTU to %zi.\n",
hard_iface->net_dev->name, hard_iface->net_dev->mtu,
ETH_DATA_LEN + BAT_HEADER_LEN);
"The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. If you experience problems getting traffic through try increasing the MTU to %zi.\n",
hard_iface->net_dev->name, hard_iface->net_dev->mtu,
ETH_DATA_LEN + BAT_HEADER_LEN);
if (hardif_is_iface_up(hard_iface))
hardif_activate_interface(hard_iface);
else
bat_err(hard_iface->soft_iface, "Not using interface %s "
"(retrying later): interface not active\n",
bat_err(hard_iface->soft_iface,
"Not using interface %s (retrying later): interface not active\n",
hard_iface->net_dev->name);
/* begin scheduling originator messages on that interface */
@@ -527,9 +522,10 @@ static int hard_if_event(struct notifier_block *this,
goto hardif_put;
check_known_mac_addr(hard_iface->net_dev);
bat_ogm_update_mac(hard_iface);
bat_priv = netdev_priv(hard_iface->soft_iface);
bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface);
primary_if = primary_if_get_selected(bat_priv);
if (!primary_if)
goto hardif_put;
@@ -572,8 +568,8 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
goto err_free;
/* expect a valid ethernet header here. */
if (unlikely(skb->mac_len != sizeof(struct ethhdr)
|| !skb_mac_header(skb)))
if (unlikely(skb->mac_len != sizeof(struct ethhdr) ||
!skb_mac_header(skb)))
goto err_free;
if (!hard_iface->soft_iface)
@@ -590,17 +586,17 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
batman_ogm_packet = (struct batman_ogm_packet *)skb->data;
if (batman_ogm_packet->version != COMPAT_VERSION) {
if (batman_ogm_packet->header.version != COMPAT_VERSION) {
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: incompatible batman version (%i)\n",
batman_ogm_packet->version);
batman_ogm_packet->header.version);
goto err_free;
}
/* all receive handlers return whether they received or reused
* the supplied skb. if not, we have to free the skb. */
switch (batman_ogm_packet->packet_type) {
switch (batman_ogm_packet->header.packet_type) {
/* batman originator packet */
case BAT_OGM:
ret = recv_bat_ogm_packet(skb, hard_iface);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2006-2012 B.A.T.M.A.N. contributors:
*
* Simon Wunderlich, Marek Lindner
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2006-2012 B.A.T.M.A.N. contributors:
*
* Simon Wunderlich, Marek Lindner
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*
@@ -59,8 +59,7 @@ static int bat_socket_open(struct inode *inode, struct file *file)
}
if (i == ARRAY_SIZE(socket_client_hash)) {
pr_err("Error - can't add another packet client: "
"maximum number of clients reached\n");
pr_err("Error - can't add another packet client: maximum number of clients reached\n");
kfree(socket_client);
return -EXFULL;
}
@@ -162,8 +161,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
if (len < sizeof(struct icmp_packet)) {
bat_dbg(DBG_BATMAN, bat_priv,
"Error - can't send packet from char device: "
"invalid packet size\n");
"Error - can't send packet from char device: invalid packet size\n");
return -EINVAL;
}
@@ -191,27 +189,25 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
goto free_skb;
}
if (icmp_packet->packet_type != BAT_ICMP) {
if (icmp_packet->header.packet_type != BAT_ICMP) {
bat_dbg(DBG_BATMAN, bat_priv,
"Error - can't send packet from char device: "
"got bogus packet type (expected: BAT_ICMP)\n");
"Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
len = -EINVAL;
goto free_skb;
}
if (icmp_packet->msg_type != ECHO_REQUEST) {
bat_dbg(DBG_BATMAN, bat_priv,
"Error - can't send packet from char device: "
"got bogus message type (expected: ECHO_REQUEST)\n");
"Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
len = -EINVAL;
goto free_skb;
}
icmp_packet->uid = socket_client->index;
if (icmp_packet->version != COMPAT_VERSION) {
if (icmp_packet->header.version != COMPAT_VERSION) {
icmp_packet->msg_type = PARAMETER_PROBLEM;
icmp_packet->version = COMPAT_VERSION;
icmp_packet->header.version = COMPAT_VERSION;
bat_socket_add_packet(socket_client, icmp_packet, packet_len);
goto free_skb;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*
@@ -32,11 +32,14 @@
#include "gateway_client.h"
#include "vis.h"
#include "hash.h"
#include "bat_algo.h"
/* List manipulations on hardif_list have to be rtnl_lock()'ed,
* list traversals just rcu-locked */
struct list_head hardif_list;
char bat_routing_algo[20] = "BATMAN IV";
static struct hlist_head bat_algo_list;
unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -45,6 +48,9 @@ struct workqueue_struct *bat_event_workqueue;
static int __init batman_init(void)
{
INIT_LIST_HEAD(&hardif_list);
INIT_HLIST_HEAD(&bat_algo_list);
bat_iv_init();
/* the name should not be longer than 10 chars - see
* http://lwn.net/Articles/23634/ */
@@ -58,8 +64,8 @@ static int __init batman_init(void)
register_netdevice_notifier(&hard_if_notifier);
pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) "
"loaded\n", SOURCE_VERSION, COMPAT_VERSION);
pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n",
SOURCE_VERSION, COMPAT_VERSION);
return 0;
}
@@ -170,9 +176,110 @@ int is_my_mac(const uint8_t *addr)
}
rcu_read_unlock();
return 0;
}
static struct bat_algo_ops *bat_algo_get(char *name)
{
struct bat_algo_ops *bat_algo_ops = NULL, *bat_algo_ops_tmp;
struct hlist_node *node;
hlist_for_each_entry(bat_algo_ops_tmp, node, &bat_algo_list, list) {
if (strcmp(bat_algo_ops_tmp->name, name) != 0)
continue;
bat_algo_ops = bat_algo_ops_tmp;
break;
}
return bat_algo_ops;
}
int bat_algo_register(struct bat_algo_ops *bat_algo_ops)
{
struct bat_algo_ops *bat_algo_ops_tmp;
int ret = -1;
bat_algo_ops_tmp = bat_algo_get(bat_algo_ops->name);
if (bat_algo_ops_tmp) {
pr_info("Trying to register already registered routing algorithm: %s\n",
bat_algo_ops->name);
goto out;
}
/* all algorithms must implement all ops (for now) */
if (!bat_algo_ops->bat_ogm_init ||
!bat_algo_ops->bat_ogm_init_primary ||
!bat_algo_ops->bat_ogm_update_mac ||
!bat_algo_ops->bat_ogm_schedule ||
!bat_algo_ops->bat_ogm_emit ||
!bat_algo_ops->bat_ogm_receive) {
pr_info("Routing algo '%s' does not implement required ops\n",
bat_algo_ops->name);
goto out;
}
INIT_HLIST_NODE(&bat_algo_ops->list);
hlist_add_head(&bat_algo_ops->list, &bat_algo_list);
ret = 0;
out:
return ret;
}
int bat_algo_select(struct bat_priv *bat_priv, char *name)
{
struct bat_algo_ops *bat_algo_ops;
int ret = -1;
bat_algo_ops = bat_algo_get(name);
if (!bat_algo_ops)
goto out;
bat_priv->bat_algo_ops = bat_algo_ops;
ret = 0;
out:
return ret;
}
int bat_algo_seq_print_text(struct seq_file *seq, void *offset)
{
struct bat_algo_ops *bat_algo_ops;
struct hlist_node *node;
seq_printf(seq, "Available routing algorithms:\n");
hlist_for_each_entry(bat_algo_ops, node, &bat_algo_list, list) {
seq_printf(seq, "%s\n", bat_algo_ops->name);
}
return 0;
}
static int param_set_ra(const char *val, const struct kernel_param *kp)
{
struct bat_algo_ops *bat_algo_ops;
bat_algo_ops = bat_algo_get((char *)val);
if (!bat_algo_ops) {
pr_err("Routing algorithm '%s' is not supported\n", val);
return -EINVAL;
}
return param_set_copystring(val, kp);
}
static const struct kernel_param_ops param_ops_ra = {
.set = param_set_ra,
.get = param_get_string,
};
static struct kparam_string __param_string_ra = {
.maxlen = sizeof(bat_routing_algo),
.string = bat_routing_algo,
};
module_param_cb(routing_algo, &param_ops_ra, &__param_string_ra, 0644);
module_init(batman_init);
module_exit(batman_exit);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*
@@ -28,7 +28,7 @@
#define DRIVER_DEVICE "batman-adv"
#ifndef SOURCE_VERSION
#define SOURCE_VERSION "2012.0.0"
#define SOURCE_VERSION "2012.1.0"
#endif
/* B.A.T.M.A.N. parameters */
@@ -41,13 +41,14 @@
/* purge originators after time in seconds if no valid packet comes in
* -> TODO: check influence on TQ_LOCAL_WINDOW_SIZE */
#define PURGE_TIMEOUT 200
#define TT_LOCAL_TIMEOUT 3600 /* in seconds */
#define TT_CLIENT_ROAM_TIMEOUT 600
#define PURGE_TIMEOUT 200000 /* 200 seconds */
#define TT_LOCAL_TIMEOUT 3600000 /* in miliseconds */
#define TT_CLIENT_ROAM_TIMEOUT 600000 /* in miliseconds */
/* sliding packet range of received originator messages in sequence numbers
* (should be a multiple of our word size) */
#define TQ_LOCAL_WINDOW_SIZE 64
#define TT_REQUEST_TIMEOUT 3 /* seconds we have to keep pending tt_req */
#define TT_REQUEST_TIMEOUT 3000 /* miliseconds we have to keep
* pending tt_req */
#define TQ_GLOBAL_WINDOW_SIZE 5
#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1
@@ -56,8 +57,8 @@
#define TT_OGM_APPEND_MAX 3 /* number of OGMs sent with the last tt diff */
#define ROAMING_MAX_TIME 20 /* Time in which a client can roam at most
* ROAMING_MAX_COUNT times */
#define ROAMING_MAX_TIME 20000 /* Time in which a client can roam at most
* ROAMING_MAX_COUNT times in miliseconds*/
#define ROAMING_MAX_COUNT 5
#define NO_FLAGS 0
@@ -106,9 +107,7 @@ enum uev_type {
#define GW_THRESHOLD 50
/*
* Debug Messages
*/
/* Debug Messages */
#ifdef pr_fmt
#undef pr_fmt
#endif
@@ -123,14 +122,7 @@ enum dbg_level {
DBG_ALL = 7
};
/*
* Vis
*/
/*
* Kernel headers
*/
/* Kernel headers */
#include <linux/mutex.h> /* mutex */
#include <linux/module.h> /* needed by all modules */
@@ -147,6 +139,7 @@ enum dbg_level {
#include <linux/seq_file.h>
#include "types.h"
extern char bat_routing_algo[];
extern struct list_head hardif_list;
extern unsigned char broadcast_addr[];
@@ -157,6 +150,9 @@ void mesh_free(struct net_device *soft_iface);
void inc_module_count(void);
void dec_module_count(void);
int is_my_mac(const uint8_t *addr);
int bat_algo_register(struct bat_algo_ops *bat_algo_ops);
int bat_algo_select(struct bat_priv *bat_priv, char *name);
int bat_algo_seq_print_text(struct seq_file *seq, void *offset);
#ifdef CONFIG_BATMAN_ADV_DEBUG
int debug_log(struct bat_priv *bat_priv, const char *fmt, ...) __printf(2, 3);
@@ -202,6 +198,17 @@ static inline int compare_eth(const void *data1, const void *data2)
return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
}
/**
* has_timed_out - compares current time (jiffies) and timestamp + timeout
* @timestamp: base value to compare with (in jiffies)
* @timeout: added to base value before comparing (in milliseconds)
*
* Returns true if current time is after timestamp + timeout
*/
static inline bool has_timed_out(unsigned long timestamp, unsigned int timeout)
{
return time_is_before_jiffies(timestamp + msecs_to_jiffies(timeout));
}
#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2009-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*
@@ -143,7 +143,7 @@ static void orig_node_free_rcu(struct rcu_head *rcu)
frag_list_free(&orig_node->frag_list);
tt_global_del_orig(orig_node->bat_priv, orig_node,
"originator timed out");
"originator timed out");
kfree(orig_node->tt_buff);
kfree(orig_node->bcast_own);
@@ -219,6 +219,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr)
/* extra reference for return */
atomic_set(&orig_node->refcount, 2);
orig_node->tt_initialised = false;
orig_node->tt_poss_change = false;
orig_node->bat_priv = bat_priv;
memcpy(orig_node->orig, addr, ETH_ALEN);
@@ -281,8 +282,7 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv,
hlist_for_each_entry_safe(neigh_node, node, node_tmp,
&orig_node->neigh_list, list) {
if ((time_after(jiffies,
neigh_node->last_valid + PURGE_TIMEOUT * HZ)) ||
if ((has_timed_out(neigh_node->last_valid, PURGE_TIMEOUT)) ||
(neigh_node->if_incoming->if_status == IF_INACTIVE) ||
(neigh_node->if_incoming->if_status == IF_NOT_IN_USE) ||
(neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) {
@@ -294,14 +294,12 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv,
(neigh_node->if_incoming->if_status ==
IF_TO_BE_REMOVED))
bat_dbg(DBG_BATMAN, bat_priv,
"neighbor purge: originator %pM, "
"neighbor: %pM, iface: %s\n",
"neighbor purge: originator %pM, neighbor: %pM, iface: %s\n",
orig_node->orig, neigh_node->addr,
neigh_node->if_incoming->net_dev->name);
else
bat_dbg(DBG_BATMAN, bat_priv,
"neighbor timeout: originator %pM, "
"neighbor: %pM, last_valid: %lu\n",
"neighbor timeout: originator %pM, neighbor: %pM, last_valid: %lu\n",
orig_node->orig, neigh_node->addr,
(neigh_node->last_valid / HZ));
@@ -326,18 +324,15 @@ static bool purge_orig_node(struct bat_priv *bat_priv,
{
struct neigh_node *best_neigh_node;
if (time_after(jiffies,
orig_node->last_valid + 2 * PURGE_TIMEOUT * HZ)) {
if (has_timed_out(orig_node->last_valid, 2 * PURGE_TIMEOUT)) {
bat_dbg(DBG_BATMAN, bat_priv,
"Originator timeout: originator %pM, last_valid %lu\n",
orig_node->orig, (orig_node->last_valid / HZ));
return true;
} else {
if (purge_orig_neighbors(bat_priv, orig_node,
&best_neigh_node)) {
&best_neigh_node))
update_route(bat_priv, orig_node, best_neigh_node);
}
}
return false;
@@ -371,8 +366,8 @@ static void _purge_orig(struct bat_priv *bat_priv)
continue;
}
if (time_after(jiffies, orig_node->last_frag_packet +
msecs_to_jiffies(FRAG_TIMEOUT)))
if (has_timed_out(orig_node->last_frag_packet,
FRAG_TIMEOUT))
frag_list_free(&orig_node->frag_list);
}
spin_unlock_bh(list_lock);
@@ -419,15 +414,15 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
primary_if = primary_if_get_selected(bat_priv);
if (!primary_if) {
ret = seq_printf(seq, "BATMAN mesh %s disabled - "
"please specify interfaces to enable it\n",
ret = seq_printf(seq,
"BATMAN mesh %s disabled - please specify interfaces to enable it\n",
net_dev->name);
goto out;
}
if (primary_if->if_status != IF_ACTIVE) {
ret = seq_printf(seq, "BATMAN mesh %s "
"disabled - primary interface not active\n",
ret = seq_printf(seq,
"BATMAN mesh %s disabled - primary interface not active\n",
net_dev->name);
goto out;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*
@@ -90,10 +90,14 @@ enum tt_client_flags {
TT_CLIENT_PENDING = 1 << 10
};
struct batman_ogm_packet {
struct batman_header {
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t ttl;
} __packed;
struct batman_ogm_packet {
struct batman_header header;
uint8_t flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */
uint32_t seqno;
uint8_t orig[6];
@@ -108,9 +112,7 @@ struct batman_ogm_packet {
#define BATMAN_OGM_LEN sizeof(struct batman_ogm_packet)
struct icmp_packet {
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t ttl;
struct batman_header header;
uint8_t msg_type; /* see ICMP message types above */
uint8_t dst[6];
uint8_t orig[6];
@@ -124,9 +126,7 @@ struct icmp_packet {
/* icmp_packet_rr must start with all fields from imcp_packet
* as this is assumed by code that handles ICMP packets */
struct icmp_packet_rr {
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t ttl;
struct batman_header header;
uint8_t msg_type; /* see ICMP message types above */
uint8_t dst[6];
uint8_t orig[6];
@@ -137,17 +137,13 @@ struct icmp_packet_rr {
} __packed;
struct unicast_packet {
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t ttl;
struct batman_header header;
uint8_t ttvn; /* destination translation table version number */
uint8_t dest[6];
} __packed;
struct unicast_frag_packet {
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t ttl;
struct batman_header header;
uint8_t ttvn; /* destination translation table version number */
uint8_t dest[6];
uint8_t flags;
@@ -157,18 +153,14 @@ struct unicast_frag_packet {
} __packed;
struct bcast_packet {
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t ttl;
struct batman_header header;
uint8_t reserved;
uint32_t seqno;
uint8_t orig[6];
} __packed;
struct vis_packet {
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t ttl; /* TTL */
struct batman_header header;
uint8_t vis_type; /* which type of vis-participant sent this? */
uint32_t seqno; /* sequence number */
uint8_t entries; /* number of entries behind this struct */
@@ -179,9 +171,7 @@ struct vis_packet {
} __packed;
struct tt_query_packet {
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t ttl;
struct batman_header header;
/* the flag field is a combination of:
* - TT_REQUEST or TT_RESPONSE
* - TT_FULL_TABLE */
@@ -202,9 +192,7 @@ struct tt_query_packet {
} __packed;
struct roam_adv_packet {
uint8_t packet_type;
uint8_t version;
uint8_t ttl;
struct batman_header header;
uint8_t reserved;
uint8_t dst[ETH_ALEN];
uint8_t src[ETH_ALEN];

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*
@@ -29,7 +29,6 @@
#include "originator.h"
#include "vis.h"
#include "unicast.h"
#include "bat_ogm.h"
void slide_own_bcast_window(struct hard_iface *hard_iface)
{
@@ -73,7 +72,7 @@ static void _update_route(struct bat_priv *bat_priv,
bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n",
orig_node->orig);
tt_global_del_orig(bat_priv, orig_node,
"Deleted route towards originator");
"Deleted route towards originator");
/* route added */
} else if ((!curr_router) && (neigh_node)) {
@@ -84,8 +83,7 @@ static void _update_route(struct bat_priv *bat_priv,
/* route changed */
} else if (neigh_node && curr_router) {
bat_dbg(DBG_ROUTES, bat_priv,
"Changing route towards: %pM "
"(now via %pM - was via %pM)\n",
"Changing route towards: %pM (now via %pM - was via %pM)\n",
orig_node->orig, neigh_node->addr,
curr_router->addr);
}
@@ -230,24 +228,25 @@ void bonding_save_primary(const struct orig_node *orig_node,
int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff,
unsigned long *last_reset)
{
if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
|| (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
if (time_after(jiffies, *last_reset +
msecs_to_jiffies(RESET_PROTECTION_MS))) {
if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) ||
(seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
if (has_timed_out(*last_reset, RESET_PROTECTION_MS)) {
*last_reset = jiffies;
bat_dbg(DBG_BATMAN, bat_priv,
"old packet received, start protection\n");
return 0;
} else
} else {
return 1;
}
}
return 0;
}
int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
{
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct ethhdr *ethhdr;
/* drop packet if it has not necessary minimum size */
@@ -272,9 +271,7 @@ int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
if (skb_linearize(skb) < 0)
return NET_RX_DROP;
ethhdr = (struct ethhdr *)skb_mac_header(skb);
bat_ogm_receive(ethhdr, skb->data, skb_headlen(skb), hard_iface);
bat_priv->bat_algo_ops->bat_ogm_receive(hard_iface, skb);
kfree_skb(skb);
return NET_RX_SUCCESS;
@@ -320,7 +317,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
icmp_packet->msg_type = ECHO_REPLY;
icmp_packet->ttl = TTL;
icmp_packet->header.ttl = TTL;
send_skb_packet(skb, router->if_incoming, router->addr);
ret = NET_RX_SUCCESS;
@@ -348,9 +345,8 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
/* send TTL exceeded if packet is an echo request (traceroute) */
if (icmp_packet->msg_type != ECHO_REQUEST) {
pr_debug("Warning - can't forward icmp packet from %pM to "
"%pM: ttl exceeded\n", icmp_packet->orig,
icmp_packet->dst);
pr_debug("Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n",
icmp_packet->orig, icmp_packet->dst);
goto out;
}
@@ -376,7 +372,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
icmp_packet->msg_type = TTL_EXCEEDED;
icmp_packet->ttl = TTL;
icmp_packet->header.ttl = TTL;
send_skb_packet(skb, router->if_incoming, router->addr);
ret = NET_RX_SUCCESS;
@@ -432,7 +428,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
if ((hdr_size == sizeof(struct icmp_packet_rr)) &&
(icmp_packet->rr_cur < BAT_RR_LEN)) {
memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]),
ethhdr->h_dest, ETH_ALEN);
ethhdr->h_dest, ETH_ALEN);
icmp_packet->rr_cur++;
}
@@ -441,7 +437,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
return recv_my_icmp_packet(bat_priv, skb, hdr_size);
/* TTL exceeded */
if (icmp_packet->ttl < 2)
if (icmp_packet->header.ttl < 2)
return recv_icmp_ttl_exceeded(bat_priv, skb);
/* get routing information */
@@ -460,7 +456,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
icmp_packet = (struct icmp_packet_rr *)skb->data;
/* decrement ttl */
icmp_packet->ttl--;
icmp_packet->header.ttl--;
/* route it */
send_skb_packet(skb, router->if_incoming, router->addr);
@@ -677,9 +673,9 @@ int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if)
if (!orig_node)
goto out;
bat_dbg(DBG_TT, bat_priv, "Received ROAMING_ADV from %pM "
"(client %pM)\n", roam_adv_packet->src,
roam_adv_packet->client);
bat_dbg(DBG_TT, bat_priv,
"Received ROAMING_ADV from %pM (client %pM)\n",
roam_adv_packet->src, roam_adv_packet->client);
tt_global_add(bat_priv, orig_node, roam_adv_packet->client,
atomic_read(&orig_node->last_ttvn) + 1, true, false);
@@ -815,10 +811,9 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
unicast_packet = (struct unicast_packet *)skb->data;
/* TTL exceeded */
if (unicast_packet->ttl < 2) {
pr_debug("Warning - can't forward unicast packet from %pM to "
"%pM: ttl exceeded\n", ethhdr->h_source,
unicast_packet->dest);
if (unicast_packet->header.ttl < 2) {
pr_debug("Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n",
ethhdr->h_source, unicast_packet->dest);
goto out;
}
@@ -840,7 +835,7 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
unicast_packet = (struct unicast_packet *)skb->data;
if (unicast_packet->packet_type == BAT_UNICAST &&
if (unicast_packet->header.packet_type == BAT_UNICAST &&
atomic_read(&bat_priv->fragmentation) &&
skb->len > neigh_node->if_incoming->net_dev->mtu) {
ret = frag_send_skb(skb, bat_priv,
@@ -848,7 +843,7 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
goto out;
}
if (unicast_packet->packet_type == BAT_UNICAST_FRAG &&
if (unicast_packet->header.packet_type == BAT_UNICAST_FRAG &&
frag_can_reassemble(skb, neigh_node->if_incoming->net_dev->mtu)) {
ret = frag_reassemble_skb(skb, bat_priv, &new_skb);
@@ -867,7 +862,7 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
}
/* decrement ttl */
unicast_packet->ttl--;
unicast_packet->header.ttl--;
/* route it */
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
@@ -937,10 +932,10 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv,
orig_node_free_ref(orig_node);
}
bat_dbg(DBG_ROUTES, bat_priv, "TTVN mismatch (old_ttvn %u "
"new_ttvn %u)! Rerouting unicast packet (for %pM) to "
"%pM\n", unicast_packet->ttvn, curr_ttvn,
ethhdr->h_dest, unicast_packet->dest);
bat_dbg(DBG_ROUTES, bat_priv,
"TTVN mismatch (old_ttvn %u new_ttvn %u)! Rerouting unicast packet (for %pM) to %pM\n",
unicast_packet->ttvn, curr_ttvn, ethhdr->h_dest,
unicast_packet->dest);
unicast_packet->ttvn = curr_ttvn;
}
@@ -1041,7 +1036,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
if (is_my_mac(bcast_packet->orig))
goto out;
if (bcast_packet->ttl < 2)
if (bcast_packet->header.ttl < 2)
goto out;
orig_node = orig_hash_find(bat_priv, bcast_packet->orig);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*
@@ -28,7 +28,6 @@
#include "vis.h"
#include "gateway_common.h"
#include "originator.h"
#include "bat_ogm.h"
static void send_outstanding_bcast_packet(struct work_struct *work);
@@ -46,8 +45,8 @@ int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface,
goto send_skb_err;
if (!(hard_iface->net_dev->flags & IFF_UP)) {
pr_warning("Interface %s is not up - can't send packet via "
"that interface!\n", hard_iface->net_dev->name);
pr_warning("Interface %s is not up - can't send packet via that interface!\n",
hard_iface->net_dev->name);
goto send_skb_err;
}
@@ -57,7 +56,7 @@ int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface,
skb_reset_mac_header(skb);
ethhdr = (struct ethhdr *) skb_mac_header(skb);
ethhdr = (struct ethhdr *)skb_mac_header(skb);
memcpy(ethhdr->h_source, hard_iface->net_dev->dev_addr, ETH_ALEN);
memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN);
ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);
@@ -168,7 +167,7 @@ void schedule_bat_ogm(struct hard_iface *hard_iface)
if (primary_if)
hardif_free_ref(primary_if);
bat_ogm_schedule(hard_iface, tt_num_changes);
bat_priv->bat_algo_ops->bat_ogm_schedule(hard_iface, tt_num_changes);
}
static void forw_packet_free(struct forw_packet *forw_packet)
@@ -234,7 +233,7 @@ int add_bcast_packet_to_list(struct bat_priv *bat_priv,
/* as we have a copy now, it is safe to decrease the TTL */
bcast_packet = (struct bcast_packet *)newskb->data;
bcast_packet->ttl--;
bcast_packet->header.ttl--;
skb_reset_mac_header(newskb);
@@ -318,7 +317,7 @@ void send_outstanding_bat_ogm_packet(struct work_struct *work)
if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING)
goto out;
bat_ogm_emit(forw_packet);
bat_priv->bat_algo_ops->bat_ogm_emit(forw_packet);
/**
* we have to have at least one packet in the queue

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*
@@ -252,8 +252,8 @@ static void softif_neigh_vid_select(struct bat_priv *bat_priv,
vid, curr_neigh->addr);
else if ((curr_neigh) && (new_neigh))
bat_dbg(DBG_ROUTES, bat_priv,
"Changing mesh exit point on vid: %d from %pM "
"to %pM.\n", vid, curr_neigh->addr, new_neigh->addr);
"Changing mesh exit point on vid: %d from %pM to %pM.\n",
vid, curr_neigh->addr, new_neigh->addr);
else if ((!curr_neigh) && (new_neigh))
bat_dbg(DBG_ROUTES, bat_priv,
"Setting mesh exit point on vid: %d to %pM.\n",
@@ -327,15 +327,15 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
primary_if = primary_if_get_selected(bat_priv);
if (!primary_if) {
ret = seq_printf(seq, "BATMAN mesh %s disabled - "
"please specify interfaces to enable it\n",
ret = seq_printf(seq,
"BATMAN mesh %s disabled - please specify interfaces to enable it\n",
net_dev->name);
goto out;
}
if (primary_if->if_status != IF_ACTIVE) {
ret = seq_printf(seq, "BATMAN mesh %s "
"disabled - primary interface not active\n",
ret = seq_printf(seq,
"BATMAN mesh %s disabled - primary interface not active\n",
net_dev->name);
goto out;
}
@@ -396,15 +396,14 @@ void softif_neigh_purge(struct bat_priv *bat_priv)
hlist_for_each_entry_safe(softif_neigh, node_tmp, node_tmp2,
&softif_neigh_vid->softif_neigh_list,
list) {
if ((!time_after(jiffies, softif_neigh->last_seen +
msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) &&
if ((!has_timed_out(softif_neigh->last_seen,
SOFTIF_NEIGH_TIMEOUT)) &&
(atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE))
continue;
if (curr_softif_neigh == softif_neigh) {
bat_dbg(DBG_ROUTES, bat_priv,
"Current mesh exit point on vid: %d "
"'%pM' vanished.\n",
"Current mesh exit point on vid: %d '%pM' vanished.\n",
softif_neigh_vid->vid,
softif_neigh->addr);
do_deselect = 1;
@@ -457,10 +456,10 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
batman_ogm_packet = (struct batman_ogm_packet *)
(skb->data + ETH_HLEN);
if (batman_ogm_packet->version != COMPAT_VERSION)
if (batman_ogm_packet->header.version != COMPAT_VERSION)
goto out;
if (batman_ogm_packet->packet_type != BAT_OGM)
if (batman_ogm_packet->header.packet_type != BAT_OGM)
goto out;
if (!(batman_ogm_packet->flags & PRIMARIES_FIRST_HOP))
@@ -541,6 +540,7 @@ static int interface_set_mac_addr(struct net_device *dev, void *p)
}
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
dev->addr_assign_type &= ~NET_ADDR_RANDOM;
return 0;
}
@@ -632,11 +632,11 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
goto dropped;
bcast_packet = (struct bcast_packet *)skb->data;
bcast_packet->version = COMPAT_VERSION;
bcast_packet->ttl = TTL;
bcast_packet->header.version = COMPAT_VERSION;
bcast_packet->header.ttl = TTL;
/* batman packet type: broadcast */
bcast_packet->packet_type = BAT_BCAST;
bcast_packet->header.packet_type = BAT_BCAST;
/* hw address of first interface is the orig mac because only
* this mac is known throughout the mesh */
@@ -725,8 +725,8 @@ void interface_rx(struct net_device *soft_iface,
skb_push(skb, hdr_size);
unicast_packet = (struct unicast_packet *)skb->data;
if ((unicast_packet->packet_type != BAT_UNICAST) &&
(unicast_packet->packet_type != BAT_UNICAST_FRAG))
if ((unicast_packet->header.packet_type != BAT_UNICAST) &&
(unicast_packet->header.packet_type != BAT_UNICAST_FRAG))
goto dropped;
skb_reset_mac_header(skb);
@@ -783,7 +783,6 @@ static const struct net_device_ops bat_netdev_ops = {
static void interface_setup(struct net_device *dev)
{
struct bat_priv *priv = netdev_priv(dev);
char dev_addr[ETH_ALEN];
ether_setup(dev);
@@ -800,8 +799,7 @@ static void interface_setup(struct net_device *dev)
dev->hard_header_len = BAT_HEADER_LEN;
/* generate random address */
random_ether_addr(dev_addr);
memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
eth_hw_addr_random(dev);
SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
@@ -855,6 +853,10 @@ struct net_device *softif_create(const char *name)
bat_priv->primary_if = NULL;
bat_priv->num_ifaces = 0;
ret = bat_algo_select(bat_priv, bat_routing_algo);
if (ret < 0)
goto unreg_soft_iface;
ret = sysfs_add_meshif(soft_iface);
if (ret < 0)
goto unreg_soft_iface;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*
@@ -108,14 +108,6 @@ static struct tt_global_entry *tt_global_hash_find(struct bat_priv *bat_priv,
}
static bool is_out_of_time(unsigned long starting_time, unsigned long timeout)
{
unsigned long deadline;
deadline = starting_time + msecs_to_jiffies(timeout);
return time_after(jiffies, deadline);
}
static void tt_local_entry_free_ref(struct tt_local_entry *tt_local_entry)
{
if (atomic_dec_and_test(&tt_local_entry->common.refcount))
@@ -218,6 +210,11 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
if (compare_eth(addr, soft_iface->dev_addr))
tt_local_entry->common.flags |= TT_CLIENT_NOPURGE;
/* The local entry has to be marked as NEW to avoid to send it in
* a full table response going out before the next ttvn increment
* (consistency check) */
tt_local_entry->common.flags |= TT_CLIENT_NEW;
hash_added = hash_add(bat_priv->tt_local_hash, compare_tt, choose_orig,
&tt_local_entry->common,
&tt_local_entry->common.hash_entry);
@@ -230,11 +227,6 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
tt_local_event(bat_priv, addr, tt_local_entry->common.flags);
/* The local entry has to be marked as NEW to avoid to send it in
* a full table response going out before the next ttvn increment
* (consistency check) */
tt_local_entry->common.flags |= TT_CLIENT_NEW;
/* remove address from global hash if present */
tt_global_entry = tt_global_hash_find(bat_priv, addr);
@@ -269,7 +261,7 @@ int tt_changes_fill_buffer(struct bat_priv *bat_priv,
atomic_set(&bat_priv->tt_local_changes, 0);
list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list,
list) {
list) {
if (count < tot_changes) {
memcpy(buff + tt_len(count),
&entry->change, sizeof(struct tt_change));
@@ -317,21 +309,21 @@ int tt_local_seq_print_text(struct seq_file *seq, void *offset)
primary_if = primary_if_get_selected(bat_priv);
if (!primary_if) {
ret = seq_printf(seq, "BATMAN mesh %s disabled - "
"please specify interfaces to enable it\n",
ret = seq_printf(seq,
"BATMAN mesh %s disabled - please specify interfaces to enable it\n",
net_dev->name);
goto out;
}
if (primary_if->if_status != IF_ACTIVE) {
ret = seq_printf(seq, "BATMAN mesh %s disabled - "
"primary interface not active\n",
ret = seq_printf(seq,
"BATMAN mesh %s disabled - primary interface not active\n",
net_dev->name);
goto out;
}
seq_printf(seq, "Locally retrieved addresses (from %s) "
"announced via TT (TTVN: %u):\n",
seq_printf(seq,
"Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
net_dev->name, (uint8_t)atomic_read(&bat_priv->ttvn));
for (i = 0; i < hash->size; i++) {
@@ -341,17 +333,17 @@ int tt_local_seq_print_text(struct seq_file *seq, void *offset)
hlist_for_each_entry_rcu(tt_common_entry, node,
head, hash_entry) {
seq_printf(seq, " * %pM [%c%c%c%c%c]\n",
tt_common_entry->addr,
(tt_common_entry->flags &
TT_CLIENT_ROAM ? 'R' : '.'),
(tt_common_entry->flags &
TT_CLIENT_NOPURGE ? 'P' : '.'),
(tt_common_entry->flags &
TT_CLIENT_NEW ? 'N' : '.'),
(tt_common_entry->flags &
TT_CLIENT_PENDING ? 'X' : '.'),
(tt_common_entry->flags &
TT_CLIENT_WIFI ? 'W' : '.'));
tt_common_entry->addr,
(tt_common_entry->flags &
TT_CLIENT_ROAM ? 'R' : '.'),
(tt_common_entry->flags &
TT_CLIENT_NOPURGE ? 'P' : '.'),
(tt_common_entry->flags &
TT_CLIENT_NEW ? 'N' : '.'),
(tt_common_entry->flags &
TT_CLIENT_PENDING ? 'X' : '.'),
(tt_common_entry->flags &
TT_CLIENT_WIFI ? 'W' : '.'));
}
rcu_read_unlock();
}
@@ -363,7 +355,7 @@ out:
static void tt_local_set_pending(struct bat_priv *bat_priv,
struct tt_local_entry *tt_local_entry,
uint16_t flags)
uint16_t flags, const char *message)
{
tt_local_event(bat_priv, tt_local_entry->common.addr,
tt_local_entry->common.flags | flags);
@@ -372,6 +364,10 @@ static void tt_local_set_pending(struct bat_priv *bat_priv,
* to be kept in the table in order to send it in a full table
* response issued before the net ttvn increment (consistency check) */
tt_local_entry->common.flags |= TT_CLIENT_PENDING;
bat_dbg(DBG_TT, bat_priv,
"Local tt entry (%pM) pending to be removed: %s\n",
tt_local_entry->common.addr, message);
}
void tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr,
@@ -384,10 +380,7 @@ void tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr,
goto out;
tt_local_set_pending(bat_priv, tt_local_entry, TT_CLIENT_DEL |
(roaming ? TT_CLIENT_ROAM : NO_FLAGS));
bat_dbg(DBG_TT, bat_priv, "Local tt entry (%pM) pending to be removed: "
"%s\n", tt_local_entry->common.addr, message);
(roaming ? TT_CLIENT_ROAM : NO_FLAGS), message);
out:
if (tt_local_entry)
tt_local_entry_free_ref(tt_local_entry);
@@ -420,15 +413,12 @@ static void tt_local_purge(struct bat_priv *bat_priv)
if (tt_local_entry->common.flags & TT_CLIENT_PENDING)
continue;
if (!is_out_of_time(tt_local_entry->last_seen,
TT_LOCAL_TIMEOUT * 1000))
if (!has_timed_out(tt_local_entry->last_seen,
TT_LOCAL_TIMEOUT))
continue;
tt_local_set_pending(bat_priv, tt_local_entry,
TT_CLIENT_DEL);
bat_dbg(DBG_TT, bat_priv, "Local tt entry (%pM) "
"pending to be removed: timed out\n",
tt_local_entry->common.addr);
TT_CLIENT_DEL, "timed out");
}
spin_unlock_bh(list_lock);
}
@@ -585,15 +575,15 @@ int tt_global_seq_print_text(struct seq_file *seq, void *offset)
primary_if = primary_if_get_selected(bat_priv);
if (!primary_if) {
ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
"specify interfaces to enable it\n",
ret = seq_printf(seq,
"BATMAN mesh %s disabled - please specify interfaces to enable it\n",
net_dev->name);
goto out;
}
if (primary_if->if_status != IF_ACTIVE) {
ret = seq_printf(seq, "BATMAN mesh %s disabled - "
"primary interface not active\n",
ret = seq_printf(seq,
"BATMAN mesh %s disabled - primary interface not active\n",
net_dev->name);
goto out;
}
@@ -613,20 +603,18 @@ int tt_global_seq_print_text(struct seq_file *seq, void *offset)
tt_global_entry = container_of(tt_common_entry,
struct tt_global_entry,
common);
seq_printf(seq, " * %pM (%3u) via %pM (%3u) "
"[%c%c%c]\n",
tt_global_entry->common.addr,
tt_global_entry->ttvn,
tt_global_entry->orig_node->orig,
(uint8_t) atomic_read(
seq_printf(seq,
" * %pM (%3u) via %pM (%3u) [%c%c]\n",
tt_global_entry->common.addr,
tt_global_entry->ttvn,
tt_global_entry->orig_node->orig,
(uint8_t) atomic_read(
&tt_global_entry->orig_node->
last_ttvn),
(tt_global_entry->common.flags &
TT_CLIENT_ROAM ? 'R' : '.'),
(tt_global_entry->common.flags &
TT_CLIENT_PENDING ? 'X' : '.'),
(tt_global_entry->common.flags &
TT_CLIENT_WIFI ? 'W' : '.'));
(tt_global_entry->common.flags &
TT_CLIENT_ROAM ? 'R' : '.'),
(tt_global_entry->common.flags &
TT_CLIENT_WIFI ? 'W' : '.'));
}
rcu_read_unlock();
}
@@ -665,29 +653,31 @@ void tt_global_del(struct bat_priv *bat_priv,
struct tt_local_entry *tt_local_entry = NULL;
tt_global_entry = tt_global_hash_find(bat_priv, addr);
if (!tt_global_entry)
if (!tt_global_entry || tt_global_entry->orig_node != orig_node)
goto out;
if (tt_global_entry->orig_node == orig_node) {
if (roaming) {
/* if we are deleting a global entry due to a roam
* event, there are two possibilities:
* 1) the client roamed from node A to node B => we mark
* it with TT_CLIENT_ROAM, we start a timer and we
* wait for node B to claim it. In case of timeout
* the entry is purged.
* 2) the client roamed to us => we can directly delete
* the global entry, since it is useless now. */
tt_local_entry = tt_local_hash_find(bat_priv,
tt_global_entry->common.addr);
if (!tt_local_entry) {
tt_global_entry->common.flags |= TT_CLIENT_ROAM;
tt_global_entry->roam_at = jiffies;
goto out;
}
}
_tt_global_del(bat_priv, tt_global_entry, message);
if (!roaming)
goto out_del;
/* if we are deleting a global entry due to a roam
* event, there are two possibilities:
* 1) the client roamed from node A to node B => we mark
* it with TT_CLIENT_ROAM, we start a timer and we
* wait for node B to claim it. In case of timeout
* the entry is purged.
* 2) the client roamed to us => we can directly delete
* the global entry, since it is useless now. */
tt_local_entry = tt_local_hash_find(bat_priv,
tt_global_entry->common.addr);
if (!tt_local_entry) {
tt_global_entry->common.flags |= TT_CLIENT_ROAM;
tt_global_entry->roam_at = jiffies;
goto out;
}
out_del:
_tt_global_del(bat_priv, tt_global_entry, message);
out:
if (tt_global_entry)
tt_global_entry_free_ref(tt_global_entry);
@@ -715,14 +705,13 @@ void tt_global_del_orig(struct bat_priv *bat_priv,
spin_lock_bh(list_lock);
hlist_for_each_entry_safe(tt_common_entry, node, safe,
head, hash_entry) {
head, hash_entry) {
tt_global_entry = container_of(tt_common_entry,
struct tt_global_entry,
common);
if (tt_global_entry->orig_node == orig_node) {
bat_dbg(DBG_TT, bat_priv,
"Deleting global tt entry %pM "
"(via %pM): %s\n",
"Deleting global tt entry %pM (via %pM): %s\n",
tt_global_entry->common.addr,
tt_global_entry->orig_node->orig,
message);
@@ -733,6 +722,7 @@ void tt_global_del_orig(struct bat_priv *bat_priv,
spin_unlock_bh(list_lock);
}
atomic_set(&orig_node->tt_size, 0);
orig_node->tt_initialised = false;
}
static void tt_global_roam_purge(struct bat_priv *bat_priv)
@@ -757,12 +747,12 @@ static void tt_global_roam_purge(struct bat_priv *bat_priv)
common);
if (!(tt_global_entry->common.flags & TT_CLIENT_ROAM))
continue;
if (!is_out_of_time(tt_global_entry->roam_at,
TT_CLIENT_ROAM_TIMEOUT * 1000))
if (!has_timed_out(tt_global_entry->roam_at,
TT_CLIENT_ROAM_TIMEOUT))
continue;
bat_dbg(DBG_TT, bat_priv, "Deleting global "
"tt entry (%pM): Roaming timeout\n",
bat_dbg(DBG_TT, bat_priv,
"Deleting global tt entry (%pM): Roaming timeout\n",
tt_global_entry->common.addr);
atomic_dec(&tt_global_entry->orig_node->tt_size);
hlist_del_rcu(node);
@@ -846,11 +836,6 @@ struct orig_node *transtable_search(struct bat_priv *bat_priv,
if (!atomic_inc_not_zero(&tt_global_entry->orig_node->refcount))
goto out;
/* A global client marked as PENDING has already moved from that
* originator */
if (tt_global_entry->common.flags & TT_CLIENT_PENDING)
goto out;
orig_node = tt_global_entry->orig_node;
out:
@@ -977,8 +962,7 @@ static void tt_req_purge(struct bat_priv *bat_priv)
spin_lock_bh(&bat_priv->tt_req_list_lock);
list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
if (is_out_of_time(node->issued_at,
TT_REQUEST_TIMEOUT * 1000)) {
if (has_timed_out(node->issued_at, TT_REQUEST_TIMEOUT)) {
list_del(&node->list);
kfree(node);
}
@@ -996,8 +980,8 @@ static struct tt_req_node *new_tt_req_node(struct bat_priv *bat_priv,
spin_lock_bh(&bat_priv->tt_req_list_lock);
list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) {
if (compare_eth(tt_req_node_tmp, orig_node) &&
!is_out_of_time(tt_req_node_tmp->issued_at,
TT_REQUEST_TIMEOUT * 1000))
!has_timed_out(tt_req_node_tmp->issued_at,
TT_REQUEST_TIMEOUT))
goto unlock;
}
@@ -1134,11 +1118,11 @@ static int send_tt_request(struct bat_priv *bat_priv,
tt_request = (struct tt_query_packet *)skb_put(skb,
sizeof(struct tt_query_packet));
tt_request->packet_type = BAT_TT_QUERY;
tt_request->version = COMPAT_VERSION;
tt_request->header.packet_type = BAT_TT_QUERY;
tt_request->header.version = COMPAT_VERSION;
memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN);
memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN);
tt_request->ttl = TTL;
tt_request->header.ttl = TTL;
tt_request->ttvn = ttvn;
tt_request->tt_data = tt_crc;
tt_request->flags = TT_REQUEST;
@@ -1150,8 +1134,9 @@ static int send_tt_request(struct bat_priv *bat_priv,
if (!neigh_node)
goto out;
bat_dbg(DBG_TT, bat_priv, "Sending TT_REQUEST to %pM via %pM "
"[%c]\n", dst_orig_node->orig, neigh_node->addr,
bat_dbg(DBG_TT, bat_priv,
"Sending TT_REQUEST to %pM via %pM [%c]\n",
dst_orig_node->orig, neigh_node->addr,
(full_table ? 'F' : '.'));
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
@@ -1188,9 +1173,8 @@ static bool send_other_tt_response(struct bat_priv *bat_priv,
struct tt_query_packet *tt_response;
bat_dbg(DBG_TT, bat_priv,
"Received TT_REQUEST from %pM for "
"ttvn: %u (%pM) [%c]\n", tt_request->src,
tt_request->ttvn, tt_request->dst,
"Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n",
tt_request->src, tt_request->ttvn, tt_request->dst,
(tt_request->flags & TT_FULL_TABLE ? 'F' : '.'));
/* Let's get the orig node of the REAL destination */
@@ -1264,9 +1248,9 @@ static bool send_other_tt_response(struct bat_priv *bat_priv,
tt_response = (struct tt_query_packet *)skb->data;
}
tt_response->packet_type = BAT_TT_QUERY;
tt_response->version = COMPAT_VERSION;
tt_response->ttl = TTL;
tt_response->header.packet_type = BAT_TT_QUERY;
tt_response->header.version = COMPAT_VERSION;
tt_response->header.ttl = TTL;
memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN);
memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
tt_response->flags = TT_RESPONSE;
@@ -1315,9 +1299,8 @@ static bool send_my_tt_response(struct bat_priv *bat_priv,
struct tt_query_packet *tt_response;
bat_dbg(DBG_TT, bat_priv,
"Received TT_REQUEST from %pM for "
"ttvn: %u (me) [%c]\n", tt_request->src,
tt_request->ttvn,
"Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n",
tt_request->src, tt_request->ttvn,
(tt_request->flags & TT_FULL_TABLE ? 'F' : '.'));
@@ -1381,9 +1364,9 @@ static bool send_my_tt_response(struct bat_priv *bat_priv,
tt_response = (struct tt_query_packet *)skb->data;
}
tt_response->packet_type = BAT_TT_QUERY;
tt_response->version = COMPAT_VERSION;
tt_response->ttl = TTL;
tt_response->header.packet_type = BAT_TT_QUERY;
tt_response->header.version = COMPAT_VERSION;
tt_response->header.ttl = TTL;
memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN);
memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
tt_response->flags = TT_RESPONSE;
@@ -1450,6 +1433,7 @@ static void _tt_update_changes(struct bat_priv *bat_priv,
*/
return;
}
orig_node->tt_initialised = true;
}
static void tt_fill_gtable(struct bat_priv *bat_priv,
@@ -1519,10 +1503,9 @@ void handle_tt_response(struct bat_priv *bat_priv,
struct tt_req_node *node, *safe;
struct orig_node *orig_node = NULL;
bat_dbg(DBG_TT, bat_priv, "Received TT_RESPONSE from %pM for "
"ttvn %d t_size: %d [%c]\n",
tt_response->src, tt_response->ttvn,
tt_response->tt_data,
bat_dbg(DBG_TT, bat_priv,
"Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n",
tt_response->src, tt_response->ttvn, tt_response->tt_data,
(tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
orig_node = orig_hash_find(bat_priv, tt_response->src);
@@ -1589,8 +1572,7 @@ static void tt_roam_purge(struct bat_priv *bat_priv)
spin_lock_bh(&bat_priv->tt_roam_list_lock);
list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
if (!is_out_of_time(node->first_time,
ROAMING_MAX_TIME * 1000))
if (!has_timed_out(node->first_time, ROAMING_MAX_TIME))
continue;
list_del(&node->list);
@@ -1617,8 +1599,7 @@ static bool tt_check_roam_count(struct bat_priv *bat_priv,
if (!compare_eth(tt_roam_node->addr, client))
continue;
if (is_out_of_time(tt_roam_node->first_time,
ROAMING_MAX_TIME * 1000))
if (has_timed_out(tt_roam_node->first_time, ROAMING_MAX_TIME))
continue;
if (!atomic_dec_not_zero(&tt_roam_node->counter))
@@ -1669,9 +1650,9 @@ void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
roam_adv_packet = (struct roam_adv_packet *)skb_put(skb,
sizeof(struct roam_adv_packet));
roam_adv_packet->packet_type = BAT_ROAM_ADV;
roam_adv_packet->version = COMPAT_VERSION;
roam_adv_packet->ttl = TTL;
roam_adv_packet->header.packet_type = BAT_ROAM_ADV;
roam_adv_packet->header.version = COMPAT_VERSION;
roam_adv_packet->header.ttl = TTL;
primary_if = primary_if_get_selected(bat_priv);
if (!primary_if)
goto out;
@@ -1788,8 +1769,9 @@ static void tt_local_purge_pending_clients(struct bat_priv *bat_priv)
if (!(tt_common_entry->flags & TT_CLIENT_PENDING))
continue;
bat_dbg(DBG_TT, bat_priv, "Deleting local tt entry "
"(%pM): pending\n", tt_common_entry->addr);
bat_dbg(DBG_TT, bat_priv,
"Deleting local tt entry (%pM): pending\n",
tt_common_entry->addr);
atomic_dec(&bat_priv->num_local_tt);
hlist_del_rcu(node);
@@ -1854,8 +1836,10 @@ void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
bool full_table = true;
/* the ttvn increased by one -> we can apply the attached changes */
if (ttvn - orig_ttvn == 1) {
/* orig table not initialised AND first diff is in the OGM OR the ttvn
* increased by one -> we can apply the attached changes */
if ((!orig_node->tt_initialised && ttvn == 1) ||
ttvn - orig_ttvn == 1) {
/* the OGM could not contain the changes due to their size or
* because they have already been sent TT_OGM_APPEND_MAX times.
* In this case send a tt request */
@@ -1889,14 +1873,13 @@ void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
} else {
/* if we missed more than one change or our tables are not
* in sync anymore -> request fresh tt data */
if (ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) {
if (!orig_node->tt_initialised || ttvn != orig_ttvn ||
orig_node->tt_crc != tt_crc) {
request_table:
bat_dbg(DBG_TT, bat_priv, "TT inconsistency for %pM. "
"Need to retrieve the correct information "
"(ttvn: %u last_ttvn: %u crc: %u last_crc: "
"%u num_changes: %u)\n", orig_node->orig, ttvn,
orig_ttvn, tt_crc, orig_node->tt_crc,
tt_num_changes);
bat_dbg(DBG_TT, bat_priv,
"TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u crc: %u last_crc: %u num_changes: %u)\n",
orig_node->orig, ttvn, orig_ttvn, tt_crc,
orig_node->tt_crc, tt_num_changes);
send_tt_request(bat_priv, orig_node, ttvn, tt_crc,
full_table);
return;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*
@@ -81,6 +81,7 @@ struct orig_node {
int16_t tt_buff_len;
spinlock_t tt_buff_lock; /* protects tt_buff */
atomic_t tt_size;
bool tt_initialised;
/* The tt_poss_change flag is used to detect an ongoing roaming phase.
* If true, then I sent a Roaming_adv to this orig_node and I have to
* inspect every packet directed to it to check whether it is still
@@ -205,6 +206,7 @@ struct bat_priv {
atomic_t gw_reselect;
struct hard_iface __rcu *primary_if; /* rcu protected pointer */
struct vis_info *my_vis_info;
struct bat_algo_ops *bat_algo_ops;
};
struct socket_client {
@@ -343,4 +345,23 @@ struct softif_neigh {
struct rcu_head rcu;
};
struct bat_algo_ops {
struct hlist_node list;
char *name;
/* init OGM when hard-interface is enabled */
void (*bat_ogm_init)(struct hard_iface *hard_iface);
/* init primary OGM when primary interface is selected */
void (*bat_ogm_init_primary)(struct hard_iface *hard_iface);
/* init mac addresses of the OGM belonging to this hard-interface */
void (*bat_ogm_update_mac)(struct hard_iface *hard_iface);
/* prepare a new outgoing OGM for the send queue */
void (*bat_ogm_schedule)(struct hard_iface *hard_iface,
int tt_num_changes);
/* send scheduled OGM */
void (*bat_ogm_emit)(struct forw_packet *forw_packet);
/* receive incoming OGM */
void (*bat_ogm_receive)(struct hard_iface *if_incoming,
struct sk_buff *skb);
};
#endif /* _NET_BATMAN_ADV_TYPES_H_ */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors:
*
* Andreas Langer
*
@@ -66,8 +66,8 @@ static struct sk_buff *frag_merge_packet(struct list_head *head,
kfree_skb(tmp_skb);
memmove(skb->data + uni_diff, skb->data, hdr_len);
unicast_packet = (struct unicast_packet *) skb_pull(skb, uni_diff);
unicast_packet->packet_type = BAT_UNICAST;
unicast_packet = (struct unicast_packet *)skb_pull(skb, uni_diff);
unicast_packet->header.packet_type = BAT_UNICAST;
return skb;
@@ -238,7 +238,7 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
goto dropped;
skb_reserve(frag_skb, ucf_hdr_len);
unicast_packet = (struct unicast_packet *) skb->data;
unicast_packet = (struct unicast_packet *)skb->data;
memcpy(&tmp_uc, unicast_packet, uc_hdr_len);
skb_split(skb, frag_skb, data_len / 2 + uc_hdr_len);
@@ -251,9 +251,9 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
memcpy(frag1, &tmp_uc, sizeof(tmp_uc));
frag1->ttl--;
frag1->version = COMPAT_VERSION;
frag1->packet_type = BAT_UNICAST_FRAG;
frag1->header.ttl--;
frag1->header.version = COMPAT_VERSION;
frag1->header.packet_type = BAT_UNICAST_FRAG;
memcpy(frag1->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
memcpy(frag2, frag1, sizeof(*frag2));
@@ -320,11 +320,11 @@ find_router:
unicast_packet = (struct unicast_packet *)skb->data;
unicast_packet->version = COMPAT_VERSION;
unicast_packet->header.version = COMPAT_VERSION;
/* batman packet type: unicast */
unicast_packet->packet_type = BAT_UNICAST;
unicast_packet->header.packet_type = BAT_UNICAST;
/* set unicast ttl */
unicast_packet->ttl = TTL;
unicast_packet->header.ttl = TTL;
/* copy the destination for faster routing */
memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
/* set the destination tt version number */
@@ -335,7 +335,7 @@ find_router:
data_len + sizeof(*unicast_packet) >
neigh_node->if_incoming->net_dev->mtu) {
/* send frag skb decreases ttl */
unicast_packet->ttl++;
unicast_packet->header.ttl++;
ret = frag_send_skb(skb, bat_priv,
neigh_node->if_incoming, neigh_node->addr);
goto out;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors:
*
* Andreas Langer
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2008-2012 B.A.T.M.A.N. contributors:
*
* Simon Wunderlich
*
@@ -617,7 +617,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
packet->vis_type = atomic_read(&bat_priv->vis_mode);
memcpy(packet->target_orig, broadcast_addr, ETH_ALEN);
packet->ttl = TTL;
packet->header.ttl = TTL;
packet->seqno = htonl(ntohl(packet->seqno) + 1);
packet->entries = 0;
skb_trim(info->skb_packet, sizeof(*packet));
@@ -714,8 +714,7 @@ static void purge_vis_packets(struct bat_priv *bat_priv)
if (info == bat_priv->my_vis_info)
continue;
if (time_after(jiffies,
info->first_seen + VIS_TIMEOUT * HZ)) {
if (has_timed_out(info->first_seen, VIS_TIMEOUT)) {
hlist_del(node);
send_list_del(info);
kref_put(&info->refcount, free_info);
@@ -818,19 +817,19 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
goto out;
packet = (struct vis_packet *)info->skb_packet->data;
if (packet->ttl < 2) {
if (packet->header.ttl < 2) {
pr_debug("Error - can't send vis packet: ttl exceeded\n");
goto out;
}
memcpy(packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
packet->ttl--;
packet->header.ttl--;
if (is_broadcast_ether_addr(packet->target_orig))
broadcast_vis_packet(bat_priv, info);
else
unicast_vis_packet(bat_priv, info);
packet->ttl++; /* restore TTL */
packet->header.ttl++; /* restore TTL */
out:
if (primary_if)
@@ -910,9 +909,9 @@ int vis_init(struct bat_priv *bat_priv)
INIT_LIST_HEAD(&bat_priv->my_vis_info->send_list);
kref_init(&bat_priv->my_vis_info->refcount);
bat_priv->my_vis_info->bat_priv = bat_priv;
packet->version = COMPAT_VERSION;
packet->packet_type = BAT_VIS;
packet->ttl = TTL;
packet->header.version = COMPAT_VERSION;
packet->header.packet_type = BAT_VIS;
packet->header.ttl = TTL;
packet->seqno = 0;
packet->entries = 0;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2008-2012 B.A.T.M.A.N. contributors:
*
* Simon Wunderlich, Marek Lindner
*
@@ -22,7 +22,8 @@
#ifndef _NET_BATMAN_ADV_VIS_H_
#define _NET_BATMAN_ADV_VIS_H_
#define VIS_TIMEOUT 200 /* timeout of vis packets in seconds */
#define VIS_TIMEOUT 200000 /* timeout of vis packets
* in miliseconds */
int vis_seq_print_text(struct seq_file *seq, void *offset);
void receive_server_sync_packet(struct bat_priv *bat_priv,

View File

@@ -29,7 +29,6 @@ menuconfig BT
BNEP Module (Bluetooth Network Encapsulation Protocol)
CMTP Module (CAPI Message Transport Protocol)
HIDP Module (Human Interface Device Protocol)
SMP Module (Security Manager Protocol)
Say Y here to compile Bluetooth support into the kernel or say M to
compile it as module (bluetooth).

View File

@@ -143,10 +143,10 @@ static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
{
if (cmd == BNEPGETCONNLIST) {
struct bnep_connlist_req cl;
uint32_t uci;
u32 uci;
int err;
if (get_user(cl.cnum, (uint32_t __user *) arg) ||
if (get_user(cl.cnum, (u32 __user *) arg) ||
get_user(uci, (u32 __user *) (arg + 4)))
return -EFAULT;
@@ -157,7 +157,7 @@ static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
err = bnep_get_connlist(&cl);
if (!err && put_user(cl.cnum, (uint32_t __user *) arg))
if (!err && put_user(cl.cnum, (u32 __user *) arg))
err = -EFAULT;
return err;

View File

@@ -137,10 +137,10 @@ static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
{
if (cmd == CMTPGETCONNLIST) {
struct cmtp_connlist_req cl;
uint32_t uci;
u32 uci;
int err;
if (get_user(cl.cnum, (uint32_t __user *) arg) ||
if (get_user(cl.cnum, (u32 __user *) arg) ||
get_user(uci, (u32 __user *) (arg + 4)))
return -EFAULT;
@@ -151,7 +151,7 @@ static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
err = cmtp_get_connlist(&cl);
if (!err && put_user(cl.cnum, (uint32_t __user *) arg))
if (!err && put_user(cl.cnum, (u32 __user *) arg))
err = -EFAULT;
return err;

View File

@@ -35,7 +35,6 @@
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <net/sock.h>
#include <asm/system.h>
@@ -51,7 +50,7 @@ static void hci_le_connect(struct hci_conn *conn)
struct hci_cp_le_create_conn cp;
conn->state = BT_CONNECT;
conn->out = 1;
conn->out = true;
conn->link_mode |= HCI_LM_MASTER;
conn->sec_level = BT_SECURITY_LOW;
@@ -80,10 +79,10 @@ void hci_acl_connect(struct hci_conn *conn)
struct inquiry_entry *ie;
struct hci_cp_create_conn cp;
BT_DBG("%p", conn);
BT_DBG("hcon %p", conn);
conn->state = BT_CONNECT;
conn->out = 1;
conn->out = true;
conn->link_mode = HCI_LM_MASTER;
@@ -105,7 +104,8 @@ void hci_acl_connect(struct hci_conn *conn)
}
memcpy(conn->dev_class, ie->data.dev_class, 3);
conn->ssp_mode = ie->data.ssp_mode;
if (ie->data.ssp_mode > 0)
set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
}
cp.pkt_type = cpu_to_le16(conn->pkt_type);
@@ -151,7 +151,7 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
BT_DBG("%p", conn);
conn->state = BT_CONNECT;
conn->out = 1;
conn->out = true;
conn->attempt++;
@@ -169,7 +169,7 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
BT_DBG("%p", conn);
conn->state = BT_CONNECT;
conn->out = 1;
conn->out = true;
conn->attempt++;
@@ -279,16 +279,13 @@ static void hci_conn_timeout(struct work_struct *work)
{
struct hci_conn *conn = container_of(work, struct hci_conn,
disc_work.work);
struct hci_dev *hdev = conn->hdev;
__u8 reason;
BT_DBG("conn %p state %d", conn, conn->state);
BT_DBG("conn %p state %s", conn, state_to_string(conn->state));
if (atomic_read(&conn->refcnt))
return;
hci_dev_lock(hdev);
switch (conn->state) {
case BT_CONNECT:
case BT_CONNECT2:
@@ -308,8 +305,6 @@ static void hci_conn_timeout(struct work_struct *work)
conn->state = BT_CLOSED;
break;
}
hci_dev_unlock(hdev);
}
/* Enter sniff mode */
@@ -337,7 +332,7 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn)
hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp);
}
if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
struct hci_cp_sniff_mode cp;
cp.handle = cpu_to_le16(conn->handle);
cp.max_interval = cpu_to_le16(hdev->sniff_max_interval);
@@ -372,7 +367,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
BT_DBG("%s dst %s", hdev->name, batostr(dst));
conn = kzalloc(sizeof(struct hci_conn), GFP_ATOMIC);
conn = kzalloc(sizeof(struct hci_conn), GFP_KERNEL);
if (!conn)
return NULL;
@@ -386,7 +381,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
conn->remote_auth = 0xff;
conn->key_type = 0xff;
conn->power_save = 1;
set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
switch (type) {
@@ -407,7 +402,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
skb_queue_head_init(&conn->data_q);
INIT_LIST_HEAD(&conn->chan_list);;
INIT_LIST_HEAD(&conn->chan_list);
INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout);
setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
@@ -555,7 +550,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
if (!acl) {
acl = hci_conn_add(hdev, ACL_LINK, dst);
if (!acl)
return NULL;
return ERR_PTR(-ENOMEM);
}
hci_conn_hold(acl);
@@ -575,7 +570,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
sco = hci_conn_add(hdev, type, dst);
if (!sco) {
hci_conn_put(acl);
return NULL;
return ERR_PTR(-ENOMEM);
}
}
@@ -586,12 +581,12 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
if (acl->state == BT_CONNECTED &&
(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
acl->power_save = 1;
set_bit(HCI_CONN_POWER_SAVE, &acl->flags);
hci_conn_enter_active_mode(acl, BT_POWER_FORCE_ACTIVE_ON);
if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) {
if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->flags)) {
/* defer SCO setup until mode change completed */
set_bit(HCI_CONN_SCO_SETUP_PEND, &acl->pend);
set_bit(HCI_CONN_SCO_SETUP_PEND, &acl->flags);
return sco;
}
@@ -607,8 +602,7 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0 &&
!(conn->link_mode & HCI_LM_ENCRYPT))
if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT))
return 0;
return 1;
@@ -633,17 +627,17 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
conn->auth_type = auth_type;
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
struct hci_cp_auth_requested cp;
/* encrypt must be pending if auth is also pending */
set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
sizeof(cp), &cp);
if (conn->key_type != 0xff)
set_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
set_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
}
return 0;
@@ -654,7 +648,7 @@ static void hci_conn_encrypt(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
struct hci_cp_set_conn_encrypt cp;
cp.handle = cpu_to_le16(conn->handle);
cp.encrypt = 0x01;
@@ -674,8 +668,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
/* For non 2.1 devices and low security level we don't need the link
key. */
if (sec_level == BT_SECURITY_LOW &&
(!conn->ssp_mode || !conn->hdev->ssp_mode))
if (sec_level == BT_SECURITY_LOW && !hci_conn_ssp_enabled(conn))
return 1;
/* For other security levels we need the link key. */
@@ -704,7 +697,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
goto encrypt;
auth:
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
return 0;
if (!hci_conn_auth(conn, sec_level, auth_type))
@@ -739,7 +732,7 @@ int hci_conn_change_link_key(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
struct hci_cp_change_conn_link_key cp;
cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY,
@@ -758,7 +751,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
if (!role && conn->link_mode & HCI_LM_MASTER)
return 1;
if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->flags)) {
struct hci_cp_switch_role cp;
bacpy(&cp.bdaddr, &conn->dst);
cp.role = role;
@@ -782,10 +775,10 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
if (conn->mode != HCI_CM_SNIFF)
goto timer;
if (!conn->power_save && !force_active)
if (!test_bit(HCI_CONN_POWER_SAVE, &conn->flags) && !force_active)
goto timer;
if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
struct hci_cp_exit_sniff_mode cp;
cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_EXIT_SNIFF_MODE, sizeof(cp), &cp);
@@ -801,11 +794,11 @@ timer:
void hci_conn_hash_flush(struct hci_dev *hdev)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
struct hci_conn *c, *n;
BT_DBG("hdev %s", hdev->name);
list_for_each_entry_rcu(c, &h->list, list) {
list_for_each_entry_safe(c, n, &h->list, list) {
c->state = BT_CLOSED;
hci_proto_disconn_cfm(c, HCI_ERROR_LOCAL_HOST_TERM);
@@ -950,7 +943,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn)
BT_DBG("%s conn %p", hdev->name, conn);
chan = kzalloc(sizeof(struct hci_chan), GFP_ATOMIC);
chan = kzalloc(sizeof(struct hci_chan), GFP_KERNEL);
if (!chan)
return NULL;
@@ -981,10 +974,10 @@ int hci_chan_del(struct hci_chan *chan)
void hci_chan_list_flush(struct hci_conn *conn)
{
struct hci_chan *chan;
struct hci_chan *chan, *n;
BT_DBG("conn %p", conn);
list_for_each_entry_rcu(chan, &conn->chan_list, list)
list_for_each_entry_safe(chan, n, &conn->chan_list, list)
hci_chan_del(chan);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -48,8 +48,9 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci_mon.h>
static bool enable_mgmt;
static atomic_t monitor_promisc = ATOMIC_INIT(0);
/* ----- HCI socket interface ----- */
@@ -85,22 +86,20 @@ static struct bt_sock_list hci_sk_list = {
};
/* Send frame to RAW socket */
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
struct sock *skip_sk)
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
{
struct sock *sk;
struct hlist_node *node;
struct sk_buff *skb_copy = NULL;
BT_DBG("hdev %p len %d", hdev, skb->len);
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
struct hci_filter *flt;
struct sk_buff *nskb;
if (sk == skip_sk)
continue;
if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
continue;
@@ -108,12 +107,9 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
if (skb->sk == sk)
continue;
if (bt_cb(skb)->channel != hci_pi(sk)->channel)
if (hci_pi(sk)->channel != HCI_CHANNEL_RAW)
continue;
if (bt_cb(skb)->channel == HCI_CHANNEL_CONTROL)
goto clone;
/* Apply filter */
flt = &hci_pi(sk)->filter;
@@ -137,19 +133,301 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
continue;
}
clone:
nskb = skb_clone(skb, GFP_ATOMIC);
if (!skb_copy) {
/* Create a private copy with headroom */
skb_copy = __pskb_copy(skb, 1, GFP_ATOMIC);
if (!skb_copy)
continue;
/* Put type byte before the data */
memcpy(skb_push(skb_copy, 1), &bt_cb(skb)->pkt_type, 1);
}
nskb = skb_clone(skb_copy, GFP_ATOMIC);
if (!nskb)
continue;
/* Put type byte before the data */
if (bt_cb(skb)->channel == HCI_CHANNEL_RAW)
memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
}
read_unlock(&hci_sk_list.lock);
kfree_skb(skb_copy);
}
/* Send frame to control socket */
void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk)
{
struct sock *sk;
struct hlist_node *node;
BT_DBG("len %d", skb->len);
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
struct sk_buff *nskb;
/* Skip the original socket */
if (sk == skip_sk)
continue;
if (sk->sk_state != BT_BOUND)
continue;
if (hci_pi(sk)->channel != HCI_CHANNEL_CONTROL)
continue;
nskb = skb_clone(skb, GFP_ATOMIC);
if (!nskb)
continue;
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
}
read_unlock(&hci_sk_list.lock);
}
/* Send frame to monitor socket */
void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
{
struct sock *sk;
struct hlist_node *node;
struct sk_buff *skb_copy = NULL;
__le16 opcode;
if (!atomic_read(&monitor_promisc))
return;
BT_DBG("hdev %p len %d", hdev, skb->len);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
opcode = __constant_cpu_to_le16(HCI_MON_COMMAND_PKT);
break;
case HCI_EVENT_PKT:
opcode = __constant_cpu_to_le16(HCI_MON_EVENT_PKT);
break;
case HCI_ACLDATA_PKT:
if (bt_cb(skb)->incoming)
opcode = __constant_cpu_to_le16(HCI_MON_ACL_RX_PKT);
else
opcode = __constant_cpu_to_le16(HCI_MON_ACL_TX_PKT);
break;
case HCI_SCODATA_PKT:
if (bt_cb(skb)->incoming)
opcode = __constant_cpu_to_le16(HCI_MON_SCO_RX_PKT);
else
opcode = __constant_cpu_to_le16(HCI_MON_SCO_TX_PKT);
break;
default:
return;
}
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
struct sk_buff *nskb;
if (sk->sk_state != BT_BOUND)
continue;
if (hci_pi(sk)->channel != HCI_CHANNEL_MONITOR)
continue;
if (!skb_copy) {
struct hci_mon_hdr *hdr;
/* Create a private copy with headroom */
skb_copy = __pskb_copy(skb, HCI_MON_HDR_SIZE, GFP_ATOMIC);
if (!skb_copy)
continue;
/* Put header before the data */
hdr = (void *) skb_push(skb_copy, HCI_MON_HDR_SIZE);
hdr->opcode = opcode;
hdr->index = cpu_to_le16(hdev->id);
hdr->len = cpu_to_le16(skb->len);
}
nskb = skb_clone(skb_copy, GFP_ATOMIC);
if (!nskb)
continue;
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
}
read_unlock(&hci_sk_list.lock);
kfree_skb(skb_copy);
}
static void send_monitor_event(struct sk_buff *skb)
{
struct sock *sk;
struct hlist_node *node;
BT_DBG("len %d", skb->len);
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
struct sk_buff *nskb;
if (sk->sk_state != BT_BOUND)
continue;
if (hci_pi(sk)->channel != HCI_CHANNEL_MONITOR)
continue;
nskb = skb_clone(skb, GFP_ATOMIC);
if (!nskb)
continue;
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
}
read_unlock(&hci_sk_list.lock);
}
static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
{
struct hci_mon_hdr *hdr;
struct hci_mon_new_index *ni;
struct sk_buff *skb;
__le16 opcode;
switch (event) {
case HCI_DEV_REG:
skb = bt_skb_alloc(HCI_MON_NEW_INDEX_SIZE, GFP_ATOMIC);
if (!skb)
return NULL;
ni = (void *) skb_put(skb, HCI_MON_NEW_INDEX_SIZE);
ni->type = hdev->dev_type;
ni->bus = hdev->bus;
bacpy(&ni->bdaddr, &hdev->bdaddr);
memcpy(ni->name, hdev->name, 8);
opcode = __constant_cpu_to_le16(HCI_MON_NEW_INDEX);
break;
case HCI_DEV_UNREG:
skb = bt_skb_alloc(0, GFP_ATOMIC);
if (!skb)
return NULL;
opcode = __constant_cpu_to_le16(HCI_MON_DEL_INDEX);
break;
default:
return NULL;
}
__net_timestamp(skb);
hdr = (void *) skb_push(skb, HCI_MON_HDR_SIZE);
hdr->opcode = opcode;
hdr->index = cpu_to_le16(hdev->id);
hdr->len = cpu_to_le16(skb->len - HCI_MON_HDR_SIZE);
return skb;
}
static void send_monitor_replay(struct sock *sk)
{
struct hci_dev *hdev;
read_lock(&hci_dev_list_lock);
list_for_each_entry(hdev, &hci_dev_list, list) {
struct sk_buff *skb;
skb = create_monitor_event(hdev, HCI_DEV_REG);
if (!skb)
continue;
if (sock_queue_rcv_skb(sk, skb))
kfree_skb(skb);
}
read_unlock(&hci_dev_list_lock);
}
/* Generate internal stack event */
static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
{
struct hci_event_hdr *hdr;
struct hci_ev_stack_internal *ev;
struct sk_buff *skb;
skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
if (!skb)
return;
hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
hdr->evt = HCI_EV_STACK_INTERNAL;
hdr->plen = sizeof(*ev) + dlen;
ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
ev->type = type;
memcpy(ev->data, data, dlen);
bt_cb(skb)->incoming = 1;
__net_timestamp(skb);
bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
skb->dev = (void *) hdev;
hci_send_to_sock(hdev, skb);
kfree_skb(skb);
}
void hci_sock_dev_event(struct hci_dev *hdev, int event)
{
struct hci_ev_si_device ev;
BT_DBG("hdev %s event %d", hdev->name, event);
/* Send event to monitor */
if (atomic_read(&monitor_promisc)) {
struct sk_buff *skb;
skb = create_monitor_event(hdev, event);
if (skb) {
send_monitor_event(skb);
kfree_skb(skb);
}
}
/* Send event to sockets */
ev.event = event;
ev.dev_id = hdev->id;
hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
if (event == HCI_DEV_UNREG) {
struct sock *sk;
struct hlist_node *node;
/* Detach sockets from device */
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
bh_lock_sock_nested(sk);
if (hci_pi(sk)->hdev == hdev) {
hci_pi(sk)->hdev = NULL;
sk->sk_err = EPIPE;
sk->sk_state = BT_OPEN;
sk->sk_state_change(sk);
hci_dev_put(hdev);
}
bh_unlock_sock(sk);
}
read_unlock(&hci_sk_list.lock);
}
}
static int hci_sock_release(struct socket *sock)
@@ -164,6 +442,9 @@ static int hci_sock_release(struct socket *sock)
hdev = hci_pi(sk)->hdev;
if (hci_pi(sk)->channel == HCI_CHANNEL_MONITOR)
atomic_dec(&monitor_promisc);
bt_sock_unlink(&hci_sk_list, sk);
if (hdev) {
@@ -190,7 +471,7 @@ static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
hci_dev_lock(hdev);
err = hci_blacklist_add(hdev, &bdaddr);
err = hci_blacklist_add(hdev, &bdaddr, 0);
hci_dev_unlock(hdev);
@@ -207,7 +488,7 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
hci_dev_lock(hdev);
err = hci_blacklist_del(hdev, &bdaddr);
err = hci_blacklist_del(hdev, &bdaddr, 0);
hci_dev_unlock(hdev);
@@ -340,34 +621,69 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
if (haddr.hci_family != AF_BLUETOOTH)
return -EINVAL;
if (haddr.hci_channel > HCI_CHANNEL_CONTROL)
return -EINVAL;
if (haddr.hci_channel == HCI_CHANNEL_CONTROL) {
if (!enable_mgmt)
return -EINVAL;
set_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags);
}
lock_sock(sk);
if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) {
if (sk->sk_state == BT_BOUND) {
err = -EALREADY;
goto done;
}
if (haddr.hci_dev != HCI_DEV_NONE) {
hdev = hci_dev_get(haddr.hci_dev);
if (!hdev) {
err = -ENODEV;
switch (haddr.hci_channel) {
case HCI_CHANNEL_RAW:
if (hci_pi(sk)->hdev) {
err = -EALREADY;
goto done;
}
atomic_inc(&hdev->promisc);
if (haddr.hci_dev != HCI_DEV_NONE) {
hdev = hci_dev_get(haddr.hci_dev);
if (!hdev) {
err = -ENODEV;
goto done;
}
atomic_inc(&hdev->promisc);
}
hci_pi(sk)->hdev = hdev;
break;
case HCI_CHANNEL_CONTROL:
if (haddr.hci_dev != HCI_DEV_NONE) {
err = -EINVAL;
goto done;
}
if (!capable(CAP_NET_ADMIN)) {
err = -EPERM;
goto done;
}
break;
case HCI_CHANNEL_MONITOR:
if (haddr.hci_dev != HCI_DEV_NONE) {
err = -EINVAL;
goto done;
}
if (!capable(CAP_NET_RAW)) {
err = -EPERM;
goto done;
}
send_monitor_replay(sk);
atomic_inc(&monitor_promisc);
break;
default:
err = -EINVAL;
goto done;
}
hci_pi(sk)->channel = haddr.hci_channel;
hci_pi(sk)->hdev = hdev;
sk->sk_state = BT_BOUND;
done:
@@ -461,7 +777,15 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
skb_reset_transport_header(skb);
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
hci_sock_cmsg(sk, msg, skb);
switch (hci_pi(sk)->channel) {
case HCI_CHANNEL_RAW:
hci_sock_cmsg(sk, msg, skb);
break;
case HCI_CHANNEL_CONTROL:
case HCI_CHANNEL_MONITOR:
sock_recv_timestamp(msg, sk, skb);
break;
}
skb_free_datagram(sk, skb);
@@ -495,6 +819,9 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
case HCI_CHANNEL_CONTROL:
err = mgmt_control(sk, msg, len);
goto done;
case HCI_CHANNEL_MONITOR:
err = -EOPNOTSUPP;
goto done;
default:
err = -EINVAL;
goto done;
@@ -574,6 +901,11 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char
lock_sock(sk);
if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
err = -EINVAL;
goto done;
}
switch (optname) {
case HCI_DATA_DIR:
if (get_user(opt, (int __user *)optval)) {
@@ -636,6 +968,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char
break;
}
done:
release_sock(sk);
return err;
}
@@ -644,11 +977,20 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char
{
struct hci_ufilter uf;
struct sock *sk = sock->sk;
int len, opt;
int len, opt, err = 0;
BT_DBG("sk %p, opt %d", sk, optname);
if (get_user(len, optlen))
return -EFAULT;
lock_sock(sk);
if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
err = -EINVAL;
goto done;
}
switch (optname) {
case HCI_DATA_DIR:
if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
@@ -657,7 +999,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char
opt = 0;
if (put_user(opt, optval))
return -EFAULT;
err = -EFAULT;
break;
case HCI_TIME_STAMP:
@@ -667,7 +1009,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char
opt = 0;
if (put_user(opt, optval))
return -EFAULT;
err = -EFAULT;
break;
case HCI_FILTER:
@@ -682,15 +1024,17 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char
len = min_t(unsigned int, len, sizeof(uf));
if (copy_to_user(optval, &uf, len))
return -EFAULT;
err = -EFAULT;
break;
default:
return -ENOPROTOOPT;
err = -ENOPROTOOPT;
break;
}
return 0;
done:
release_sock(sk);
return err;
}
static const struct proto_ops hci_sock_ops = {
@@ -748,52 +1092,12 @@ static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
return 0;
}
static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct hci_dev *hdev = (struct hci_dev *) ptr;
struct hci_ev_si_device ev;
BT_DBG("hdev %s event %ld", hdev->name, event);
/* Send event to sockets */
ev.event = event;
ev.dev_id = hdev->id;
hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
if (event == HCI_DEV_UNREG) {
struct sock *sk;
struct hlist_node *node;
/* Detach sockets from device */
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
bh_lock_sock_nested(sk);
if (hci_pi(sk)->hdev == hdev) {
hci_pi(sk)->hdev = NULL;
sk->sk_err = EPIPE;
sk->sk_state = BT_OPEN;
sk->sk_state_change(sk);
hci_dev_put(hdev);
}
bh_unlock_sock(sk);
}
read_unlock(&hci_sk_list.lock);
}
return NOTIFY_DONE;
}
static const struct net_proto_family hci_sock_family_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = hci_sock_create,
};
static struct notifier_block hci_sock_nblock = {
.notifier_call = hci_sock_dev_event
};
int __init hci_sock_init(void)
{
int err;
@@ -806,8 +1110,6 @@ int __init hci_sock_init(void)
if (err < 0)
goto error;
hci_register_notifier(&hci_sock_nblock);
BT_INFO("HCI socket layer initialized");
return 0;
@@ -823,10 +1125,5 @@ void hci_sock_cleanup(void)
if (bt_sock_unregister(BTPROTO_HCI) < 0)
BT_ERR("HCI socket unregistration failed");
hci_unregister_notifier(&hci_sock_nblock);
proto_unregister(&hci_sk_proto);
}
module_param(enable_mgmt, bool, 0644);
MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");

View File

@@ -33,19 +33,19 @@ static inline char *link_typetostr(int type)
static ssize_t show_link_type(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
struct hci_conn *conn = to_hci_conn(dev);
return sprintf(buf, "%s\n", link_typetostr(conn->type));
}
static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
struct hci_conn *conn = to_hci_conn(dev);
return sprintf(buf, "%s\n", batostr(&conn->dst));
}
static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
struct hci_conn *conn = to_hci_conn(dev);
return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
conn->features[0], conn->features[1],
@@ -79,8 +79,8 @@ static const struct attribute_group *bt_link_groups[] = {
static void bt_link_release(struct device *dev)
{
void *data = dev_get_drvdata(dev);
kfree(data);
struct hci_conn *conn = to_hci_conn(dev);
kfree(conn);
}
static struct device_type bt_link = {
@@ -120,8 +120,6 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
dev_set_drvdata(&conn->dev, conn);
if (device_add(&conn->dev) < 0) {
BT_ERR("Failed to register connection device");
return;
@@ -189,19 +187,19 @@ static inline char *host_typetostr(int type)
static ssize_t show_bus(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%s\n", host_bustostr(hdev->bus));
}
static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%s\n", host_typetostr(hdev->dev_type));
}
static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
char name[HCI_MAX_NAME_LENGTH + 1];
int i;
@@ -214,20 +212,20 @@ static ssize_t show_name(struct device *dev, struct device_attribute *attr, char
static ssize_t show_class(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "0x%.2x%.2x%.2x\n",
hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
}
static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%s\n", batostr(&hdev->bdaddr));
}
static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
hdev->features[0], hdev->features[1],
@@ -238,31 +236,31 @@ static ssize_t show_features(struct device *dev, struct device_attribute *attr,
static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%d\n", hdev->manufacturer);
}
static ssize_t show_hci_version(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%d\n", hdev->hci_ver);
}
static ssize_t show_hci_revision(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%d\n", hdev->hci_rev);
}
static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%d\n", hdev->idle_timeout);
}
static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
unsigned int val;
int rv;
@@ -280,13 +278,13 @@ static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *a
static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%d\n", hdev->sniff_max_interval);
}
static ssize_t store_sniff_max_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
u16 val;
int rv;
@@ -304,13 +302,13 @@ static ssize_t store_sniff_max_interval(struct device *dev, struct device_attrib
static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%d\n", hdev->sniff_min_interval);
}
static ssize_t store_sniff_min_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
u16 val;
int rv;
@@ -370,8 +368,9 @@ static const struct attribute_group *bt_host_groups[] = {
static void bt_host_release(struct device *dev)
{
void *data = dev_get_drvdata(dev);
kfree(data);
struct hci_dev *hdev = to_hci_dev(dev);
kfree(hdev);
module_put(THIS_MODULE);
}
static struct device_type bt_host = {
@@ -383,12 +382,12 @@ static struct device_type bt_host = {
static int inquiry_cache_show(struct seq_file *f, void *p)
{
struct hci_dev *hdev = f->private;
struct inquiry_cache *cache = &hdev->inq_cache;
struct discovery_state *cache = &hdev->discovery;
struct inquiry_entry *e;
hci_dev_lock(hdev);
for (e = cache->list; e; e = e->next) {
list_for_each_entry(e, &cache->all, all) {
struct inquiry_data *data = &e->data;
seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
batostr(&data->bdaddr),
@@ -523,7 +522,7 @@ void hci_init_sysfs(struct hci_dev *hdev)
dev->type = &bt_host;
dev->class = bt_class;
dev_set_drvdata(dev, hdev);
__module_get(THIS_MODULE);
device_initialize(dev);
}

View File

@@ -160,10 +160,10 @@ static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
{
if (cmd == HIDPGETCONNLIST) {
struct hidp_connlist_req cl;
uint32_t uci;
u32 uci;
int err;
if (get_user(cl.cnum, (uint32_t __user *) arg) ||
if (get_user(cl.cnum, (u32 __user *) arg) ||
get_user(uci, (u32 __user *) (arg + 4)))
return -EFAULT;
@@ -174,7 +174,7 @@ static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
err = hidp_get_connlist(&cl);
if (!err && put_user(cl.cnum, (uint32_t __user *) arg))
if (!err && put_user(cl.cnum, (u32 __user *) arg))
err = -EFAULT;
return err;

File diff suppressed because it is too large Load Diff

View File

@@ -125,13 +125,15 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
err = l2cap_chan_connect(chan, la.l2_psm, la.l2_cid, &la.l2_bdaddr);
if (err)
goto done;
return err;
lock_sock(sk);
err = bt_sock_wait_state(sk, BT_CONNECTED,
sock_sndtimeo(sk, flags & O_NONBLOCK));
done:
if (sock_owned_by_user(sk))
release_sock(sk);
release_sock(sk);
return err;
}
@@ -783,7 +785,7 @@ static void l2cap_sock_kill(struct sock *sk)
if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
return;
BT_DBG("sk %p state %d", sk, sk->sk_state);
BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state));
/* Kill poor orphan */
@@ -795,7 +797,8 @@ static void l2cap_sock_kill(struct sock *sk)
static int l2cap_sock_shutdown(struct socket *sock, int how)
{
struct sock *sk = sock->sk;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct l2cap_chan *chan;
struct l2cap_conn *conn;
int err = 0;
BT_DBG("sock %p, sk %p", sock, sk);
@@ -803,13 +806,24 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
if (!sk)
return 0;
chan = l2cap_pi(sk)->chan;
conn = chan->conn;
if (conn)
mutex_lock(&conn->chan_lock);
l2cap_chan_lock(chan);
lock_sock(sk);
if (!sk->sk_shutdown) {
if (chan->mode == L2CAP_MODE_ERTM)
err = __l2cap_wait_ack(sk);
sk->sk_shutdown = SHUTDOWN_MASK;
release_sock(sk);
l2cap_chan_close(chan, 0);
lock_sock(sk);
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
err = bt_sock_wait_state(sk, BT_CLOSED,
@@ -820,6 +834,11 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
err = -sk->sk_err;
release_sock(sk);
l2cap_chan_unlock(chan);
if (conn)
mutex_unlock(&conn->chan_lock);
return err;
}
@@ -862,8 +881,12 @@ static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb)
struct sock *sk = data;
struct l2cap_pinfo *pi = l2cap_pi(sk);
if (pi->rx_busy_skb)
return -ENOMEM;
lock_sock(sk);
if (pi->rx_busy_skb) {
err = -ENOMEM;
goto done;
}
err = sock_queue_rcv_skb(sk, skb);
@@ -882,6 +905,9 @@ static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb)
err = 0;
}
done:
release_sock(sk);
return err;
}
@@ -899,12 +925,22 @@ static void l2cap_sock_state_change_cb(void *data, int state)
sk->sk_state = state;
}
static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
unsigned long len, int nb,
int *err)
{
struct sock *sk = chan->sk;
return bt_skb_send_alloc(sk, len, nb, err);
}
static struct l2cap_ops l2cap_chan_ops = {
.name = "L2CAP Socket Interface",
.new_connection = l2cap_sock_new_connection_cb,
.recv = l2cap_sock_recv_cb,
.close = l2cap_sock_close_cb,
.state_change = l2cap_sock_state_change_cb,
.alloc_skb = l2cap_sock_alloc_skb_cb,
};
static void l2cap_sock_destruct(struct sock *sk)
@@ -1004,7 +1040,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
sk->sk_destruct = l2cap_sock_destruct;
sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
sock_reset_flag(sk, SOCK_ZAPPED);

View File

@@ -24,6 +24,8 @@
/* Bluetooth kernel library. */
#define pr_fmt(fmt) "Bluetooth: " fmt
#include <linux/module.h>
#include <linux/kernel.h>
@@ -151,7 +153,7 @@ int bt_to_errno(__u16 code)
}
EXPORT_SYMBOL(bt_to_errno);
int bt_printk(const char *level, const char *format, ...)
int bt_info(const char *format, ...)
{
struct va_format vaf;
va_list args;
@@ -162,10 +164,29 @@ int bt_printk(const char *level, const char *format, ...)
vaf.fmt = format;
vaf.va = &args;
r = printk("%sBluetooth: %pV\n", level, &vaf);
r = pr_info("%pV", &vaf);
va_end(args);
return r;
}
EXPORT_SYMBOL(bt_printk);
EXPORT_SYMBOL(bt_info);
int bt_err(const char *format, ...)
{
struct va_format vaf;
va_list args;
int r;
va_start(args, format);
vaf.fmt = format;
vaf.va = &args;
r = pr_err("%pV", &vaf);
va_end(args);
return r;
}
EXPORT_SYMBOL(bt_err);

File diff suppressed because it is too large Load Diff

View File

@@ -196,7 +196,7 @@ static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
{
struct rfcomm_dev *dev, *entry;
struct list_head *head = &rfcomm_dev_list, *p;
struct list_head *head = &rfcomm_dev_list;
int err = 0;
BT_DBG("id %d channel %d", req->dev_id, req->channel);
@@ -215,7 +215,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
break;
dev->id++;
head = p;
head = &entry->list;
}
} else {
dev->id = req->dev_id;
@@ -229,7 +229,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
if (entry->id > dev->id - 1)
break;
head = p;
head = &entry->list;
}
}

View File

@@ -29,7 +29,7 @@
#include <linux/scatterlist.h>
#include <crypto/b128ops.h>
#define SMP_TIMEOUT 30000 /* 30 seconds */
#define SMP_TIMEOUT msecs_to_jiffies(30000)
static inline void swap128(u8 src[16], u8 dst[16])
{
@@ -186,8 +186,7 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
hci_send_acl(conn->hchan, skb, 0);
cancel_delayed_work_sync(&conn->security_timer);
schedule_delayed_work(&conn->security_timer,
msecs_to_jiffies(SMP_TIMEOUT));
schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT);
}
static __u8 authreq_to_seclevel(__u8 authreq)
@@ -217,7 +216,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
{
u8 dist_keys = 0;
if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->flags)) {
if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) {
dist_keys = SMP_DIST_ENC_KEY;
authreq |= SMP_AUTH_BONDING;
} else {
@@ -250,21 +249,27 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
(max_key_size < SMP_MIN_ENC_KEY_SIZE))
return SMP_ENC_KEY_SIZE;
smp->smp_key_size = max_key_size;
smp->enc_key_size = max_key_size;
return 0;
}
static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
{
struct hci_conn *hcon = conn->hcon;
if (send)
smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
&reason);
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->pend);
mgmt_auth_failed(conn->hcon->hdev, conn->dst, reason);
cancel_delayed_work_sync(&conn->security_timer);
smp_chan_destroy(conn);
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags);
mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type,
hcon->dst_type, reason);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
cancel_delayed_work_sync(&conn->security_timer);
smp_chan_destroy(conn);
}
}
#define JUST_WORKS 0x00
@@ -305,7 +310,7 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
remote_io > SMP_IO_KEYBOARD_DISPLAY)
method = JUST_WORKS;
else
method = gen_method[local_io][remote_io];
method = gen_method[remote_io][local_io];
/* If not bonding, don't ask user to confirm a Zero TK */
if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
@@ -346,9 +351,11 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
hci_dev_lock(hcon->hdev);
if (method == REQ_PASSKEY)
ret = mgmt_user_passkey_request(hcon->hdev, conn->dst);
ret = mgmt_user_passkey_request(hcon->hdev, conn->dst,
hcon->type, hcon->dst_type);
else
ret = mgmt_user_confirm_request(hcon->hdev, conn->dst,
hcon->type, hcon->dst_type,
cpu_to_le32(passkey), 0);
hci_dev_unlock(hcon->hdev);
@@ -377,12 +384,11 @@ static void confirm_work(struct work_struct *work)
if (conn->hcon->out)
ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp, 0,
conn->src, conn->hcon->dst_type, conn->dst,
res);
conn->src, conn->hcon->dst_type, conn->dst, res);
else
ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
conn->hcon->dst_type, conn->dst, 0, conn->src,
res);
conn->hcon->dst_type, conn->dst, 0, conn->src,
res);
if (ret) {
reason = SMP_UNSPECIFIED;
goto error;
@@ -417,12 +423,10 @@ static void random_work(struct work_struct *work)
if (hcon->out)
ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, 0,
conn->src, hcon->dst_type, conn->dst,
res);
conn->src, hcon->dst_type, conn->dst, res);
else
ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
hcon->dst_type, conn->dst, 0, conn->src,
res);
hcon->dst_type, conn->dst, 0, conn->src, res);
if (ret) {
reason = SMP_UNSPECIFIED;
goto error;
@@ -446,16 +450,16 @@ static void random_work(struct work_struct *work)
smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, key);
swap128(key, stk);
memset(stk + smp->smp_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->smp_key_size);
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend)) {
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) {
reason = SMP_UNSPECIFIED;
goto error;
}
hci_le_start_enc(hcon, ediv, rand, stk);
hcon->enc_key_size = smp->smp_key_size;
hcon->enc_key_size = smp->enc_key_size;
} else {
u8 stk[16], r[16], rand[8];
__le16 ediv;
@@ -469,11 +473,12 @@ static void random_work(struct work_struct *work)
smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, key);
swap128(key, stk);
memset(stk + smp->smp_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->smp_key_size);
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
hci_add_ltk(hcon->hdev, 0, conn->dst, smp->smp_key_size,
ediv, rand, stk);
hci_add_ltk(hcon->hdev, conn->dst, hcon->dst_type,
HCI_SMP_STK_SLAVE, 0, 0, stk, smp->enc_key_size,
ediv, rand);
}
return;
@@ -506,7 +511,7 @@ void smp_chan_destroy(struct l2cap_conn *conn)
{
struct smp_chan *smp = conn->smp_chan;
clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend);
BUG_ON(!smp);
if (smp->tfm)
crypto_free_blkcipher(smp->tfm);
@@ -571,7 +576,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
if (conn->hcon->link_mode & HCI_LM_MASTER)
return SMP_CMD_NOTSUPP;
if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend))
if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
smp = smp_chan_create(conn);
smp = conn->smp_chan;
@@ -584,6 +589,8 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
if (req->auth_req & SMP_AUTH_BONDING)
auth = req->auth_req;
conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
build_pairing_cmd(conn, req, &rsp, auth);
key_size = min(req->max_key_size, rsp.max_key_size);
@@ -698,23 +705,18 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
{
struct link_key *key;
struct key_master_id *master;
struct smp_ltk *key;
struct hci_conn *hcon = conn->hcon;
key = hci_find_link_key_type(hcon->hdev, conn->dst,
HCI_LK_SMP_LTK);
key = hci_find_ltk_by_addr(hcon->hdev, conn->dst, hcon->dst_type);
if (!key)
return 0;
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND,
&hcon->pend))
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
return 1;
master = (void *) key->data;
hci_le_start_enc(hcon, master->ediv, master->rand,
key->val);
hcon->enc_key_size = key->pin_len;
hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
hcon->enc_key_size = key->enc_size;
return 1;
@@ -733,7 +735,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
if (smp_ltk_encrypt(conn))
return 0;
if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend))
if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
return 0;
smp = smp_chan_create(conn);
@@ -772,7 +774,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
if (smp_ltk_encrypt(conn))
goto done;
if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend))
if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
return 0;
smp = smp_chan_create(conn);
@@ -817,13 +819,19 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct smp_cmd_master_ident *rp = (void *) skb->data;
struct smp_chan *smp = conn->smp_chan;
struct hci_dev *hdev = conn->hcon->hdev;
struct hci_conn *hcon = conn->hcon;
u8 authenticated;
skb_pull(skb, sizeof(*rp));
hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->smp_key_size,
rp->ediv, rp->rand, smp->tk);
hci_dev_lock(hdev);
authenticated = (conn->hcon->sec_level == BT_SECURITY_HIGH);
hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
HCI_SMP_LTK, 1, authenticated, smp->tk, smp->enc_key_size,
rp->ediv, rp->rand);
smp_distribute_keys(conn, 1);
hci_dev_unlock(hdev);
return 0;
}
@@ -908,7 +916,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
BT_DBG("conn %p force %d", conn, force);
if (!test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend))
if (!test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
return 0;
rsp = (void *) &smp->prsp[1];
@@ -933,6 +941,8 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
if (*keydist & SMP_DIST_ENC_KEY) {
struct smp_cmd_encrypt_info enc;
struct smp_cmd_master_ident ident;
struct hci_conn *hcon = conn->hcon;
u8 authenticated;
__le16 ediv;
get_random_bytes(enc.ltk, sizeof(enc.ltk));
@@ -941,8 +951,10 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->smp_key_size,
ediv, ident.rand, enc.ltk);
authenticated = hcon->sec_level == BT_SECURITY_HIGH;
hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
HCI_SMP_LTK_SLAVE, 1, authenticated,
enc.ltk, smp->enc_key_size, ediv, ident.rand);
ident.ediv = cpu_to_le16(ediv);
@@ -982,7 +994,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
}
if (conn->hcon->out || force) {
clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend);
clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
cancel_delayed_work_sync(&conn->security_timer);
smp_chan_destroy(conn);
}

View File

@@ -167,10 +167,11 @@ static int br_set_mac_address(struct net_device *dev, void *p)
struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
return -EINVAL;
return -EADDRNOTAVAIL;
spin_lock_bh(&br->lock);
if (compare_ether_addr(dev->dev_addr, addr->sa_data)) {
dev->addr_assign_type &= ~NET_ADDR_RANDOM;
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
br_fdb_change_mac_address(br, addr->sa_data);
br_stp_change_bridge_id(br, addr->sa_data);
@@ -334,7 +335,7 @@ void br_dev_setup(struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);
random_ether_addr(dev->dev_addr);
eth_hw_addr_random(dev);
ether_setup(dev);
dev->netdev_ops = &br_netdev_ops;

View File

@@ -162,7 +162,6 @@ void caif_flow_cb(struct sk_buff *skb)
static int transmit(struct cflayer *layer, struct cfpkt *pkt)
{
int err, high = 0, qlen = 0;
struct caif_dev_common *caifdev;
struct caif_device_entry *caifd =
container_of(layer, struct caif_device_entry, layer);
struct sk_buff *skb;
@@ -174,7 +173,6 @@ static int transmit(struct cflayer *layer, struct cfpkt *pkt)
skb->dev = caifd->netdev;
skb_reset_network_header(skb);
skb->protocol = htons(ETH_P_CAIF);
caifdev = netdev_priv(caifd->netdev);
/* Check if we need to handle xoff */
if (likely(caifd->netdev->tx_queue_len == 0))

View File

@@ -43,34 +43,9 @@ enum caif_states {
#define TX_FLOW_ON_BIT 1
#define RX_FLOW_ON_BIT 2
static struct dentry *debugfsdir;
#ifdef CONFIG_DEBUG_FS
struct debug_fs_counter {
atomic_t caif_nr_socks;
atomic_t caif_sock_create;
atomic_t num_connect_req;
atomic_t num_connect_resp;
atomic_t num_connect_fail_resp;
atomic_t num_disconnect;
atomic_t num_remote_shutdown_ind;
atomic_t num_tx_flow_off_ind;
atomic_t num_tx_flow_on_ind;
atomic_t num_rx_flow_off;
atomic_t num_rx_flow_on;
};
static struct debug_fs_counter cnt;
#define dbfs_atomic_inc(v) atomic_inc_return(v)
#define dbfs_atomic_dec(v) atomic_dec_return(v)
#else
#define dbfs_atomic_inc(v) 0
#define dbfs_atomic_dec(v) 0
#endif
struct caifsock {
struct sock sk; /* must be first member */
struct cflayer layer;
char name[CAIF_LAYER_NAME_SZ]; /* Used for debugging */
u32 flow_state;
struct caif_connect_request conn_req;
struct mutex readlock;
@@ -161,7 +136,6 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
atomic_read(&cf_sk->sk.sk_rmem_alloc),
sk_rcvbuf_lowwater(cf_sk));
set_rx_flow_off(cf_sk);
dbfs_atomic_inc(&cnt.num_rx_flow_off);
caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
}
@@ -172,7 +146,6 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
set_rx_flow_off(cf_sk);
if (net_ratelimit())
pr_debug("sending flow OFF due to rmem_schedule\n");
dbfs_atomic_inc(&cnt.num_rx_flow_off);
caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
}
skb->dev = NULL;
@@ -233,14 +206,12 @@ static void caif_ctrl_cb(struct cflayer *layr,
switch (flow) {
case CAIF_CTRLCMD_FLOW_ON_IND:
/* OK from modem to start sending again */
dbfs_atomic_inc(&cnt.num_tx_flow_on_ind);
set_tx_flow_on(cf_sk);
cf_sk->sk.sk_state_change(&cf_sk->sk);
break;
case CAIF_CTRLCMD_FLOW_OFF_IND:
/* Modem asks us to shut up */
dbfs_atomic_inc(&cnt.num_tx_flow_off_ind);
set_tx_flow_off(cf_sk);
cf_sk->sk.sk_state_change(&cf_sk->sk);
break;
@@ -249,7 +220,6 @@ static void caif_ctrl_cb(struct cflayer *layr,
/* We're now connected */
caif_client_register_refcnt(&cf_sk->layer,
cfsk_hold, cfsk_put);
dbfs_atomic_inc(&cnt.num_connect_resp);
cf_sk->sk.sk_state = CAIF_CONNECTED;
set_tx_flow_on(cf_sk);
cf_sk->sk.sk_state_change(&cf_sk->sk);
@@ -263,7 +233,6 @@ static void caif_ctrl_cb(struct cflayer *layr,
case CAIF_CTRLCMD_INIT_FAIL_RSP:
/* Connect request failed */
dbfs_atomic_inc(&cnt.num_connect_fail_resp);
cf_sk->sk.sk_err = ECONNREFUSED;
cf_sk->sk.sk_state = CAIF_DISCONNECTED;
cf_sk->sk.sk_shutdown = SHUTDOWN_MASK;
@@ -277,7 +246,6 @@ static void caif_ctrl_cb(struct cflayer *layr,
case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND:
/* Modem has closed this connection, or device is down. */
dbfs_atomic_inc(&cnt.num_remote_shutdown_ind);
cf_sk->sk.sk_shutdown = SHUTDOWN_MASK;
cf_sk->sk.sk_err = ECONNRESET;
set_rx_flow_on(cf_sk);
@@ -297,7 +265,6 @@ static void caif_check_flow_release(struct sock *sk)
return;
if (atomic_read(&sk->sk_rmem_alloc) <= sk_rcvbuf_lowwater(cf_sk)) {
dbfs_atomic_inc(&cnt.num_rx_flow_on);
set_rx_flow_on(cf_sk);
caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_ON_REQ);
}
@@ -856,7 +823,6 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
/*ifindex = id of the interface.*/
cf_sk->conn_req.ifindex = cf_sk->sk.sk_bound_dev_if;
dbfs_atomic_inc(&cnt.num_connect_req);
cf_sk->layer.receive = caif_sktrecv_cb;
err = caif_connect_client(sock_net(sk), &cf_sk->conn_req,
@@ -945,8 +911,6 @@ static int caif_release(struct socket *sock)
spin_unlock_bh(&sk->sk_receive_queue.lock);
sock->sk = NULL;
dbfs_atomic_inc(&cnt.num_disconnect);
WARN_ON(IS_ERR(cf_sk->debugfs_socket_dir));
if (cf_sk->debugfs_socket_dir != NULL)
debugfs_remove_recursive(cf_sk->debugfs_socket_dir);
@@ -1054,14 +1018,12 @@ static void caif_sock_destructor(struct sock *sk)
return;
}
sk_stream_kill_queues(&cf_sk->sk);
dbfs_atomic_dec(&cnt.caif_nr_socks);
caif_free_client(&cf_sk->layer);
}
static int caif_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
int num;
struct sock *sk = NULL;
struct caifsock *cf_sk = NULL;
static struct proto prot = {.name = "PF_CAIF",
@@ -1122,34 +1084,6 @@ static int caif_create(struct net *net, struct socket *sock, int protocol,
cf_sk->sk.sk_priority = CAIF_PRIO_NORMAL;
cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY;
cf_sk->conn_req.protocol = protocol;
/* Increase the number of sockets created. */
dbfs_atomic_inc(&cnt.caif_nr_socks);
num = dbfs_atomic_inc(&cnt.caif_sock_create);
#ifdef CONFIG_DEBUG_FS
if (!IS_ERR(debugfsdir)) {
/* Fill in some information concerning the misc socket. */
snprintf(cf_sk->name, sizeof(cf_sk->name), "cfsk%d", num);
cf_sk->debugfs_socket_dir =
debugfs_create_dir(cf_sk->name, debugfsdir);
debugfs_create_u32("sk_state", S_IRUSR | S_IWUSR,
cf_sk->debugfs_socket_dir,
(u32 *) &cf_sk->sk.sk_state);
debugfs_create_u32("flow_state", S_IRUSR | S_IWUSR,
cf_sk->debugfs_socket_dir, &cf_sk->flow_state);
debugfs_create_u32("sk_rmem_alloc", S_IRUSR | S_IWUSR,
cf_sk->debugfs_socket_dir,
(u32 *) &cf_sk->sk.sk_rmem_alloc);
debugfs_create_u32("sk_wmem_alloc", S_IRUSR | S_IWUSR,
cf_sk->debugfs_socket_dir,
(u32 *) &cf_sk->sk.sk_wmem_alloc);
debugfs_create_u32("identity", S_IRUSR | S_IWUSR,
cf_sk->debugfs_socket_dir,
(u32 *) &cf_sk->layer.id);
}
#endif
release_sock(&cf_sk->sk);
return 0;
}
@@ -1161,7 +1095,7 @@ static struct net_proto_family caif_family_ops = {
.owner = THIS_MODULE,
};
static int af_caif_init(void)
static int __init caif_sktinit_module(void)
{
int err = sock_register(&caif_family_ops);
if (!err)
@@ -1169,54 +1103,9 @@ static int af_caif_init(void)
return 0;
}
static int __init caif_sktinit_module(void)
{
#ifdef CONFIG_DEBUG_FS
debugfsdir = debugfs_create_dir("caif_sk", NULL);
if (!IS_ERR(debugfsdir)) {
debugfs_create_u32("num_sockets", S_IRUSR | S_IWUSR,
debugfsdir,
(u32 *) &cnt.caif_nr_socks);
debugfs_create_u32("num_create", S_IRUSR | S_IWUSR,
debugfsdir,
(u32 *) &cnt.caif_sock_create);
debugfs_create_u32("num_connect_req", S_IRUSR | S_IWUSR,
debugfsdir,
(u32 *) &cnt.num_connect_req);
debugfs_create_u32("num_connect_resp", S_IRUSR | S_IWUSR,
debugfsdir,
(u32 *) &cnt.num_connect_resp);
debugfs_create_u32("num_connect_fail_resp", S_IRUSR | S_IWUSR,
debugfsdir,
(u32 *) &cnt.num_connect_fail_resp);
debugfs_create_u32("num_disconnect", S_IRUSR | S_IWUSR,
debugfsdir,
(u32 *) &cnt.num_disconnect);
debugfs_create_u32("num_remote_shutdown_ind",
S_IRUSR | S_IWUSR, debugfsdir,
(u32 *) &cnt.num_remote_shutdown_ind);
debugfs_create_u32("num_tx_flow_off_ind", S_IRUSR | S_IWUSR,
debugfsdir,
(u32 *) &cnt.num_tx_flow_off_ind);
debugfs_create_u32("num_tx_flow_on_ind", S_IRUSR | S_IWUSR,
debugfsdir,
(u32 *) &cnt.num_tx_flow_on_ind);
debugfs_create_u32("num_rx_flow_off", S_IRUSR | S_IWUSR,
debugfsdir,
(u32 *) &cnt.num_rx_flow_off);
debugfs_create_u32("num_rx_flow_on", S_IRUSR | S_IWUSR,
debugfsdir,
(u32 *) &cnt.num_rx_flow_on);
}
#endif
return af_caif_init();
}
static void __exit caif_sktexit_module(void)
{
sock_unregister(PF_CAIF);
if (debugfsdir != NULL)
debugfs_remove_recursive(debugfsdir);
}
module_init(caif_sktinit_module);
module_exit(caif_sktexit_module);

View File

@@ -41,8 +41,10 @@ static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt)
struct caif_payload_info *info;
int ret;
if (!cfsrvl_ready(service, &ret))
if (!cfsrvl_ready(service, &ret)) {
cfpkt_destroy(pkt);
return ret;
}
/* Add info for MUX-layer to route the packet out */
info = cfpkt_info(pkt);

View File

@@ -86,12 +86,17 @@ static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt)
struct caif_payload_info *info;
struct cfsrvl *service = container_obj(layr);
int ret;
if (!cfsrvl_ready(service, &ret))
if (!cfsrvl_ready(service, &ret)) {
cfpkt_destroy(pkt);
return ret;
}
/* STE Modem cannot handle more than 1500 bytes datagrams */
if (cfpkt_getlen(pkt) > DGM_MTU)
if (cfpkt_getlen(pkt) > DGM_MTU) {
cfpkt_destroy(pkt);
return -EMSGSIZE;
}
cfpkt_add_head(pkt, &zero, 3);
packet_type = 0x08; /* B9 set - UNCLASSIFIED */

View File

@@ -184,6 +184,11 @@ out:
rfml->serv.dev_info.id);
}
spin_unlock(&rfml->sync);
if (unlikely(err == -EAGAIN))
/* It is not possible to recover after drop of a fragment */
err = -EIO;
return err;
}
@@ -218,7 +223,7 @@ static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt)
caif_assert(layr->dn->transmit != NULL);
if (!cfsrvl_ready(&rfml->serv, &err))
return err;
goto out;
err = -EPROTO;
if (cfpkt_getlen(pkt) <= RFM_HEAD_SIZE-1)
@@ -251,8 +256,11 @@ static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt)
err = cfrfml_transmit_segment(rfml, frontpkt);
if (err != 0)
if (err != 0) {
frontpkt = NULL;
goto out;
}
frontpkt = rearpkt;
rearpkt = NULL;
@@ -286,19 +294,8 @@ out:
if (rearpkt)
cfpkt_destroy(rearpkt);
if (frontpkt && frontpkt != pkt) {
if (frontpkt)
cfpkt_destroy(frontpkt);
/*
* Socket layer will free the original packet,
* but this packet may already be sent and
* freed. So we have to return 0 in this case
* to avoid socket layer to re-free this packet.
* The return of shutdown indication will
* cause connection to be invalidated anyhow.
*/
err = 0;
}
}
return err;

View File

@@ -174,15 +174,11 @@ void cfsrvl_init(struct cfsrvl *service,
bool cfsrvl_ready(struct cfsrvl *service, int *err)
{
if (service->open && service->modem_flow_on && service->phy_flow_on)
return true;
if (!service->open) {
*err = -ENOTCONN;
return false;
}
caif_assert(!(service->modem_flow_on && service->phy_flow_on));
*err = -EAGAIN;
return false;
return true;
}
u8 cfsrvl_getphyid(struct cflayer *layer)

View File

@@ -84,8 +84,11 @@ static int cfutill_transmit(struct cflayer *layr, struct cfpkt *pkt)
caif_assert(layr != NULL);
caif_assert(layr->dn != NULL);
caif_assert(layr->dn->transmit != NULL);
if (!cfsrvl_ready(service, &ret))
if (!cfsrvl_ready(service, &ret)) {
cfpkt_destroy(pkt);
return ret;
}
cfpkt_add_head(pkt, &zero, 1);
/* Add info for MUX-layer to route the packet out. */

View File

@@ -50,8 +50,12 @@ static int cfvidl_transmit(struct cflayer *layr, struct cfpkt *pkt)
struct caif_payload_info *info;
u32 videoheader = 0;
int ret;
if (!cfsrvl_ready(service, &ret))
if (!cfsrvl_ready(service, &ret)) {
cfpkt_destroy(pkt);
return ret;
}
cfpkt_add_head(pkt, &videoheader, 4);
/* Add info for MUX-layer to route the packet out */
info = cfpkt_info(pkt);

View File

@@ -28,6 +28,7 @@
/* 5 sec. connect timeout */
#define CONNECT_TIMEOUT (5 * HZ)
#define CAIF_NET_DEFAULT_QUEUE_LEN 500
#define UNDEF_CONNID 0xffffffff
/*This list is protected by the rtnl lock. */
static LIST_HEAD(chnl_net_list);
@@ -72,14 +73,12 @@ static void robust_list_del(struct list_head *delete_node)
static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
{
struct sk_buff *skb;
struct chnl_net *priv = container_of(layr, struct chnl_net, chnl);
struct chnl_net *priv;
int pktlen;
int err = 0;
const u8 *ip_version;
u8 buf;
priv = container_of(layr, struct chnl_net, chnl);
if (!priv)
return -EINVAL;
@@ -95,8 +94,7 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
/* check the version of IP */
ip_version = skb_header_pointer(skb, 0, 1, &buf);
if (!ip_version)
return -EINVAL;
switch (*ip_version >> 4) {
case 4:
skb->protocol = htons(ETH_P_IP);
@@ -105,6 +103,7 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
skb->protocol = htons(ETH_P_IPV6);
break;
default:
priv->netdev->stats.rx_errors++;
return -EINVAL;
}
@@ -123,7 +122,7 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
priv->netdev->stats.rx_packets++;
priv->netdev->stats.rx_bytes += pktlen;
return err;
return 0;
}
static int delete_device(struct chnl_net *dev)
@@ -221,11 +220,13 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb->len > priv->netdev->mtu) {
pr_warn("Size of skb exceeded MTU\n");
dev->stats.tx_errors++;
return -ENOSPC;
}
if (!priv->flowenabled) {
pr_debug("dropping packets flow off\n");
dev->stats.tx_dropped++;
return NETDEV_TX_BUSY;
}
@@ -240,8 +241,7 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Send the packet down the stack. */
result = priv->chnl.dn->transmit(priv->chnl.dn, pkt);
if (result) {
if (result == -EAGAIN)
result = NETDEV_TX_BUSY;
dev->stats.tx_dropped++;
return result;
}
@@ -409,7 +409,7 @@ static void ipcaif_net_setup(struct net_device *dev)
priv->conn_req.link_selector = CAIF_LINK_HIGH_BANDW;
priv->conn_req.priority = CAIF_PRIO_LOW;
/* Insert illegal value */
priv->conn_req.sockaddr.u.dgm.connection_id = 0;
priv->conn_req.sockaddr.u.dgm.connection_id = UNDEF_CONNID;
priv->flowenabled = false;
init_waitqueue_head(&priv->netmgmt_wq);
@@ -472,9 +472,11 @@ static int ipcaif_newlink(struct net *src_net, struct net_device *dev,
else
list_add(&caifdev->list_field, &chnl_net_list);
/* Take ifindex as connection-id if null */
if (caifdev->conn_req.sockaddr.u.dgm.connection_id == 0)
/* Use ifindex as connection id, and use loopback channel default. */
if (caifdev->conn_req.sockaddr.u.dgm.connection_id == UNDEF_CONNID) {
caifdev->conn_req.sockaddr.u.dgm.connection_id = dev->ifindex;
caifdev->conn_req.protocol = CAIFPROTO_DATAGRAM_LOOP;
}
return ret;
}

View File

@@ -79,7 +79,7 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
/* I've named the args so it is easy to tell whose space the pointers are in. */
int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
struct sockaddr *kern_address, int mode)
struct sockaddr_storage *kern_address, int mode)
{
int tot_len;

View File

@@ -132,6 +132,8 @@ out_noerr:
* __skb_recv_datagram - Receive a datagram skbuff
* @sk: socket
* @flags: MSG_ flags
* @off: an offset in bytes to peek skb from. Returns an offset
* within an skb where data actually starts
* @peeked: returns non-zero if this packet has been seen before
* @err: error code returned
*
@@ -158,7 +160,7 @@ out_noerr:
* the standard around please.
*/
struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
int *peeked, int *err)
int *peeked, int *off, int *err)
{
struct sk_buff *skb;
long timeo;
@@ -180,21 +182,25 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
* However, this function was correct in any case. 8)
*/
unsigned long cpu_flags;
struct sk_buff_head *queue = &sk->sk_receive_queue;
spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
skb = skb_peek(&sk->sk_receive_queue);
if (skb) {
spin_lock_irqsave(&queue->lock, cpu_flags);
skb_queue_walk(queue, skb) {
*peeked = skb->peeked;
if (flags & MSG_PEEK) {
if (*off >= skb->len) {
*off -= skb->len;
continue;
}
skb->peeked = 1;
atomic_inc(&skb->users);
} else
__skb_unlink(skb, &sk->sk_receive_queue);
}
spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);
__skb_unlink(skb, queue);
if (skb)
spin_unlock_irqrestore(&queue->lock, cpu_flags);
return skb;
}
spin_unlock_irqrestore(&queue->lock, cpu_flags);
/* User doesn't want to wait */
error = -EAGAIN;
@@ -214,10 +220,10 @@ EXPORT_SYMBOL(__skb_recv_datagram);
struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
int noblock, int *err)
{
int peeked;
int peeked, off = 0;
return __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
&peeked, err);
&peeked, &off, err);
}
EXPORT_SYMBOL(skb_recv_datagram);

View File

@@ -446,7 +446,7 @@ void __dev_remove_pack(struct packet_type *pt)
}
}
printk(KERN_WARNING "dev_remove_pack: %p not found.\n", pt);
pr_warn("dev_remove_pack: %p not found\n", pt);
out:
spin_unlock(&ptype_lock);
}
@@ -848,21 +848,21 @@ EXPORT_SYMBOL(dev_get_by_flags_rcu);
* to allow sysfs to work. We also disallow any kind of
* whitespace.
*/
int dev_valid_name(const char *name)
bool dev_valid_name(const char *name)
{
if (*name == '\0')
return 0;
return false;
if (strlen(name) >= IFNAMSIZ)
return 0;
return false;
if (!strcmp(name, ".") || !strcmp(name, ".."))
return 0;
return false;
while (*name) {
if (*name == '/' || isspace(*name))
return 0;
return false;
name++;
}
return 1;
return true;
}
EXPORT_SYMBOL(dev_valid_name);
@@ -1039,8 +1039,7 @@ rollback:
memcpy(dev->name, oldname, IFNAMSIZ);
goto rollback;
} else {
printk(KERN_ERR
"%s: name change rollback failed: %d.\n",
pr_err("%s: name change rollback failed: %d\n",
dev->name, ret);
}
}
@@ -1139,9 +1138,8 @@ void dev_load(struct net *net, const char *name)
no_module = request_module("netdev-%s", name);
if (no_module && capable(CAP_SYS_MODULE)) {
if (!request_module("%s", name))
pr_err("Loading kernel module for a network device "
"with CAP_SYS_MODULE (deprecated). Use CAP_NET_ADMIN and alias netdev-%s "
"instead\n", name);
pr_err("Loading kernel module for a network device with CAP_SYS_MODULE (deprecated). Use CAP_NET_ADMIN and alias netdev-%s instead.\n",
name);
}
}
EXPORT_SYMBOL(dev_load);
@@ -1655,10 +1653,9 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
if (skb_network_header(skb2) < skb2->data ||
skb2->network_header > skb2->tail) {
if (net_ratelimit())
printk(KERN_CRIT "protocol %04x is "
"buggy, dev %s\n",
ntohs(skb2->protocol),
dev->name);
pr_crit("protocol %04x is buggy, dev %s\n",
ntohs(skb2->protocol),
dev->name);
skb_reset_network_header(skb2);
}
@@ -1691,9 +1688,7 @@ static void netif_setup_tc(struct net_device *dev, unsigned int txq)
/* If TC0 is invalidated disable TC mapping */
if (tc->offset + tc->count > txq) {
pr_warning("Number of in use tx queues changed "
"invalidating tc mappings. Priority "
"traffic classification disabled!\n");
pr_warn("Number of in use tx queues changed invalidating tc mappings. Priority traffic classification disabled!\n");
dev->num_tc = 0;
return;
}
@@ -1704,11 +1699,8 @@ static void netif_setup_tc(struct net_device *dev, unsigned int txq)
tc = &dev->tc_to_txq[q];
if (tc->offset + tc->count > txq) {
pr_warning("Number of in use tx queues "
"changed. Priority %i to tc "
"mapping %i is no longer valid "
"setting map to 0\n",
i, q);
pr_warn("Number of in use tx queues changed. Priority %i to tc mapping %i is no longer valid. Setting map to 0\n",
i, q);
netdev_set_prio_tc_map(dev, i, 0);
}
}
@@ -2014,8 +2006,7 @@ EXPORT_SYMBOL(skb_gso_segment);
void netdev_rx_csum_fault(struct net_device *dev)
{
if (net_ratelimit()) {
printk(KERN_ERR "%s: hw csum failure.\n",
dev ? dev->name : "<unknown>");
pr_err("%s: hw csum failure\n", dev ? dev->name : "<unknown>");
dump_stack();
}
}
@@ -2332,9 +2323,9 @@ static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index)
{
if (unlikely(queue_index >= dev->real_num_tx_queues)) {
if (net_ratelimit()) {
pr_warning("%s selects TX queue %d, but "
"real number of TX queues is %d\n",
dev->name, queue_index, dev->real_num_tx_queues);
pr_warn("%s selects TX queue %d, but real number of TX queues is %d\n",
dev->name, queue_index,
dev->real_num_tx_queues);
}
return 0;
}
@@ -2578,16 +2569,16 @@ int dev_queue_xmit(struct sk_buff *skb)
}
HARD_TX_UNLOCK(dev, txq);
if (net_ratelimit())
printk(KERN_CRIT "Virtual device %s asks to "
"queue packet!\n", dev->name);
pr_crit("Virtual device %s asks to queue packet!\n",
dev->name);
} else {
/* Recursion is detected! It is possible,
* unfortunately
*/
recursion_alert:
if (net_ratelimit())
printk(KERN_CRIT "Dead loop on virtual device "
"%s, fix it urgently!\n", dev->name);
pr_crit("Dead loop on virtual device %s, fix it urgently!\n",
dev->name);
}
}
@@ -3069,8 +3060,8 @@ static int ing_filter(struct sk_buff *skb, struct netdev_queue *rxq)
if (unlikely(MAX_RED_LOOP < ttl++)) {
if (net_ratelimit())
pr_warning( "Redir loop detected Dropping packet (%d->%d)\n",
skb->skb_iif, dev->ifindex);
pr_warn("Redir loop detected Dropping packet (%d->%d)\n",
skb->skb_iif, dev->ifindex);
return TC_ACT_SHOT;
}
@@ -4497,16 +4488,15 @@ static int __dev_set_promiscuity(struct net_device *dev, int inc)
dev->flags &= ~IFF_PROMISC;
else {
dev->promiscuity -= inc;
printk(KERN_WARNING "%s: promiscuity touches roof, "
"set promiscuity failed, promiscuity feature "
"of device might be broken.\n", dev->name);
pr_warn("%s: promiscuity touches roof, set promiscuity failed. promiscuity feature of device might be broken.\n",
dev->name);
return -EOVERFLOW;
}
}
if (dev->flags != old_flags) {
printk(KERN_INFO "device %s %s promiscuous mode\n",
dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
"left");
pr_info("device %s %s promiscuous mode\n",
dev->name,
dev->flags & IFF_PROMISC ? "entered" : "left");
if (audit_enabled) {
current_uid_gid(&uid, &gid);
audit_log(current->audit_context, GFP_ATOMIC,
@@ -4579,9 +4569,8 @@ int dev_set_allmulti(struct net_device *dev, int inc)
dev->flags &= ~IFF_ALLMULTI;
else {
dev->allmulti -= inc;
printk(KERN_WARNING "%s: allmulti touches roof, "
"set allmulti failed, allmulti feature of "
"device might be broken.\n", dev->name);
pr_warn("%s: allmulti touches roof, set allmulti failed. allmulti feature of device might be broken.\n",
dev->name);
return -EOVERFLOW;
}
}
@@ -5238,8 +5227,8 @@ static void rollback_registered_many(struct list_head *head)
* devices and proceed with the remaining.
*/
if (dev->reg_state == NETREG_UNINITIALIZED) {
pr_debug("unregister_netdevice: device %s/%p never "
"was registered\n", dev->name, dev);
pr_debug("unregister_netdevice: device %s/%p never was registered\n",
dev->name, dev);
WARN_ON(1);
list_del(&dev->unreg_list);
@@ -5471,7 +5460,7 @@ static int netif_alloc_rx_queues(struct net_device *dev)
rx = kcalloc(count, sizeof(struct netdev_rx_queue), GFP_KERNEL);
if (!rx) {
pr_err("netdev: Unable to allocate %u rx queues.\n", count);
pr_err("netdev: Unable to allocate %u rx queues\n", count);
return -ENOMEM;
}
dev->_rx = rx;
@@ -5505,8 +5494,7 @@ static int netif_alloc_netdev_queues(struct net_device *dev)
tx = kcalloc(count, sizeof(struct netdev_queue), GFP_KERNEL);
if (!tx) {
pr_err("netdev: Unable to allocate %u tx queues.\n",
count);
pr_err("netdev: Unable to allocate %u tx queues\n", count);
return -ENOMEM;
}
dev->_tx = tx;
@@ -5765,10 +5753,8 @@ static void netdev_wait_allrefs(struct net_device *dev)
refcnt = netdev_refcnt_read(dev);
if (time_after(jiffies, warning_time + 10 * HZ)) {
printk(KERN_EMERG "unregister_netdevice: "
"waiting for %s to become free. Usage "
"count = %d\n",
dev->name, refcnt);
pr_emerg("unregister_netdevice: waiting for %s to become free. Usage count = %d\n",
dev->name, refcnt);
warning_time = jiffies;
}
}
@@ -5819,7 +5805,7 @@ void netdev_run_todo(void)
list_del(&dev->todo_list);
if (unlikely(dev->reg_state != NETREG_UNREGISTERING)) {
printk(KERN_ERR "network todo '%s' but state %d\n",
pr_err("network todo '%s' but state %d\n",
dev->name, dev->reg_state);
dump_stack();
continue;
@@ -5848,12 +5834,12 @@ void netdev_run_todo(void)
/* Convert net_device_stats to rtnl_link_stats64. They have the same
* fields in the same order, with only the type differing.
*/
static void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
const struct net_device_stats *netdev_stats)
void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
const struct net_device_stats *netdev_stats)
{
#if BITS_PER_LONG == 64
BUILD_BUG_ON(sizeof(*stats64) != sizeof(*netdev_stats));
memcpy(stats64, netdev_stats, sizeof(*stats64));
BUILD_BUG_ON(sizeof(*stats64) != sizeof(*netdev_stats));
memcpy(stats64, netdev_stats, sizeof(*stats64));
#else
size_t i, n = sizeof(*stats64) / sizeof(u64);
const unsigned long *src = (const unsigned long *)netdev_stats;
@@ -5865,6 +5851,7 @@ static void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
dst[i] = src[i];
#endif
}
EXPORT_SYMBOL(netdev_stats_to_stats64);
/**
* dev_get_stats - get network device statistics
@@ -5935,15 +5922,13 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
BUG_ON(strlen(name) >= sizeof(dev->name));
if (txqs < 1) {
pr_err("alloc_netdev: Unable to allocate device "
"with zero queues.\n");
pr_err("alloc_netdev: Unable to allocate device with zero queues\n");
return NULL;
}
#ifdef CONFIG_RPS
if (rxqs < 1) {
pr_err("alloc_netdev: Unable to allocate device "
"with zero RX queues.\n");
pr_err("alloc_netdev: Unable to allocate device with zero RX queues\n");
return NULL;
}
#endif
@@ -5959,7 +5944,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
p = kzalloc(alloc_size, GFP_KERNEL);
if (!p) {
printk(KERN_ERR "alloc_netdev: Unable to allocate device.\n");
pr_err("alloc_netdev: Unable to allocate device\n");
return NULL;
}
@@ -6492,8 +6477,8 @@ static void __net_exit default_device_exit(struct net *net)
snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex);
err = dev_change_net_namespace(dev, &init_net, fb_name);
if (err) {
printk(KERN_EMERG "%s: failed to move %s to init_net: %d\n",
__func__, dev->name, err);
pr_emerg("%s: failed to move %s to init_net: %d\n",
__func__, dev->name, err);
BUG();
}
}

View File

@@ -73,6 +73,8 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]
[NETIF_F_RXCSUM_BIT] = "rx-checksum",
[NETIF_F_NOCACHE_COPY_BIT] = "tx-nocache-copy",
[NETIF_F_LOOPBACK_BIT] = "loopback",
[NETIF_F_RXFCS_BIT] = "rx-fcs",
[NETIF_F_RXALL_BIT] = "rx-all",
};
static int ethtool_get_features(struct net_device *dev, void __user *useraddr)

View File

@@ -35,7 +35,7 @@
* in any case.
*/
int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *address, int mode)
{
int size, ct, err;

View File

@@ -2167,6 +2167,35 @@ nla_put_failure:
return -EMSGSIZE;
}
static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn,
u32 pid, u32 seq, int type, unsigned int flags,
struct neigh_table *tbl)
{
struct nlmsghdr *nlh;
struct ndmsg *ndm;
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags);
if (nlh == NULL)
return -EMSGSIZE;
ndm = nlmsg_data(nlh);
ndm->ndm_family = tbl->family;
ndm->ndm_pad1 = 0;
ndm->ndm_pad2 = 0;
ndm->ndm_flags = pn->flags | NTF_PROXY;
ndm->ndm_type = NDA_DST;
ndm->ndm_ifindex = pn->dev->ifindex;
ndm->ndm_state = NUD_NONE;
NLA_PUT(skb, NDA_DST, tbl->key_len, pn->key);
return nlmsg_end(skb, nlh);
nla_put_failure:
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
static void neigh_update_notify(struct neighbour *neigh)
{
call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
@@ -2216,23 +2245,78 @@ out:
return rc;
}
static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
struct netlink_callback *cb)
{
struct pneigh_entry *n;
struct net *net = sock_net(skb->sk);
int rc, h, s_h = cb->args[3];
int idx, s_idx = idx = cb->args[4];
read_lock_bh(&tbl->lock);
for (h = 0; h <= PNEIGH_HASHMASK; h++) {
if (h < s_h)
continue;
if (h > s_h)
s_idx = 0;
for (n = tbl->phash_buckets[h], idx = 0; n; n = n->next) {
if (dev_net(n->dev) != net)
continue;
if (idx < s_idx)
goto next;
if (pneigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq,
RTM_NEWNEIGH,
NLM_F_MULTI, tbl) <= 0) {
read_unlock_bh(&tbl->lock);
rc = -1;
goto out;
}
next:
idx++;
}
}
read_unlock_bh(&tbl->lock);
rc = skb->len;
out:
cb->args[3] = h;
cb->args[4] = idx;
return rc;
}
static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
{
struct neigh_table *tbl;
int t, family, s_t;
int proxy = 0;
int err = 0;
read_lock(&neigh_tbl_lock);
family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family;
/* check for full ndmsg structure presence, family member is
* the same for both structures
*/
if (nlmsg_len(cb->nlh) >= sizeof(struct ndmsg) &&
((struct ndmsg *) nlmsg_data(cb->nlh))->ndm_flags == NTF_PROXY)
proxy = 1;
s_t = cb->args[0];
for (tbl = neigh_tables, t = 0; tbl; tbl = tbl->next, t++) {
for (tbl = neigh_tables, t = 0; tbl && (err >= 0);
tbl = tbl->next, t++) {
if (t < s_t || (family && tbl->family != family))
continue;
if (t > s_t)
memset(&cb->args[1], 0, sizeof(cb->args) -
sizeof(cb->args[0]));
if (neigh_dump_table(tbl, skb, cb) < 0)
break;
if (proxy)
err = pneigh_dump_table(tbl, skb, cb);
else
err = neigh_dump_table(tbl, skb, cb);
}
read_unlock(&neigh_tbl_lock);

View File

@@ -9,6 +9,8 @@
* Copyright (C) 2002 Red Hat, Inc.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/moduleparam.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -45,9 +47,11 @@ static atomic_t trapped;
#define NETPOLL_RX_ENABLED 1
#define NETPOLL_RX_DROP 2
#define MAX_SKB_SIZE \
(MAX_UDP_CHUNK + sizeof(struct udphdr) + \
sizeof(struct iphdr) + sizeof(struct ethhdr))
#define MAX_SKB_SIZE \
(sizeof(struct ethhdr) + \
sizeof(struct iphdr) + \
sizeof(struct udphdr) + \
MAX_UDP_CHUNK)
static void zap_completion_queue(void);
static void arp_reply(struct sk_buff *skb);
@@ -55,6 +59,13 @@ static void arp_reply(struct sk_buff *skb);
static unsigned int carrier_timeout = 4;
module_param(carrier_timeout, uint, 0644);
#define np_info(np, fmt, ...) \
pr_info("%s: " fmt, np->name, ##__VA_ARGS__)
#define np_err(np, fmt, ...) \
pr_err("%s: " fmt, np->name, ##__VA_ARGS__)
#define np_notice(np, fmt, ...) \
pr_notice("%s: " fmt, np->name, ##__VA_ARGS__)
static void queue_process(struct work_struct *work)
{
struct netpoll_info *npinfo =
@@ -627,18 +638,12 @@ out:
void netpoll_print_options(struct netpoll *np)
{
printk(KERN_INFO "%s: local port %d\n",
np->name, np->local_port);
printk(KERN_INFO "%s: local IP %pI4\n",
np->name, &np->local_ip);
printk(KERN_INFO "%s: interface '%s'\n",
np->name, np->dev_name);
printk(KERN_INFO "%s: remote port %d\n",
np->name, np->remote_port);
printk(KERN_INFO "%s: remote IP %pI4\n",
np->name, &np->remote_ip);
printk(KERN_INFO "%s: remote ethernet address %pM\n",
np->name, np->remote_mac);
np_info(np, "local port %d\n", np->local_port);
np_info(np, "local IP %pI4\n", &np->local_ip);
np_info(np, "interface '%s'\n", np->dev_name);
np_info(np, "remote port %d\n", np->remote_port);
np_info(np, "remote IP %pI4\n", &np->remote_ip);
np_info(np, "remote ethernet address %pM\n", np->remote_mac);
}
EXPORT_SYMBOL(netpoll_print_options);
@@ -680,8 +685,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
goto parse_failed;
*delim = 0;
if (*cur == ' ' || *cur == '\t')
printk(KERN_INFO "%s: warning: whitespace"
"is not allowed\n", np->name);
np_info(np, "warning: whitespace is not allowed\n");
np->remote_port = simple_strtol(cur, NULL, 10);
cur = delim;
}
@@ -705,8 +709,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
return 0;
parse_failed:
printk(KERN_INFO "%s: couldn't parse config at '%s'!\n",
np->name, cur);
np_info(np, "couldn't parse config at '%s'!\n", cur);
return -1;
}
EXPORT_SYMBOL(netpoll_parse_options);
@@ -721,8 +724,8 @@ int __netpoll_setup(struct netpoll *np)
if ((ndev->priv_flags & IFF_DISABLE_NETPOLL) ||
!ndev->netdev_ops->ndo_poll_controller) {
printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",
np->name, np->dev_name);
np_err(np, "%s doesn't support polling, aborting\n",
np->dev_name);
err = -ENOTSUPP;
goto out;
}
@@ -785,14 +788,12 @@ int netpoll_setup(struct netpoll *np)
if (np->dev_name)
ndev = dev_get_by_name(&init_net, np->dev_name);
if (!ndev) {
printk(KERN_ERR "%s: %s doesn't exist, aborting.\n",
np->name, np->dev_name);
np_err(np, "%s doesn't exist, aborting\n", np->dev_name);
return -ENODEV;
}
if (ndev->master) {
printk(KERN_ERR "%s: %s is a slave device, aborting.\n",
np->name, np->dev_name);
np_err(np, "%s is a slave device, aborting\n", np->dev_name);
err = -EBUSY;
goto put;
}
@@ -800,16 +801,14 @@ int netpoll_setup(struct netpoll *np)
if (!netif_running(ndev)) {
unsigned long atmost, atleast;
printk(KERN_INFO "%s: device %s not up yet, forcing it\n",
np->name, np->dev_name);
np_info(np, "device %s not up yet, forcing it\n", np->dev_name);
rtnl_lock();
err = dev_open(ndev);
rtnl_unlock();
if (err) {
printk(KERN_ERR "%s: failed to open %s\n",
np->name, ndev->name);
np_err(np, "failed to open %s\n", ndev->name);
goto put;
}
@@ -817,9 +816,7 @@ int netpoll_setup(struct netpoll *np)
atmost = jiffies + carrier_timeout * HZ;
while (!netif_carrier_ok(ndev)) {
if (time_after(jiffies, atmost)) {
printk(KERN_NOTICE
"%s: timeout waiting for carrier\n",
np->name);
np_notice(np, "timeout waiting for carrier\n");
break;
}
msleep(1);
@@ -831,9 +828,7 @@ int netpoll_setup(struct netpoll *np)
*/
if (time_before(jiffies, atleast)) {
printk(KERN_NOTICE "%s: carrier detect appears"
" untrustworthy, waiting 4 seconds\n",
np->name);
np_notice(np, "carrier detect appears untrustworthy, waiting 4 seconds\n");
msleep(4000);
}
}
@@ -844,15 +839,15 @@ int netpoll_setup(struct netpoll *np)
if (!in_dev || !in_dev->ifa_list) {
rcu_read_unlock();
printk(KERN_ERR "%s: no IP address for %s, aborting\n",
np->name, np->dev_name);
np_err(np, "no IP address for %s, aborting\n",
np->dev_name);
err = -EDESTADDRREQ;
goto put;
}
np->local_ip = in_dev->ifa_list->ifa_local;
rcu_read_unlock();
printk(KERN_INFO "%s: local IP %pI4\n", np->name, &np->local_ip);
np_info(np, "local IP %pI4\n", &np->local_ip);
}
np->dev = ndev;

View File

@@ -1133,6 +1133,8 @@ static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
.len = sizeof(struct ifla_vf_vlan) },
[IFLA_VF_TX_RATE] = { .type = NLA_BINARY,
.len = sizeof(struct ifla_vf_tx_rate) },
[IFLA_VF_SPOOFCHK] = { .type = NLA_BINARY,
.len = sizeof(struct ifla_vf_spoofchk) },
};
static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = {
@@ -2019,8 +2021,13 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
__rtnl_unlock();
rtnl = net->rtnl;
err = netlink_dump_start(rtnl, skb, nlh, dumpit,
NULL, min_dump_alloc);
{
struct netlink_dump_control c = {
.dump = dumpit,
.min_dump_alloc = min_dump_alloc,
};
err = netlink_dump_start(rtnl, skb, nlh, &c);
}
rtnl_lock();
return err;
}

View File

@@ -592,6 +592,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->rxhash = old->rxhash;
new->ooo_okay = old->ooo_okay;
new->l4_rxhash = old->l4_rxhash;
new->no_fcs = old->no_fcs;
#ifdef CONFIG_XFRM
new->sp = secpath_get(old->sp);
#endif
@@ -2906,7 +2907,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
nskb->prev = p;
nskb->data_len += p->len;
nskb->truesize += p->len;
nskb->truesize += p->truesize;
nskb->len += p->len;
*head = nskb;
@@ -2916,6 +2917,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
p = nskb;
merge:
p->truesize += skb->truesize - len;
if (offset > headlen) {
unsigned int eat = offset - headlen;

View File

@@ -793,6 +793,17 @@ set_rcvbuf:
sock_valbool_flag(sk, SOCK_WIFI_STATUS, valbool);
break;
case SO_PEEK_OFF:
if (sock->ops->set_peek_off)
sock->ops->set_peek_off(sk, val);
else
ret = -EOPNOTSUPP;
break;
case SO_NOFCS:
sock_valbool_flag(sk, SOCK_NOFCS, valbool);
break;
default:
ret = -ENOPROTOOPT;
break;
@@ -1018,6 +1029,15 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
v.val = !!sock_flag(sk, SOCK_WIFI_STATUS);
break;
case SO_PEEK_OFF:
if (!sock->ops->set_peek_off)
return -EOPNOTSUPP;
v.val = sk->sk_peek_off;
break;
case SO_NOFCS:
v.val = !!sock_flag(sk, SOCK_NOFCS);
break;
default:
return -ENOPROTOOPT;
}
@@ -2092,6 +2112,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
sk->sk_sndmsg_page = NULL;
sk->sk_sndmsg_off = 0;
sk->sk_peek_off = -1;
sk->sk_peer_pid = NULL;
sk->sk_peer_cred = NULL;

View File

@@ -98,6 +98,7 @@ static void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hc)
{
hc->tx_t_ipi = scaled_div32(((u64)hc->tx_s) << 6, hc->tx_x);
DCCP_BUG_ON(hc->tx_t_ipi == 0);
ccid3_pr_debug("t_ipi=%u, s=%u, X=%u\n", hc->tx_t_ipi,
hc->tx_s, (unsigned)(hc->tx_x >> 6));
}
@@ -236,8 +237,6 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
*
* Note that X_recv is scaled by 2^6 while X_calc is not
*/
BUG_ON(hc->tx_p && !hc->tx_x_calc);
if (hc->tx_x_calc > (hc->tx_x_recv >> 5))
hc->tx_x_recv =
max(hc->tx_x_recv / 2,

View File

@@ -300,7 +300,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
*/
WARN_ON(req->sk);
if (seq != dccp_rsk(req)->dreq_iss) {
if (!between48(seq, dccp_rsk(req)->dreq_iss,
dccp_rsk(req)->dreq_gss)) {
NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
goto out;
}
@@ -639,11 +640,12 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
*
* Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
*
* In fact we defer setting S.GSR, S.SWL, S.SWH to
* dccp_create_openreq_child.
* Setting S.SWL/S.SWH to is deferred to dccp_create_openreq_child().
*/
dreq->dreq_isr = dcb->dccpd_seq;
dreq->dreq_gsr = dreq->dreq_isr;
dreq->dreq_iss = dccp_v4_init_sequence(skb);
dreq->dreq_gss = dreq->dreq_iss;
dreq->dreq_service = service;
if (dccp_v4_send_response(sk, req, NULL))

View File

@@ -193,7 +193,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
*/
WARN_ON(req->sk != NULL);
if (seq != dccp_rsk(req)->dreq_iss) {
if (!between48(seq, dccp_rsk(req)->dreq_iss,
dccp_rsk(req)->dreq_gss)) {
NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
goto out;
}
@@ -440,11 +441,12 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
*
* Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
*
* In fact we defer setting S.GSR, S.SWL, S.SWH to
* dccp_create_openreq_child.
* Setting S.SWL/S.SWH to is deferred to dccp_create_openreq_child().
*/
dreq->dreq_isr = dcb->dccpd_seq;
dreq->dreq_gsr = dreq->dreq_isr;
dreq->dreq_iss = dccp_v6_init_sequence(skb);
dreq->dreq_gss = dreq->dreq_iss;
dreq->dreq_service = service;
if (dccp_v6_send_response(sk, req, NULL))

View File

@@ -127,9 +127,11 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
* activation below, as these windows all depend on the local
* and remote Sequence Window feature values (7.5.2).
*/
newdp->dccps_gss = newdp->dccps_iss = dreq->dreq_iss;
newdp->dccps_iss = dreq->dreq_iss;
newdp->dccps_gss = dreq->dreq_gss;
newdp->dccps_gar = newdp->dccps_iss;
newdp->dccps_gsr = newdp->dccps_isr = dreq->dreq_isr;
newdp->dccps_isr = dreq->dreq_isr;
newdp->dccps_gsr = dreq->dreq_gsr;
/*
* Activate features: initialise CCIDs, sequence windows etc.
@@ -164,9 +166,9 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
/* Check for retransmitted REQUEST */
if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) {
if (after48(DCCP_SKB_CB(skb)->dccpd_seq, dreq->dreq_isr)) {
if (after48(DCCP_SKB_CB(skb)->dccpd_seq, dreq->dreq_gsr)) {
dccp_pr_debug("Retransmitted REQUEST\n");
dreq->dreq_isr = DCCP_SKB_CB(skb)->dccpd_seq;
dreq->dreq_gsr = DCCP_SKB_CB(skb)->dccpd_seq;
/*
* Send another RESPONSE packet
* To protect against Request floods, increment retrans
@@ -186,12 +188,14 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
goto drop;
/* Invalid ACK */
if (DCCP_SKB_CB(skb)->dccpd_ack_seq != dreq->dreq_iss) {
if (!between48(DCCP_SKB_CB(skb)->dccpd_ack_seq,
dreq->dreq_iss, dreq->dreq_gss)) {
dccp_pr_debug("Invalid ACK number: ack_seq=%llu, "
"dreq_iss=%llu\n",
"dreq_iss=%llu, dreq_gss=%llu\n",
(unsigned long long)
DCCP_SKB_CB(skb)->dccpd_ack_seq,
(unsigned long long) dreq->dreq_iss);
(unsigned long long) dreq->dreq_iss,
(unsigned long long) dreq->dreq_gss);
goto drop;
}

View File

@@ -408,10 +408,10 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
skb_dst_set(skb, dst_clone(dst));
dreq = dccp_rsk(req);
if (inet_rsk(req)->acked) /* increase ISS upon retransmission */
dccp_inc_seqno(&dreq->dreq_iss);
if (inet_rsk(req)->acked) /* increase GSS upon retransmission */
dccp_inc_seqno(&dreq->dreq_gss);
DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss;
DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_gss;
/* Resolve feature dependencies resulting from choice of CCID */
if (dccp_feat_server_ccid_dependencies(dreq))
@@ -429,8 +429,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
dh->dccph_type = DCCP_PKT_RESPONSE;
dh->dccph_x = 1;
dccp_hdr_set_seq(dh, dreq->dreq_iss);
dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_isr);
dccp_hdr_set_seq(dh, dreq->dreq_gss);
dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_gsr);
dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service;
dccp_csum_outgoing(skb);

View File

@@ -205,17 +205,23 @@ static int dn_neigh_output_packet(struct sk_buff *skb)
struct neighbour *neigh = dst_get_neighbour_noref(dst);
struct net_device *dev = neigh->dev;
char mac_addr[ETH_ALEN];
unsigned int seq;
int err;
dn_dn2eth(mac_addr, rt->rt_local_src);
if (dev_hard_header(skb, dev, ntohs(skb->protocol), neigh->ha,
mac_addr, skb->len) >= 0)
return dev_queue_xmit(skb);
do {
seq = read_seqbegin(&neigh->ha_lock);
err = dev_hard_header(skb, dev, ntohs(skb->protocol),
neigh->ha, mac_addr, skb->len);
} while (read_seqretry(&neigh->ha_lock, seq));
if (net_ratelimit())
printk(KERN_DEBUG "dn_neigh_output_packet: oops, can't send packet\n");
kfree_skb(skb);
return -EINVAL;
if (err >= 0)
err = dev_queue_xmit(skb);
else {
kfree_skb(skb);
err = -EINVAL;
}
return err;
}
static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb)

View File

@@ -724,11 +724,10 @@ static int dn_output(struct sk_buff *skb)
struct dn_route *rt = (struct dn_route *)dst;
struct net_device *dev = dst->dev;
struct dn_skb_cb *cb = DN_SKB_CB(skb);
struct neighbour *neigh;
int err = -EINVAL;
if ((neigh = dst_get_neighbour_noref(dst)) == NULL)
if (dst_get_neighbour_noref(dst) == NULL)
goto error;
skb->dev = dev;

View File

@@ -288,6 +288,8 @@ int eth_mac_addr(struct net_device *dev, void *p)
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
/* if device marked as NET_ADDR_RANDOM, reset it */
dev->addr_assign_type &= ~NET_ADDR_RANDOM;
return 0;
}
EXPORT_SYMBOL(eth_mac_addr);

View File

@@ -55,6 +55,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <net/af_ieee802154.h>
#include <net/ieee802154.h>
#include <net/ieee802154_netdev.h>
@@ -924,19 +925,6 @@ drop:
return -EINVAL;
}
static int lowpan_set_address(struct net_device *dev, void *p)
{
struct sockaddr *sa = p;
if (netif_running(dev))
return -EBUSY;
/* TODO: validate addr */
memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
return 0;
}
static int lowpan_get_mac_header_length(struct sk_buff *skb)
{
/*
@@ -1062,7 +1050,7 @@ static struct header_ops lowpan_header_ops = {
static const struct net_device_ops lowpan_netdev_ops = {
.ndo_start_xmit = lowpan_xmit,
.ndo_set_mac_address = lowpan_set_address,
.ndo_set_mac_address = eth_mac_addr,
};
static void lowpan_setup(struct net_device *dev)

View File

@@ -65,6 +65,8 @@
* 2 of the License, or (at your option) any later version.
*/
#define pr_fmt(fmt) "IPv4: " fmt
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/types.h>
@@ -381,6 +383,7 @@ lookup_protocol:
inet->mc_all = 1;
inet->mc_index = 0;
inet->mc_list = NULL;
inet->rcv_tos = 0;
sk_refcnt_debug_inc(sk);
@@ -1084,13 +1087,11 @@ out:
return;
out_permanent:
printk(KERN_ERR "Attempt to override permanent protocol %d.\n",
protocol);
pr_err("Attempt to override permanent protocol %d\n", protocol);
goto out;
out_illegal:
printk(KERN_ERR
"Ignoring attempt to register invalid socket type %d.\n",
pr_err("Ignoring attempt to register invalid socket type %d\n",
p->type);
goto out;
}
@@ -1099,8 +1100,7 @@ EXPORT_SYMBOL(inet_register_protosw);
void inet_unregister_protosw(struct inet_protosw *p)
{
if (INET_PROTOSW_PERMANENT & p->flags) {
printk(KERN_ERR
"Attempt to unregister permanent protocol %d.\n",
pr_err("Attempt to unregister permanent protocol %d\n",
p->protocol);
} else {
spin_lock_bh(&inetsw_lock);
@@ -1149,8 +1149,8 @@ static int inet_sk_reselect_saddr(struct sock *sk)
return 0;
if (sysctl_ip_dynaddr > 1) {
printk(KERN_INFO "%s(): shifting inet->saddr from %pI4 to %pI4\n",
__func__, &old_saddr, &new_saddr);
pr_info("%s(): shifting inet->saddr from %pI4 to %pI4\n",
__func__, &old_saddr, &new_saddr);
}
inet->inet_saddr = inet->inet_rcv_saddr = new_saddr;
@@ -1679,14 +1679,14 @@ static int __init inet_init(void)
*/
if (inet_add_protocol(&icmp_protocol, IPPROTO_ICMP) < 0)
printk(KERN_CRIT "inet_init: Cannot add ICMP protocol\n");
pr_crit("%s: Cannot add ICMP protocol\n", __func__);
if (inet_add_protocol(&udp_protocol, IPPROTO_UDP) < 0)
printk(KERN_CRIT "inet_init: Cannot add UDP protocol\n");
pr_crit("%s: Cannot add UDP protocol\n", __func__);
if (inet_add_protocol(&tcp_protocol, IPPROTO_TCP) < 0)
printk(KERN_CRIT "inet_init: Cannot add TCP protocol\n");
pr_crit("%s: Cannot add TCP protocol\n", __func__);
#ifdef CONFIG_IP_MULTICAST
if (inet_add_protocol(&igmp_protocol, IPPROTO_IGMP) < 0)
printk(KERN_CRIT "inet_init: Cannot add IGMP protocol\n");
pr_crit("%s: Cannot add IGMP protocol\n", __func__);
#endif
/* Register the socket-side information for inet_create. */
@@ -1733,14 +1733,14 @@ static int __init inet_init(void)
*/
#if defined(CONFIG_IP_MROUTE)
if (ip_mr_init())
printk(KERN_CRIT "inet_init: Cannot init ipv4 mroute\n");
pr_crit("%s: Cannot init ipv4 mroute\n", __func__);
#endif
/*
* Initialise per-cpu ipv4 mibs
*/
if (init_ipv4_mibs())
printk(KERN_CRIT "inet_init: Cannot init ipv4 mibs\n");
pr_crit("%s: Cannot init ipv4 mibs\n", __func__);
ipv4_proc_init();

View File

@@ -1,3 +1,5 @@
#define pr_fmt(fmt) "IPsec: " fmt
#include <crypto/hash.h>
#include <linux/err.h>
#include <linux/module.h>
@@ -445,9 +447,10 @@ static int ah_init_state(struct xfrm_state *x)
if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
crypto_ahash_digestsize(ahash)) {
printk(KERN_INFO "AH: %s digestsize %u != %hu\n",
x->aalg->alg_name, crypto_ahash_digestsize(ahash),
aalg_desc->uinfo.auth.icv_fullbits/8);
pr_info("%s: %s digestsize %u != %hu\n",
__func__, x->aalg->alg_name,
crypto_ahash_digestsize(ahash),
aalg_desc->uinfo.auth.icv_fullbits / 8);
goto error;
}
@@ -510,11 +513,11 @@ static const struct net_protocol ah4_protocol = {
static int __init ah4_init(void)
{
if (xfrm_register_type(&ah_type, AF_INET) < 0) {
printk(KERN_INFO "ip ah init: can't add xfrm type\n");
pr_info("%s: can't add xfrm type\n", __func__);
return -EAGAIN;
}
if (inet_add_protocol(&ah4_protocol, IPPROTO_AH) < 0) {
printk(KERN_INFO "ip ah init: can't add protocol\n");
pr_info("%s: can't add protocol\n", __func__);
xfrm_unregister_type(&ah_type, AF_INET);
return -EAGAIN;
}
@@ -524,9 +527,9 @@ static int __init ah4_init(void)
static void __exit ah4_fini(void)
{
if (inet_del_protocol(&ah4_protocol, IPPROTO_AH) < 0)
printk(KERN_INFO "ip ah close: can't remove protocol\n");
pr_info("%s: can't remove protocol\n", __func__);
if (xfrm_unregister_type(&ah_type, AF_INET) < 0)
printk(KERN_INFO "ip ah close: can't remove xfrm type\n");
pr_info("%s: can't remove xfrm type\n", __func__);
}
module_init(ah4_init);

View File

@@ -889,7 +889,7 @@ static int arp_process(struct sk_buff *skb)
n = __neigh_lookup(&arp_tbl, &sip, dev, 0);
if (IPV4_DEVCONF_ALL(dev_net(dev), ARP_ACCEPT)) {
if (IN_DEV_ARP_ACCEPT(in_dev)) {
/* Unsolicited ARP is not accepted by default.
It is possible, that this option should be enabled for some
devices (strip is candidate)

View File

@@ -1,3 +1,5 @@
#define pr_fmt(fmt) "IPsec: " fmt
#include <crypto/aead.h>
#include <crypto/authenc.h>
#include <linux/err.h>
@@ -706,11 +708,11 @@ static const struct net_protocol esp4_protocol = {
static int __init esp4_init(void)
{
if (xfrm_register_type(&esp_type, AF_INET) < 0) {
printk(KERN_INFO "ip esp init: can't add xfrm type\n");
pr_info("%s: can't add xfrm type\n", __func__);
return -EAGAIN;
}
if (inet_add_protocol(&esp4_protocol, IPPROTO_ESP) < 0) {
printk(KERN_INFO "ip esp init: can't add protocol\n");
pr_info("%s: can't add protocol\n", __func__);
xfrm_unregister_type(&esp_type, AF_INET);
return -EAGAIN;
}
@@ -720,9 +722,9 @@ static int __init esp4_init(void)
static void __exit esp4_fini(void)
{
if (inet_del_protocol(&esp4_protocol, IPPROTO_ESP) < 0)
printk(KERN_INFO "ip esp close: can't remove protocol\n");
pr_info("%s: can't remove protocol\n", __func__);
if (xfrm_unregister_type(&esp_type, AF_INET) < 0)
printk(KERN_INFO "ip esp close: can't remove xfrm type\n");
pr_info("%s: can't remove xfrm type\n", __func__);
}
module_init(esp4_init);

View File

@@ -695,7 +695,7 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
if (ifa->ifa_flags & IFA_F_SECONDARY) {
prim = inet_ifa_byprefix(in_dev, prefix, mask);
if (prim == NULL) {
printk(KERN_WARNING "fib_add_ifaddr: bug: prim == NULL\n");
pr_warn("%s: bug: prim == NULL\n", __func__);
return;
}
}
@@ -749,11 +749,11 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)
if (ifa->ifa_flags & IFA_F_SECONDARY) {
prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask);
if (prim == NULL) {
printk(KERN_WARNING "fib_del_ifaddr: bug: prim == NULL\n");
pr_warn("%s: bug: prim == NULL\n", __func__);
return;
}
if (iprim && iprim != prim) {
printk(KERN_WARNING "fib_del_ifaddr: bug: iprim != prim\n");
pr_warn("%s: bug: iprim != prim\n", __func__);
return;
}
} else if (!ipv4_is_zeronet(any) &&

View File

@@ -154,7 +154,7 @@ static void free_fib_info_rcu(struct rcu_head *head)
void free_fib_info(struct fib_info *fi)
{
if (fi->fib_dead == 0) {
pr_warning("Freeing alive fib_info %p\n", fi);
pr_warn("Freeing alive fib_info %p\n", fi);
return;
}
change_nexthops(fi) {

View File

@@ -1170,9 +1170,8 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen)
}
if (tp && tp->pos + tp->bits > 32)
pr_warning("fib_trie"
" tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
tp, tp->pos, tp->bits, key, plen);
pr_warn("fib_trie tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
tp, tp->pos, tp->bits, key, plen);
/* Rebalance the trie */

View File

@@ -10,6 +10,8 @@
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
@@ -118,10 +120,10 @@ static const struct net_protocol net_gre_protocol = {
static int __init gre_init(void)
{
pr_info("GRE over IPv4 demultiplexor driver");
pr_info("GRE over IPv4 demultiplexor driver\n");
if (inet_add_protocol(&net_gre_protocol, IPPROTO_GRE) < 0) {
pr_err("gre: can't add protocol\n");
pr_err("can't add protocol\n");
return -EAGAIN;
}

View File

@@ -62,6 +62,8 @@
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/types.h>
#include <linux/jiffies.h>
@@ -670,7 +672,7 @@ static void icmp_unreach(struct sk_buff *skb)
break;
case ICMP_FRAG_NEEDED:
if (ipv4_config.no_pmtu_disc) {
LIMIT_NETDEBUG(KERN_INFO "ICMP: %pI4: fragmentation needed and DF set.\n",
LIMIT_NETDEBUG(KERN_INFO pr_fmt("%pI4: fragmentation needed and DF set\n"),
&iph->daddr);
} else {
info = ip_rt_frag_needed(net, iph,
@@ -681,7 +683,7 @@ static void icmp_unreach(struct sk_buff *skb)
}
break;
case ICMP_SR_FAILED:
LIMIT_NETDEBUG(KERN_INFO "ICMP: %pI4: Source Route Failed.\n",
LIMIT_NETDEBUG(KERN_INFO pr_fmt("%pI4: Source Route Failed\n"),
&iph->daddr);
break;
default:
@@ -713,13 +715,10 @@ static void icmp_unreach(struct sk_buff *skb)
if (!net->ipv4.sysctl_icmp_ignore_bogus_error_responses &&
inet_addr_type(net, iph->daddr) == RTN_BROADCAST) {
if (net_ratelimit())
printk(KERN_WARNING "%pI4 sent an invalid ICMP "
"type %u, code %u "
"error to a broadcast: %pI4 on %s\n",
&ip_hdr(skb)->saddr,
icmph->type, icmph->code,
&iph->daddr,
skb->dev->name);
pr_warn("%pI4 sent an invalid ICMP type %u, code %u error to a broadcast: %pI4 on %s\n",
&ip_hdr(skb)->saddr,
icmph->type, icmph->code,
&iph->daddr, skb->dev->name);
goto out;
}
@@ -946,8 +945,8 @@ static void icmp_address_reply(struct sk_buff *skb)
break;
}
if (!ifa && net_ratelimit()) {
printk(KERN_INFO "Wrong address mask %pI4 from %s/%pI4\n",
mp, dev->name, &ip_hdr(skb)->saddr);
pr_info("Wrong address mask %pI4 from %s/%pI4\n",
mp, dev->name, &ip_hdr(skb)->saddr);
}
}
}

View File

@@ -960,9 +960,12 @@ static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh)
inet_diag_bc_audit(nla_data(attr), nla_len(attr)))
return -EINVAL;
}
return netlink_dump_start(sock_diag_nlsk, skb, nlh,
inet_diag_dump_compat, NULL, 0);
{
struct netlink_dump_control c = {
.dump = inet_diag_dump_compat,
};
return netlink_dump_start(sock_diag_nlsk, skb, nlh, &c);
}
}
return inet_diag_get_exact_compat(skb, nlh);
@@ -985,9 +988,12 @@ static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
inet_diag_bc_audit(nla_data(attr), nla_len(attr)))
return -EINVAL;
}
return netlink_dump_start(sock_diag_nlsk, skb, h,
inet_diag_dump, NULL, 0);
{
struct netlink_dump_control c = {
.dump = inet_diag_dump,
};
return netlink_dump_start(sock_diag_nlsk, skb, h, &c);
}
}
return inet_diag_get_exact(skb, h, (struct inet_diag_req_v2 *)NLMSG_DATA(h));

View File

@@ -20,6 +20,8 @@
* Patrick McHardy : LRU queue of frag heads for evictor.
*/
#define pr_fmt(fmt) "IPv4: " fmt
#include <linux/compiler.h>
#include <linux/module.h>
#include <linux/types.h>
@@ -299,7 +301,7 @@ static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user)
return container_of(q, struct ipq, q);
out_nomem:
LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n");
LIMIT_NETDEBUG(KERN_ERR pr_fmt("ip_frag_create: no memory left !\n"));
return NULL;
}
@@ -637,14 +639,13 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
return 0;
out_nomem:
LIMIT_NETDEBUG(KERN_ERR "IP: queue_glue: no memory for gluing "
"queue %p\n", qp);
LIMIT_NETDEBUG(KERN_ERR pr_fmt("queue_glue: no memory for gluing queue %p\n"),
qp);
err = -ENOMEM;
goto out_fail;
out_oversize:
if (net_ratelimit())
printk(KERN_INFO "Oversized IP packet from %pI4.\n",
&qp->saddr);
pr_info("Oversized IP packet from %pI4\n", &qp->saddr);
out_fail:
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
return err;

View File

@@ -10,6 +10,8 @@
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/capability.h>
#include <linux/module.h>
#include <linux/types.h>
@@ -730,15 +732,16 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
if (skb->protocol == htons(ETH_P_IP)) {
rt = skb_rtable(skb);
if ((dst = rt->rt_gateway) == 0)
goto tx_error_icmp;
dst = rt->rt_gateway;
}
#if IS_ENABLED(CONFIG_IPV6)
else if (skb->protocol == htons(ETH_P_IPV6)) {
struct neighbour *neigh = dst_get_neighbour_noref(skb_dst(skb));
const struct in6_addr *addr6;
struct neighbour *neigh;
bool do_tx_error_icmp;
int addr_type;
neigh = dst_neigh_lookup(skb_dst(skb), &ipv6_hdr(skb)->daddr);
if (neigh == NULL)
goto tx_error;
@@ -751,9 +754,14 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
}
if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
do_tx_error_icmp = true;
else {
do_tx_error_icmp = false;
dst = addr6->s6_addr32[3];
}
neigh_release(neigh);
if (do_tx_error_icmp)
goto tx_error_icmp;
dst = addr6->s6_addr32[3];
}
#endif
else
@@ -914,9 +922,10 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
__IPTUNNEL_XMIT(tstats, &dev->stats);
return NETDEV_TX_OK;
#if IS_ENABLED(CONFIG_IPV6)
tx_error_icmp:
dst_link_failure(skb);
#endif
tx_error:
dev->stats.tx_errors++;
dev_kfree_skb(skb);
@@ -1529,7 +1538,7 @@ static int ipgre_newlink(struct net *src_net, struct net_device *dev, struct nla
return -EEXIST;
if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
random_ether_addr(dev->dev_addr);
eth_hw_addr_random(dev);
mtu = ipgre_tunnel_bind_dev(dev);
if (!tb[IFLA_MTU])
@@ -1709,7 +1718,7 @@ static int __init ipgre_init(void)
{
int err;
printk(KERN_INFO "GRE over IPv4 tunneling driver\n");
pr_info("GRE over IPv4 tunneling driver\n");
err = register_pernet_device(&ipgre_net_ops);
if (err < 0)
@@ -1717,7 +1726,7 @@ static int __init ipgre_init(void)
err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
if (err < 0) {
printk(KERN_INFO "ipgre init: can't add protocol\n");
pr_info("%s: can't add protocol\n", __func__);
goto add_proto_failed;
}
@@ -1746,7 +1755,7 @@ static void __exit ipgre_fini(void)
rtnl_link_unregister(&ipgre_tap_ops);
rtnl_link_unregister(&ipgre_link_ops);
if (gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO) < 0)
printk(KERN_INFO "ipgre close: can't remove protocol\n");
pr_info("%s: can't remove protocol\n", __func__);
unregister_pernet_device(&ipgre_net_ops);
}

View File

@@ -113,6 +113,8 @@
* 2 of the License, or (at your option) any later version.
*/
#define pr_fmt(fmt) "IPv4: " fmt
#include <asm/system.h>
#include <linux/module.h>
#include <linux/types.h>
@@ -148,7 +150,7 @@
/*
* Process Router Attention IP option (RFC 2113)
*/
int ip_call_ra_chain(struct sk_buff *skb)
bool ip_call_ra_chain(struct sk_buff *skb)
{
struct ip_ra_chain *ra;
u8 protocol = ip_hdr(skb)->protocol;
@@ -167,7 +169,7 @@ int ip_call_ra_chain(struct sk_buff *skb)
net_eq(sock_net(sk), dev_net(dev))) {
if (ip_is_fragment(ip_hdr(skb))) {
if (ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN))
return 1;
return true;
}
if (last) {
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
@@ -180,9 +182,9 @@ int ip_call_ra_chain(struct sk_buff *skb)
if (last) {
raw_rcv(last, skb);
return 1;
return true;
}
return 0;
return false;
}
static int ip_local_deliver_finish(struct sk_buff *skb)
@@ -265,7 +267,7 @@ int ip_local_deliver(struct sk_buff *skb)
ip_local_deliver_finish);
}
static inline int ip_rcv_options(struct sk_buff *skb)
static inline bool ip_rcv_options(struct sk_buff *skb)
{
struct ip_options *opt;
const struct iphdr *iph;
@@ -299,8 +301,8 @@ static inline int ip_rcv_options(struct sk_buff *skb)
if (!IN_DEV_SOURCE_ROUTE(in_dev)) {
if (IN_DEV_LOG_MARTIANS(in_dev) &&
net_ratelimit())
printk(KERN_INFO "source route option %pI4 -> %pI4\n",
&iph->saddr, &iph->daddr);
pr_info("source route option %pI4 -> %pI4\n",
&iph->saddr, &iph->daddr);
goto drop;
}
}
@@ -309,9 +311,9 @@ static inline int ip_rcv_options(struct sk_buff *skb)
goto drop;
}
return 0;
return false;
drop:
return -1;
return true;
}
static int ip_rcv_finish(struct sk_buff *skb)

View File

@@ -9,6 +9,8 @@
*
*/
#define pr_fmt(fmt) "IPv4: " fmt
#include <linux/capability.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -577,7 +579,7 @@ void ip_forward_options(struct sk_buff *skb)
ip_rt_get_source(&optptr[srrptr-1], skb, rt);
optptr[2] = srrptr+4;
} else if (net_ratelimit())
printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
pr_crit("%s(): Argh! Destination lost!\n", __func__);
if (opt->ts_needaddr) {
optptr = raw + opt->ts;
ip_rt_get_source(&optptr[optptr[2]-9], skb, rt);

View File

@@ -464,6 +464,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
(1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
(1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
(1<<IP_MINTTL) | (1<<IP_NODEFRAG))) ||
optname == IP_UNICAST_IF ||
optname == IP_MULTICAST_TTL ||
optname == IP_MULTICAST_ALL ||
optname == IP_MULTICAST_LOOP ||
@@ -623,6 +624,35 @@ static int do_ip_setsockopt(struct sock *sk, int level,
goto e_inval;
inet->mc_loop = !!val;
break;
case IP_UNICAST_IF:
{
struct net_device *dev = NULL;
int ifindex;
if (optlen != sizeof(int))
goto e_inval;
ifindex = (__force int)ntohl((__force __be32)val);
if (ifindex == 0) {
inet->uc_index = 0;
err = 0;
break;
}
dev = dev_get_by_index(sock_net(sk), ifindex);
err = -EADDRNOTAVAIL;
if (!dev)
break;
dev_put(dev);
err = -EINVAL;
if (sk->sk_bound_dev_if)
break;
inet->uc_index = ifindex;
err = 0;
break;
}
case IP_MULTICAST_IF:
{
struct ip_mreqn mreq;
@@ -1173,6 +1203,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
case IP_MULTICAST_LOOP:
val = inet->mc_loop;
break;
case IP_UNICAST_IF:
val = (__force int)htonl((__u32) inet->uc_index);
break;
case IP_MULTICAST_IF:
{
struct in_addr addr;
@@ -1251,6 +1284,10 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
int hlim = inet->mc_ttl;
put_cmsg(&msg, SOL_IP, IP_TTL, sizeof(hlim), &hlim);
}
if (inet->cmsg_flags & IP_CMSG_TOS) {
int tos = inet->rcv_tos;
put_cmsg(&msg, SOL_IP, IP_TOS, sizeof(tos), &tos);
}
len -= msg.msg_controllen;
return put_user(len, optlen);
}

Some files were not shown because too many files have changed in this diff Show More