{
        struct tcf_pedit *p = a->priv;
        int i, munged = 0;
-       u8 *pptr;
+       unsigned int off;
 
        if (!(skb->tc_verd & TC_OK2MUNGE)) {
                /* should we set skb->cloned? */
                }
        }
 
-       pptr = skb_network_header(skb);
+       off = skb_network_offset(skb);
 
        spin_lock(&p->tcf_lock);
 
                struct tc_pedit_key *tkey = p->tcfp_keys;
 
                for (i = p->tcfp_nkeys; i > 0; i--, tkey++) {
-                       u32 *ptr;
+                       u32 *ptr, _data;
                        int offset = tkey->off;
 
                        if (tkey->offmask) {
-                               if (skb->len > tkey->at) {
-                                        char *j = pptr + tkey->at;
-                                        offset += ((*j & tkey->offmask) >>
-                                                  tkey->shift);
-                               } else {
+                               char *d, _d;
+
+                               d = skb_header_pointer(skb, off + tkey->at, 1,
+                                                      &_d);
+                               if (!d)
                                        goto bad;
-                               }
+                               offset += (*d & tkey->offmask) >> tkey->shift;
                        }
 
                        if (offset % 4) {
                                goto bad;
                        }
 
-                       ptr = (u32 *)(pptr+offset);
+                       ptr = skb_header_pointer(skb, off + offset, 4, &_data);
+                       if (!ptr)
+                               goto bad;
                        /* just do it, baby */
                        *ptr = ((*ptr & tkey->mask) ^ tkey->val);
+                       if (ptr == &_data)
+                               skb_store_bits(skb, off + offset, ptr, 4);
                        munged++;
                }