[2/8] batman-adv: gateways silently drop DHCP requests
Commit Message
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
batman-adv/gateway_client.c | 31 +++++++++++++++++--------------
batman-adv/gateway_client.h | 2 +-
batman-adv/soft-interface.c | 16 ++++++++++------
3 files changed, 28 insertions(+), 21 deletions(-)
@@ -399,54 +399,57 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset)
return 0;
}
-bool gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
+int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
{
struct ethhdr *ethhdr;
struct iphdr *iphdr;
struct udphdr *udphdr;
unsigned int header_len = 0;
- if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT)
- return false;
-
- if (!bat_priv->curr_gw)
- return false;
+ if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF)
+ return 0;
/* check for ethernet header */
if (!pskb_may_pull(skb, header_len + ETH_HLEN))
- return false;
+ return 0;
ethhdr = (struct ethhdr *)skb->data;
header_len += ETH_HLEN;
/* check for initial vlan header */
if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
if (!pskb_may_pull(skb, header_len + VLAN_HLEN))
- return false;
+ return 0;
ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
header_len += VLAN_HLEN;
}
/* check for ip header */
if (ntohs(ethhdr->h_proto) != ETH_P_IP)
- return false;
+ return 0;
if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr)))
- return false;
+ return 0;
iphdr = (struct iphdr *)(skb->data + header_len);
header_len += iphdr->ihl * 4;
/* check for udp header */
if (iphdr->protocol != IPPROTO_UDP)
- return false;
+ return 0;
if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr)))
- return false;
+ return 0;
udphdr = (struct udphdr *)(skb->data + header_len);
header_len += sizeof(struct udphdr);
/* check for bootp port */
if (ntohs(udphdr->dest) != 67)
- return false;
+ return 0;
+
+ if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)
+ return -1;
+
+ if (!bat_priv->curr_gw)
+ return 0;
- return true;
+ return 1;
}
@@ -31,6 +31,6 @@ void gw_node_update(struct bat_priv *bat_priv,
void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node);
void gw_node_purge(struct bat_priv *bat_priv);
int gw_client_seq_print_text(struct seq_file *seq, void *offset);
-bool gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb);
+int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb);
#endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */
@@ -347,7 +347,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
struct vlan_ethhdr *vhdr;
int data_len = skb->len, ret;
short vid = -1;
- bool bcast_dst = false, do_bcast = true;
+ bool do_bcast = false;
if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
goto dropped;
@@ -378,14 +378,18 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
/* TODO: check this for locks */
hna_local_add(soft_iface, ethhdr->h_source);
- if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest))
- bcast_dst = true;
+ if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) {
+ ret = gw_is_target(bat_priv, skb);
- if ((bcast_dst) && gw_is_target(bat_priv, skb))
- do_bcast = false;
+ if (ret < 0)
+ goto dropped;
+
+ if (ret == 0)
+ do_bcast = true;
+ }
/* ethernet packet should be broadcasted */
- if (bcast_dst && do_bcast) {
+ if (do_bcast) {
if (!bat_priv->primary_if)
goto dropped;