reqid:1;
 };
 
+union ipt_policy_addr
+{
+       struct in_addr  a4;
+       struct in6_addr a6;
+};
+
 struct ipt_policy_elem
 {
-       u_int32_t       saddr;
-       u_int32_t       smask;
-       u_int32_t       daddr;
-       u_int32_t       dmask;
-       u_int32_t       spi;
-       u_int32_t       reqid;
-       u_int8_t        proto;
-       u_int8_t        mode;
+       union ipt_policy_addr   saddr;
+       union ipt_policy_addr   smask;
+       union ipt_policy_addr   daddr;
+       union ipt_policy_addr   dmask;
+       u_int32_t               spi;
+       u_int32_t               reqid;
+       u_int8_t                proto;
+       u_int8_t                mode;
 
        struct ipt_policy_spec  match;
        struct ipt_policy_spec  invert;
 
                        reqid:1;
 };
 
+union ip6t_policy_addr
+{
+       struct in_addr  a4;
+       struct in6_addr a6;
+};
+
 struct ip6t_policy_elem
 {
-       struct in6_addr saddr;
-       struct in6_addr smask;
-       struct in6_addr daddr;
-       struct in6_addr dmask;
-       u_int32_t       spi;
-       u_int32_t       reqid;
-       u_int8_t        proto;
-       u_int8_t        mode;
+       union ip6t_policy_addr  saddr;
+       union ip6t_policy_addr  smask;
+       union ip6t_policy_addr  daddr;
+       union ip6t_policy_addr  dmask;
+       u_int32_t               spi;
+       u_int32_t               reqid;
+       u_int8_t                proto;
+       u_int8_t                mode;
 
        struct ip6t_policy_spec match;
        struct ip6t_policy_spec invert;
 
 static inline int
 match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
 {
-#define MATCH(x,y)     (!e->match.x || ((e->x == (y)) ^ e->invert.x))
+#define MATCH_ADDR(x,y,z)      (!e->match.x ||                              \
+                                ((e->x.a4.s_addr == (e->y.a4.s_addr & (z))) \
+                                 ^ e->invert.x))
+#define MATCH(x,y)             (!e->match.x || ((e->x == (y)) ^ e->invert.x))
 
-       return MATCH(saddr, x->props.saddr.a4 & e->smask) &&
-              MATCH(daddr, x->id.daddr.a4 & e->dmask) &&
+       return MATCH_ADDR(saddr, smask, x->props.saddr.a4) &&
+              MATCH_ADDR(daddr, dmask, x->id.daddr.a4) &&
               MATCH(proto, x->id.proto) &&
               MATCH(mode, x->props.mode) &&
               MATCH(spi, x->id.spi) &&
 
 static inline int
 match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e)
 {
-#define MATCH_ADDR(x,y,z)      (!e->match.x ||                          \
-                                ((!ip6_masked_addrcmp(&e->x, &e->y, z)) \
+#define MATCH_ADDR(x,y,z)      (!e->match.x ||                                \
+                                ((!ip6_masked_addrcmp(&e->x.a6, &e->y.a6, z)) \
                                  ^ e->invert.x))
 #define MATCH(x,y)             (!e->match.x || ((e->x == (y)) ^ e->invert.x))