|
@@ -20,6 +20,7 @@
|
|
|
|
|
|
#include <linux/atomic.h>
|
|
#include <linux/atomic.h>
|
|
#include <linux/byteorder/generic.h>
|
|
#include <linux/byteorder/generic.h>
|
|
|
|
+#include <linux/errno.h>
|
|
#include <linux/etherdevice.h>
|
|
#include <linux/etherdevice.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/if.h>
|
|
#include <linux/if.h>
|
|
@@ -72,6 +73,7 @@ int batadv_send_skb_packet(struct sk_buff *skb,
|
|
{
|
|
{
|
|
struct batadv_priv *bat_priv;
|
|
struct batadv_priv *bat_priv;
|
|
struct ethhdr *ethhdr;
|
|
struct ethhdr *ethhdr;
|
|
|
|
+ int ret;
|
|
|
|
|
|
bat_priv = netdev_priv(hard_iface->soft_iface);
|
|
bat_priv = netdev_priv(hard_iface->soft_iface);
|
|
|
|
|
|
@@ -109,8 +111,15 @@ int batadv_send_skb_packet(struct sk_buff *skb,
|
|
/* dev_queue_xmit() returns a negative result on error. However on
|
|
/* dev_queue_xmit() returns a negative result on error. However on
|
|
* congestion and traffic shaping, it drops and returns NET_XMIT_DROP
|
|
* congestion and traffic shaping, it drops and returns NET_XMIT_DROP
|
|
* (which is > 0). This will not be treated as an error.
|
|
* (which is > 0). This will not be treated as an error.
|
|
|
|
+ *
|
|
|
|
+ * a negative value cannot be returned because it could be interepreted
|
|
|
|
+ * as not consumed skb by callers of batadv_send_skb_to_orig.
|
|
*/
|
|
*/
|
|
- return dev_queue_xmit(skb);
|
|
|
|
|
|
+ ret = dev_queue_xmit(skb);
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ ret = NET_XMIT_DROP;
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
send_skb_err:
|
|
send_skb_err:
|
|
kfree_skb(skb);
|
|
kfree_skb(skb);
|
|
return NET_XMIT_DROP;
|
|
return NET_XMIT_DROP;
|
|
@@ -156,8 +165,11 @@ int batadv_send_unicast_skb(struct sk_buff *skb,
|
|
* host, NULL can be passed as recv_if and no interface alternating is
|
|
* host, NULL can be passed as recv_if and no interface alternating is
|
|
* attempted.
|
|
* attempted.
|
|
*
|
|
*
|
|
- * Return: NET_XMIT_SUCCESS on success, NET_XMIT_DROP on failure, or
|
|
|
|
- * -EINPROGRESS if the skb is buffered for later transmit.
|
|
|
|
|
|
+ * Return: -1 on failure (and the skb is not consumed), -EINPROGRESS if the
|
|
|
|
+ * skb is buffered for later transmit or the NET_XMIT status returned by the
|
|
|
|
+ * lower routine if the packet has been passed down.
|
|
|
|
+ *
|
|
|
|
+ * If the returning value is not -1 the skb has been consumed.
|
|
*/
|
|
*/
|
|
int batadv_send_skb_to_orig(struct sk_buff *skb,
|
|
int batadv_send_skb_to_orig(struct sk_buff *skb,
|
|
struct batadv_orig_node *orig_node,
|
|
struct batadv_orig_node *orig_node,
|
|
@@ -165,7 +177,7 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
|
|
{
|
|
{
|
|
struct batadv_priv *bat_priv = orig_node->bat_priv;
|
|
struct batadv_priv *bat_priv = orig_node->bat_priv;
|
|
struct batadv_neigh_node *neigh_node;
|
|
struct batadv_neigh_node *neigh_node;
|
|
- int ret = NET_XMIT_DROP;
|
|
|
|
|
|
+ int ret = -1;
|
|
|
|
|
|
/* batadv_find_router() increases neigh_nodes refcount if found. */
|
|
/* batadv_find_router() increases neigh_nodes refcount if found. */
|
|
neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
|
|
neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
|
|
@@ -178,8 +190,7 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
|
|
if (atomic_read(&bat_priv->fragmentation) &&
|
|
if (atomic_read(&bat_priv->fragmentation) &&
|
|
skb->len > neigh_node->if_incoming->net_dev->mtu) {
|
|
skb->len > neigh_node->if_incoming->net_dev->mtu) {
|
|
/* Fragment and send packet. */
|
|
/* Fragment and send packet. */
|
|
- if (batadv_frag_send_packet(skb, orig_node, neigh_node))
|
|
|
|
- ret = NET_XMIT_SUCCESS;
|
|
|
|
|
|
+ ret = batadv_frag_send_packet(skb, orig_node, neigh_node);
|
|
|
|
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
@@ -188,12 +199,10 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
|
|
* (i.e. being forwarded). If the packet originates from this node or if
|
|
* (i.e. being forwarded). If the packet originates from this node or if
|
|
* network coding fails, then send the packet as usual.
|
|
* network coding fails, then send the packet as usual.
|
|
*/
|
|
*/
|
|
- if (recv_if && batadv_nc_skb_forward(skb, neigh_node)) {
|
|
|
|
|
|
+ if (recv_if && batadv_nc_skb_forward(skb, neigh_node))
|
|
ret = -EINPROGRESS;
|
|
ret = -EINPROGRESS;
|
|
- } else {
|
|
|
|
- batadv_send_unicast_skb(skb, neigh_node);
|
|
|
|
- ret = NET_XMIT_SUCCESS;
|
|
|
|
- }
|
|
|
|
|
|
+ else
|
|
|
|
+ ret = batadv_send_unicast_skb(skb, neigh_node);
|
|
|
|
|
|
out:
|
|
out:
|
|
if (neigh_node)
|
|
if (neigh_node)
|
|
@@ -319,7 +328,7 @@ int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
|
|
{
|
|
{
|
|
struct batadv_unicast_packet *unicast_packet;
|
|
struct batadv_unicast_packet *unicast_packet;
|
|
struct ethhdr *ethhdr;
|
|
struct ethhdr *ethhdr;
|
|
- int ret = NET_XMIT_DROP;
|
|
|
|
|
|
+ int res, ret = NET_XMIT_DROP;
|
|
|
|
|
|
if (!orig_node)
|
|
if (!orig_node)
|
|
goto out;
|
|
goto out;
|
|
@@ -356,7 +365,8 @@ int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
|
|
if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest, vid))
|
|
if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest, vid))
|
|
unicast_packet->ttvn = unicast_packet->ttvn - 1;
|
|
unicast_packet->ttvn = unicast_packet->ttvn - 1;
|
|
|
|
|
|
- if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
|
|
|
|
|
|
+ res = batadv_send_skb_to_orig(skb, orig_node, NULL);
|
|
|
|
+ if (res != -1)
|
|
ret = NET_XMIT_SUCCESS;
|
|
ret = NET_XMIT_SUCCESS;
|
|
|
|
|
|
out:
|
|
out:
|