@@ -1410,7 +1410,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
* @if_outgoing: the interface for which the packet should be considered
*/
static void
-batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
+batadv_iv_ogm_process_per_outif(struct sk_buff *skb, int ogm_offset,
struct batadv_orig_node *orig_node,
struct batadv_hard_iface *if_incoming,
struct batadv_hard_iface *if_outgoing)
@@ -1614,7 +1614,7 @@ batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
* @ogm_offset: offset to the OGM which should be processed (for aggregates)
* @if_incoming: the interface where this packet was receved
*/
-static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
+static void batadv_iv_ogm_process(struct sk_buff *skb, int ogm_offset,
struct batadv_hard_iface *if_incoming)
{
struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
@@ -603,7 +603,7 @@ static bool batadv_v_ogm_route_update(struct batadv_priv *bat_priv,
*/
static void
batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv,
- const struct sk_buff *skb,
+ struct sk_buff *skb,
const struct batadv_ogm2_packet *ogm2,
struct batadv_orig_node *orig_node,
struct batadv_neigh_node *neigh_node,
@@ -673,7 +673,7 @@ static bool batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
* @ogm_offset: offset to the OGM which should be processed (for aggregates)
* @if_incoming: the interface where this packet was receved
*/
-static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset,
+static void batadv_v_ogm_process(struct sk_buff *skb, int ogm_offset,
struct batadv_hard_iface *if_incoming)
{
struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
@@ -497,12 +497,12 @@ static void batadv_tvlv_call_unfound_handlers(struct batadv_priv *bat_priv,
* any TVLV handler called successfully. Returns NET_RX_DROP otherwise.
*/
int batadv_tvlv_containers_process2(struct batadv_priv *bat_priv,
- const struct sk_buff *skb, u8 packet_type,
+ struct sk_buff *skb, u8 packet_type,
unsigned int tvlv_offset,
u16 tvlv_value_len, void *ctx)
{
struct batadv_tvlv_hdr *tvlv_hdr, tvlv_hdr_buff;
- u8 *tvlv_value, tvlv_value_buff[128];
+ u8 *tvlv_value, tvlv_value_buff[256];
u16 tvlv_value_cont_len;
int ret = NET_RX_SUCCESS;
@@ -517,14 +517,16 @@ int batadv_tvlv_containers_process2(struct batadv_priv *bat_priv,
tvlv_offset += sizeof(*tvlv_hdr);
tvlv_value_len -= sizeof(*tvlv_hdr);
- if (tvlv_value_cont_len > sizeof(tvlv_value_buff)) {
- pr_warn_once("batman-adv: TVLVs greater than 128 bytes unsupported for now, ignoring\n");
- goto skip_handler_call;
- }
-
if (tvlv_value_cont_len > tvlv_value_len)
return NET_RX_DROP;
+ /* check for sufficient space either in stack buffer or
+ * in skb's linear data buffer
+ */
+ if (tvlv_value_cont_len > sizeof(tvlv_value_buff) &&
+ !pskb_may_pull(skb, tvlv_offset + tvlv_value_cont_len))
+ return NET_RX_DROP;
+
tvlv_value = skb_header_pointer(skb, tvlv_offset,
tvlv_value_cont_len,
tvlv_value_buff);
@@ -535,7 +537,7 @@ int batadv_tvlv_containers_process2(struct batadv_priv *bat_priv,
tvlv_hdr->type,
tvlv_hdr->version, tvlv_value,
tvlv_value_cont_len, ctx);
-skip_handler_call:
+
tvlv_offset += tvlv_value_cont_len;
tvlv_value_len -= tvlv_value_cont_len;
}
@@ -626,7 +628,7 @@ int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
* OGM header.
*/
void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv,
- const struct sk_buff *skb,
+ struct sk_buff *skb,
struct batadv_orig_node *orig_node)
{
struct batadv_ogm_packet *ogm_packet;
@@ -31,7 +31,7 @@ u16 batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
unsigned char **packet_buff,
int *packet_buff_len, int packet_min_len);
void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv,
- const struct sk_buff *skb,
+ struct sk_buff *skb,
struct batadv_orig_node *orig_node);
void batadv_tvlv_container_unregister(struct batadv_priv *bat_priv,
u8 type, u8 version);
@@ -65,7 +65,7 @@ int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
u8 *src, u8 *dst,
void *tvlv_buff, u16 tvlv_buff_len);
int batadv_tvlv_containers_process2(struct batadv_priv *bat_priv,
- const struct sk_buff *skb, u8 packet_type,
+ struct sk_buff *skb, u8 packet_type,
unsigned int tvlv_offset,
u16 tvlv_value_len, void *ctx);
void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, u8 *src,