struct net_bridge_port *p)
{
WARN_ON_ONCE(skb_shared(skb));
+ WARN_ON_ONCE(skb->destructor);
if (run_flow_through_tables(chain, skb, p))
dp_output_control(chain->dp, skb, fwd_save_skb(skb),
chain->dp->miss_send_len,
{
const struct ofp_packet_out *opo = msg;
struct sk_buff *skb;
- struct vlan_ethhdr *mac;
- int nh_ofs;
uint16_t v_code;
struct sw_flow_key key;
size_t actions_len = ntohs(opo->actions_len);
/* FIXME? We don't reserve NET_IP_ALIGN or NET_SKB_PAD since
* we're just transmitting this raw without examining anything
* at those layers. */
- memcpy(skb_put(skb, data_len), (uint8_t *)opo->actions + actions_len,
- data_len);
-
- skb_set_mac_header(skb, 0);
- mac = vlan_eth_hdr(skb);
- if (likely(mac->h_vlan_proto != htons(ETH_P_8021Q)))
- nh_ofs = sizeof(struct ethhdr);
- else
- nh_ofs = sizeof(struct vlan_ethhdr);
- skb_set_network_header(skb, nh_ofs);
+ skb_put(skb, data_len);
+ skb_copy_to_linear_data(skb,
+ (uint8_t *)opo->actions + actions_len,
+ data_len);
+ skb_reset_mac_header(skb);
} else {
skb = retrieve_skb(ntohl(opo->buffer_id));
if (!skb)
unsigned long int flags;
uint32_t id;
+ /* FIXME: Probably just need a skb_clone() here. */
+ skb = skb_copy(skb, GFP_ATOMIC);
+ if (!skb)
+ return -1;
+
spin_lock_irqsave(&buffer_lock, flags);
buffer_idx = (buffer_idx + 1) & PKT_BUFFER_MASK;
p = &buffers[buffer_idx];
* OVERWRITE_SECS old. */
if (time_before(jiffies, p->exp_jiffies)) {
spin_unlock_irqrestore(&buffer_lock, flags);
+ kfree_skb(skb);
return -1;
} else {
- /* Defer kfree_skb() until interrupts re-enabled. */
+ /* Defer kfree_skb() until interrupts re-enabled.
+ * FIXME: we only need to do that if it has a
+ * destructor, but it never should since we orphan
+ * sk_buffs on entry. */
old_skb = p->skb;
}
}
* special. */
if (++p->cookie >= (1u << PKT_COOKIE_BITS) - 1)
p->cookie = 0;
- skb_get(skb);
p->skb = skb;
p->exp_jiffies = jiffies + OVERWRITE_JIFFIES;
id = buffer_idx | (p->cookie << PKT_BUFFER_BITS);