On Friday, February 10, 2012 07:41:42 Antonio Quartulli wrote:
> In order to enable an higher verbosity level of the DAT debug messages, the
> unicast_4addr_packet is now used to carry ARP packets generated by the DAT
> internal mechanism. This packet type will enable batman-adv to recognise
> each DAT related message and to print its source (this will help to track
> possibly bogus ARP entries)
>
> Signed-off-by: Antonio Quartulli <ordex@autistici.org>
> ---
> distributed-arp-table.c | 129
> +++++++++++++++++++++++++++++++--------------- distributed-arp-table.h |
> 16 +++---
> soft-interface.c | 15 +++--
> 3 files changed, 105 insertions(+), 55 deletions(-)
>
> diff --git a/distributed-arp-table.c b/distributed-arp-table.c
> index 48e97e0..239b5c4 100644
> --- a/distributed-arp-table.c
> +++ b/distributed-arp-table.c
> @@ -31,6 +31,7 @@
> #include "originator.h"
> #include "send.h"
> #include "soft-interface.h"
> +#include "translation-table.h"
> #include "types.h"
> #include "translation-table.h"
> #include "unicast.h"
> @@ -38,10 +39,44 @@
> #ifdef CONFIG_BATMAN_ADV_DEBUG
>
> static inline void bat_dbg_arp(struct bat_priv *bat_priv,
> - struct sk_buff *skb, uint16_t type) {
> + struct sk_buff *skb, uint16_t type,
> + int hdr_size) {
> + struct unicast_4addr_packet *unicast_4addr_packet;
> +
> bat_dbg(DBG_ARP, bat_priv, "ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]\n",
> - ARP_HW_SRC(skb), &ARP_IP_SRC(skb), ARP_HW_DST(skb),
> - &ARP_IP_DST(skb));
> + ARP_HW_SRC(skb, hdr_size), &ARP_IP_SRC(skb, hdr_size),
> + ARP_HW_DST(skb, hdr_size), &ARP_IP_DST(skb, hdr_size));
> +
> + if (hdr_size == 0)
> + return;
> +
> + /* if the AP packet is encapsulated in a batman packet, let's print some
> + * debug messages */
> + unicast_4addr_packet = (struct unicast_4addr_packet *)skb->data;
> +
> + switch (unicast_4addr_packet->u.header.packet_type) {
> + case BAT_UNICAST:
> + bat_dbg(DBG_ARP, bat_priv, "encapsulated within a UNICAST "
> + "packet\n");
> + break;
> + case BAT_UNICAST_4ADDR:
> + bat_dbg(DBG_ARP, bat_priv, "encapsulated within a "
> + "UNICAST_4ADDR packet (src: %pM)\n",
> + unicast_4addr_packet->src);
> + if (unicast_4addr_packet->subtype != BAT_P_DHT_PUT ||
> + unicast_4addr_packet->subtype != BAT_P_DHT_GET)
> + bat_dbg(DBG_ARP, bat_priv, "It's a DAT message\n");
Isn't this check going to fail as soon as a new subtype was added ?
> + unicast_4addr_packet = (struct unicast_4addr_packet *)skb->data;
> +
> + if (dat_snoop_incoming_arp_request(bat_priv, skb, hdr_size))
> + goto out;
> +
> + if (dat_snoop_incoming_arp_reply(bat_priv, skb, hdr_size))
> + goto out;
> +
The unicast_4addr_packet variable isn't used anywhere ...
Most of this patch simply adds a hdr_size variable to the functions added by
earlier patches. Why not adding the unicast_4addr type at the beginning of the
patch series ? You would not need this patch.
Cheers,
Marek
On Sat, Feb 11, 2012 at 09:44:23PM +0800, Marek Lindner wrote:
> On Friday, February 10, 2012 07:41:42 Antonio Quartulli wrote:
> > In order to enable an higher verbosity level of the DAT debug messages, the
> > unicast_4addr_packet is now used to carry ARP packets generated by the DAT
> > internal mechanism. This packet type will enable batman-adv to recognise
> > each DAT related message and to print its source (this will help to track
> > possibly bogus ARP entries)
> >
> > Signed-off-by: Antonio Quartulli <ordex@autistici.org>
> > ---
> > distributed-arp-table.c | 129
> > +++++++++++++++++++++++++++++++--------------- distributed-arp-table.h |
> > 16 +++---
> > soft-interface.c | 15 +++--
> > 3 files changed, 105 insertions(+), 55 deletions(-)
> >
> > diff --git a/distributed-arp-table.c b/distributed-arp-table.c
> > index 48e97e0..239b5c4 100644
> > --- a/distributed-arp-table.c
> > +++ b/distributed-arp-table.c
> > @@ -31,6 +31,7 @@
> > #include "originator.h"
> > #include "send.h"
> > #include "soft-interface.h"
> > +#include "translation-table.h"
> > #include "types.h"
> > #include "translation-table.h"
> > #include "unicast.h"
> > @@ -38,10 +39,44 @@
> > #ifdef CONFIG_BATMAN_ADV_DEBUG
> >
> > static inline void bat_dbg_arp(struct bat_priv *bat_priv,
> > - struct sk_buff *skb, uint16_t type) {
> > + struct sk_buff *skb, uint16_t type,
> > + int hdr_size) {
> > + struct unicast_4addr_packet *unicast_4addr_packet;
> > +
> > bat_dbg(DBG_ARP, bat_priv, "ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]\n",
> > - ARP_HW_SRC(skb), &ARP_IP_SRC(skb), ARP_HW_DST(skb),
> > - &ARP_IP_DST(skb));
> > + ARP_HW_SRC(skb, hdr_size), &ARP_IP_SRC(skb, hdr_size),
> > + ARP_HW_DST(skb, hdr_size), &ARP_IP_DST(skb, hdr_size));
> > +
> > + if (hdr_size == 0)
> > + return;
> > +
> > + /* if the AP packet is encapsulated in a batman packet, let's print some
> > + * debug messages */
> > + unicast_4addr_packet = (struct unicast_4addr_packet *)skb->data;
> > +
> > + switch (unicast_4addr_packet->u.header.packet_type) {
> > + case BAT_UNICAST:
> > + bat_dbg(DBG_ARP, bat_priv, "encapsulated within a UNICAST "
> > + "packet\n");
> > + break;
> > + case BAT_UNICAST_4ADDR:
> > + bat_dbg(DBG_ARP, bat_priv, "encapsulated within a "
> > + "UNICAST_4ADDR packet (src: %pM)\n",
> > + unicast_4addr_packet->src);
> > + if (unicast_4addr_packet->subtype != BAT_P_DHT_PUT ||
> > + unicast_4addr_packet->subtype != BAT_P_DHT_GET)
> > + bat_dbg(DBG_ARP, bat_priv, "It's a DAT message\n");
>
> Isn't this check going to fail as soon as a new subtype was added ?
>
>
> > + unicast_4addr_packet = (struct unicast_4addr_packet *)skb->data;
> > +
> > + if (dat_snoop_incoming_arp_request(bat_priv, skb, hdr_size))
> > + goto out;
> > +
> > + if (dat_snoop_incoming_arp_reply(bat_priv, skb, hdr_size))
> > + goto out;
> > +
>
> The unicast_4addr_packet variable isn't used anywhere ...
>
> Most of this patch simply adds a hdr_size variable to the functions added by
> earlier patches. Why not adding the unicast_4addr type at the beginning of the
> patch series ? You would not need this patch.
Thank you for your feedback.
Yes, you are right. Actually I didn't care about the "weight" of th patch: I
simply added the new type at the end and then applied the needed changes. But I
agree with you: moving the new type patch at the beginning is a good idea.
Cheers,
>
> Cheers,
> Marek
@@ -31,6 +31,7 @@
#include "originator.h"
#include "send.h"
#include "soft-interface.h"
+#include "translation-table.h"
#include "types.h"
#include "translation-table.h"
#include "unicast.h"
@@ -38,10 +39,44 @@
#ifdef CONFIG_BATMAN_ADV_DEBUG
static inline void bat_dbg_arp(struct bat_priv *bat_priv,
- struct sk_buff *skb, uint16_t type) {
+ struct sk_buff *skb, uint16_t type,
+ int hdr_size) {
+ struct unicast_4addr_packet *unicast_4addr_packet;
+
bat_dbg(DBG_ARP, bat_priv, "ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]\n",
- ARP_HW_SRC(skb), &ARP_IP_SRC(skb), ARP_HW_DST(skb),
- &ARP_IP_DST(skb));
+ ARP_HW_SRC(skb, hdr_size), &ARP_IP_SRC(skb, hdr_size),
+ ARP_HW_DST(skb, hdr_size), &ARP_IP_DST(skb, hdr_size));
+
+ if (hdr_size == 0)
+ return;
+
+ /* if the AP packet is encapsulated in a batman packet, let's print some
+ * debug messages */
+ unicast_4addr_packet = (struct unicast_4addr_packet *)skb->data;
+
+ switch (unicast_4addr_packet->u.header.packet_type) {
+ case BAT_UNICAST:
+ bat_dbg(DBG_ARP, bat_priv, "encapsulated within a UNICAST "
+ "packet\n");
+ break;
+ case BAT_UNICAST_4ADDR:
+ bat_dbg(DBG_ARP, bat_priv, "encapsulated within a "
+ "UNICAST_4ADDR packet (src: %pM)\n",
+ unicast_4addr_packet->src);
+ if (unicast_4addr_packet->subtype != BAT_P_DHT_PUT ||
+ unicast_4addr_packet->subtype != BAT_P_DHT_GET)
+ bat_dbg(DBG_ARP, bat_priv, "It's a DAT message\n");
+ break;
+ case BAT_BCAST:
+ bat_dbg(DBG_ARP, bat_priv, "encapsulated within a BCAST packet "
+ "(src: %pM)\n",
+ ((struct bcast_packet *)unicast_4addr_packet)->orig);
+ break;
+ default:
+ bat_dbg(DBG_ARP, bat_priv, "encapsulated within an unknown "
+ "packet type (0x%x)\n",
+ unicast_4addr_packet->u.header.packet_type);
+ }
}
#else
@@ -184,7 +219,8 @@ static bool dht_send_data(struct bat_priv *bat_priv, struct sk_buff *skb,
goto free_orig;
tmp_skb = pskb_copy(skb, GFP_ATOMIC);
- if (prepare_unicast_packet(tmp_skb, cand[i].orig_node))
+ if (prepare_unicast_4addr_packet(bat_priv, tmp_skb,
+ cand[i].orig_node))
send_skb_packet(tmp_skb, neigh_node->if_incoming,
neigh_node->addr);
else
@@ -228,24 +264,28 @@ out:
/* Returns arphdr->ar_op if the skb contains a valid ARP packet, otherwise
* returns 0 */
-static uint16_t arp_get_type(struct bat_priv *bat_priv, struct sk_buff *skb)
+static uint16_t arp_get_type(struct bat_priv *bat_priv, struct sk_buff *skb,
+ int hdr_size)
{
struct arphdr *arphdr;
struct ethhdr *ethhdr;
uint16_t type = 0;
- if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
+ /* pull the ethernet header */
+ if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN)))
goto out;
- ethhdr = (struct ethhdr *)skb_mac_header(skb);
+ ethhdr = (struct ethhdr *)(skb->data + hdr_size);
if (ethhdr->h_proto != htons(ETH_P_ARP))
goto out;
- if (unlikely(!pskb_may_pull(skb, ETH_HLEN + arp_hdr_len(skb->dev))))
+ /* pull the ARP payload */
+ if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN +
+ arp_hdr_len(skb->dev))))
goto out;
- arphdr = (struct arphdr *)(skb->data + sizeof(struct ethhdr));
+ arphdr = (struct arphdr *)(skb->data + hdr_size + ETH_HLEN);
/* Check whether the ARP packet carries a valid
* IP information */
@@ -263,10 +303,10 @@ static uint16_t arp_get_type(struct bat_priv *bat_priv, struct sk_buff *skb)
/* Check for bad reply/request. If the ARP message is not sane, DAT
* will simply ignore it */
- if (ipv4_is_loopback(ARP_IP_SRC(skb)) ||
- ipv4_is_multicast(ARP_IP_SRC(skb)) ||
- ipv4_is_loopback(ARP_IP_DST(skb)) ||
- ipv4_is_multicast(ARP_IP_DST(skb)))
+ if (ipv4_is_loopback(ARP_IP_SRC(skb, hdr_size)) ||
+ ipv4_is_multicast(ARP_IP_SRC(skb, hdr_size)) ||
+ ipv4_is_loopback(ARP_IP_DST(skb, hdr_size)) ||
+ ipv4_is_multicast(ARP_IP_DST(skb, hdr_size)))
goto out;
type = ntohs(arphdr->ar_op);
@@ -288,18 +328,18 @@ bool dat_snoop_outgoing_arp_request(struct bat_priv *bat_priv,
struct hard_iface *primary_if = NULL;
struct sk_buff *skb_new;
- type = arp_get_type(bat_priv, skb);
+ type = arp_get_type(bat_priv, skb, 0);
/* If we get an ARP_REQUEST we have to send the unicast message to the
* selected DHT candidates */
if (type != ARPOP_REQUEST)
goto out;
bat_dbg(DBG_ARP, bat_priv, "Parsing outgoing ARP REQUEST\n");
- bat_dbg_arp(bat_priv, skb, type);
+ bat_dbg_arp(bat_priv, skb, type, 0);
- ip_src = ARP_IP_SRC(skb);
- hw_src = ARP_HW_SRC(skb);
- ip_dst = ARP_IP_DST(skb);
+ ip_src = ARP_IP_SRC(skb, 0);
+ hw_src = ARP_HW_SRC(skb, 0);
+ ip_dst = ARP_IP_DST(skb, 0);
primary_if = primary_if_get_selected(bat_priv);
if (!primary_if)
@@ -341,7 +381,7 @@ out:
* into the local table. If found, an ARP reply is sent immediately, otherwise
* the caller has to deliver the ARP request to the upper layer */
bool dat_snoop_incoming_arp_request(struct bat_priv *bat_priv,
- struct sk_buff *skb)
+ struct sk_buff *skb, int hdr_size)
{
uint16_t type;
uint32_t ip_src, ip_dst;
@@ -351,16 +391,16 @@ bool dat_snoop_incoming_arp_request(struct bat_priv *bat_priv,
struct neighbour *n = NULL;
bool ret = false;
- type = arp_get_type(bat_priv, skb);
+ type = arp_get_type(bat_priv, skb, hdr_size);
if (type != ARPOP_REQUEST)
goto out;
- hw_src = ARP_HW_SRC(skb);
- ip_src = ARP_IP_SRC(skb);
- ip_dst = ARP_IP_DST(skb);
+ hw_src = ARP_HW_SRC(skb, hdr_size);
+ ip_src = ARP_IP_SRC(skb, hdr_size);
+ ip_dst = ARP_IP_DST(skb, hdr_size);
bat_dbg(DBG_ARP, bat_priv, "Parsing incoming ARP REQUEST\n");
- bat_dbg_arp(bat_priv, skb, type);
+ bat_dbg_arp(bat_priv, skb, type, hdr_size);
primary_if = primary_if_get_selected(bat_priv);
if (!primary_if)
@@ -380,7 +420,7 @@ bool dat_snoop_incoming_arp_request(struct bat_priv *bat_priv,
if (!skb_new)
goto out;
- unicast_send_skb(skb_new, bat_priv);
+ unicast_4addr_send_skb(skb_new, bat_priv);
ret = true;
out:
@@ -404,17 +444,17 @@ bool dat_snoop_outgoing_arp_reply(struct bat_priv *bat_priv,
uint8_t *hw_src, *hw_dst;
bool ret = false;
- type = arp_get_type(bat_priv, skb);
+ type = arp_get_type(bat_priv, skb, 0);
if (type != ARPOP_REPLY)
goto out;
bat_dbg(DBG_ARP, bat_priv, "Parsing outgoing ARP REPLY\n");
- bat_dbg_arp(bat_priv, skb, type);
+ bat_dbg_arp(bat_priv, skb, type, 0);
- hw_src = ARP_HW_SRC(skb);
- ip_src = ARP_IP_SRC(skb);
- hw_dst = ARP_HW_DST(skb);
- ip_dst = ARP_IP_DST(skb);
+ hw_src = ARP_HW_SRC(skb, 0);
+ ip_src = ARP_IP_SRC(skb, 0);
+ hw_dst = ARP_HW_DST(skb, 0);
+ ip_dst = ARP_IP_DST(skb, 0);
arp_neigh_update(bat_priv, ip_src, hw_src);
arp_neigh_update(bat_priv, ip_dst, hw_dst);
@@ -431,24 +471,24 @@ out:
/* This function has to be invoked on an ARP reply coming into the soft
* interface from the mesh network. The local table has to be updated */
bool dat_snoop_incoming_arp_reply(struct bat_priv *bat_priv,
- struct sk_buff *skb)
+ struct sk_buff *skb, int hdr_size)
{
uint16_t type;
uint32_t ip_src, ip_dst;
uint8_t *hw_src, *hw_dst;
bool ret = false;
- type = arp_get_type(bat_priv, skb);
+ type = arp_get_type(bat_priv, skb, hdr_size);
if (type != ARPOP_REPLY)
goto out;
bat_dbg(DBG_ARP, bat_priv, "Parsing incoming ARP REPLY\n");
- bat_dbg_arp(bat_priv, skb, type);
+ bat_dbg_arp(bat_priv, skb, type, hdr_size);
- hw_src = ARP_HW_SRC(skb);
- ip_src = ARP_IP_SRC(skb);
- hw_dst = ARP_HW_DST(skb);
- ip_dst = ARP_IP_DST(skb);
+ hw_src = ARP_HW_SRC(skb, hdr_size);
+ ip_src = ARP_IP_SRC(skb, hdr_size);
+ hw_dst = ARP_HW_DST(skb, hdr_size);
+ ip_dst = ARP_IP_DST(skb, hdr_size);
/* Update our internal cache with both the IP addresses we fetched from
* the ARP reply */
@@ -471,20 +511,25 @@ bool arp_drop_broadcast_packet(struct bat_priv *bat_priv,
/* If this packet is an ARP_REQUEST and we already have the information
* that it is going to ask, we can drop the packet */
if (!forw_packet->num_packets &&
- (arp_get_type(bat_priv, forw_packet->skb) ==
+ (arp_get_type(bat_priv, forw_packet->skb,
+ sizeof(struct bcast_packet)) ==
ARPOP_REQUEST)) {
- n = neigh_lookup(&arp_tbl, &ARP_IP_DST(forw_packet->skb),
+ n = neigh_lookup(&arp_tbl,
+ &ARP_IP_DST(forw_packet->skb,
+ sizeof(struct bcast_packet)),
forw_packet->if_incoming->soft_iface);
/* check if we already know this neigh */
if (n && (n->nud_state & NUD_CONNECTED)) {
bat_dbg(DBG_ARP, bat_priv, "ARP Request for %pI4: "
"fallback prevented\n",
- &ARP_IP_DST(forw_packet->skb));
+ &ARP_IP_DST(forw_packet->skb,
+ sizeof(struct bcast_packet)));
return true;
}
bat_dbg(DBG_ARP, bat_priv, "ARP Request for %pI4: fallback\n",
- &ARP_IP_DST(forw_packet->skb));
+ &ARP_IP_DST(forw_packet->skb,
+ sizeof(struct bcast_packet)));
}
return false;
}
@@ -41,20 +41,22 @@ struct forw_packet;
#define dat_addr_t uint16_t
#define DAT_ADDR_MAX biggest_unsigned_int(dat_addr_t)
-#define ARP_HW_SRC(skb) ((uint8_t *)(skb->data) + sizeof(struct ethhdr) + \
- sizeof(struct arphdr))
-#define ARP_IP_SRC(skb) (*(uint32_t *)(ARP_HW_SRC(skb) + ETH_ALEN))
-#define ARP_HW_DST(skb) (ARP_HW_SRC(skb) + ETH_ALEN + 4)
-#define ARP_IP_DST(skb) (*(uint32_t *)(ARP_HW_SRC(skb) + ETH_ALEN * 2 + 4))
+#define ARP_HW_SRC(skb, hdr_size) ((uint8_t *)(skb->data + hdr_size) + \
+ sizeof(struct ethhdr) + sizeof(struct arphdr))
+#define ARP_IP_SRC(skb, hdr_size) (*(uint32_t *)(ARP_HW_SRC(skb, hdr_size) + \
+ ETH_ALEN))
+#define ARP_HW_DST(skb, hdr_size) (ARP_HW_SRC(skb, hdr_size) + ETH_ALEN + 4)
+#define ARP_IP_DST(skb, hdr_size) (*(uint32_t *)(ARP_HW_SRC(skb, hdr_size) + \
+ ETH_ALEN * 2 + 4))
bool dat_snoop_outgoing_arp_request(struct bat_priv *bat_priv,
struct sk_buff *skb);
bool dat_snoop_incoming_arp_request(struct bat_priv *bat_priv,
- struct sk_buff *skb);
+ struct sk_buff *skb, int hdr_size);
bool dat_snoop_outgoing_arp_reply(struct bat_priv *bat_priv,
struct sk_buff *skb);
bool dat_snoop_incoming_arp_reply(struct bat_priv *bat_priv,
- struct sk_buff *skb);
+ struct sk_buff *skb, int hdr_size);
bool arp_drop_broadcast_packet(struct bat_priv *bat_priv,
struct forw_packet *forw_packet);
void arp_change_timeout(struct net_device *soft_iface, const char *name);
@@ -258,6 +258,7 @@ void interface_rx(struct net_device *soft_iface,
int hdr_size)
{
struct bat_priv *bat_priv = netdev_priv(soft_iface);
+ struct unicast_4addr_packet *unicast_4addr_packet;
struct ethhdr *ethhdr;
struct vlan_ethhdr *vhdr;
short vid = -1;
@@ -266,6 +267,14 @@ void interface_rx(struct net_device *soft_iface,
if (!pskb_may_pull(skb, hdr_size))
goto dropped;
+ unicast_4addr_packet = (struct unicast_4addr_packet *)skb->data;
+
+ if (dat_snoop_incoming_arp_request(bat_priv, skb, hdr_size))
+ goto out;
+
+ if (dat_snoop_incoming_arp_reply(bat_priv, skb, hdr_size))
+ goto out;
+
skb_pull_rcsum(skb, hdr_size);
skb_reset_mac_header(skb);
@@ -284,12 +293,6 @@ void interface_rx(struct net_device *soft_iface,
goto dropped;
}
- if (dat_snoop_incoming_arp_request(bat_priv, skb))
- goto out;
-
- if (dat_snoop_incoming_arp_reply(bat_priv, skb))
- goto out;
-
/* skb->dev & skb->pkt_type are set here */
if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
goto dropped;