mods[i].mod->evhand(NULL, MOD_UNLOAD, mods[i].mod->priv);
}
}
-/*--- end of module bindinghelper functions ---*/
+/*--- end of module binding helper functions ---*/
/*---
* Control hooks:
* - the hook names change between macros (NF_IP*) and enum NF_INET_*
*
* - the second argument to the netfilter hook is
- * struct sk_buff ** in kernels <= 2.6.22
- * struct sk_buff * in kernels > 2.6.22
+ * struct sk_buff ** in kernels <= 2.6.22
+ * struct sk_buff * in kernels > 2.6.22
*
* - NF_STOP is not defined before 2.6 so we remap it to NF_ACCEPT
*
* - the packet descriptor passed to the queue handler is
- * struct nf_info in kernels <= 2.6.24
- * struct nf_queue_entry in kernels <= 2.6.24
+ * struct nf_info in kernels <= 2.6.24
+ * struct nf_queue_entry in kernels <= 2.6.24
*
* - the arguments to the queue handler also change;
*/
-
+
/*
* declare hook to grab packets from the netfilter interface.
* The NF_* names change in different versions of linux, in some
#endif
/*
- * ipfw hooks the POST_ROUTING and the PRE_ROUTING chain.
- * PlanetLab tags the xid in the LOCAL_INPUT and in the
- * POST_ROUTING chain, so if we want to intercept the
- * traffic by using the id we need to hook the LOCAL_INPUT
- * chain instead of the PRE_ROUTING.
+ * ipfw hooks into the POST_ROUTING and the PRE_ROUTING chains.
+ * PlanetLab sets skb_tag to the slice id in the LOCAL_INPUT and
+ * POST_ROUTING chains, so if we want to use that information we
+ * need to hook the LOCAL_INPUT chain instead of the PRE_ROUTING.
+ * However at the moment the skb_tag info is not reliable so
+ * we stay with the standard hooks.
*/
-#ifdef IPFW_PLANETLAB
+#if 0 // defined(IPFW_PLANETLAB)
#define IPFW_HOOK_IN NF_IP_LOCAL_IN
#else
#define IPFW_HOOK_IN NF_IP_PRE_ROUTING
*
* We do this only on selected protocols: TCP, ...
*
- * Note- for locally generated, outgoing packets we don't need to
- * do a lookup because the sk_buff already points to the socket where
+ * The chain is the following
+ * sk_buff* sock* socket* file*
+ * skb -> sk ->sk_socket->file ->f_owner ->pid
+ * skb -> sk ->sk_socket->file ->f_uid (direct)
+ * skb -> sk ->sk_socket->file ->f_cred->fsuid (2.6.29+)
+ *
+ * Related headers:
+ * linux/skbuff.h struct skbuff
+ * net/sock.h struct sock
+ * linux/net.h struct socket
+ * linux/fs.h struct file
+ *
+ * With vserver we may have sk->sk_xid and sk->sk_nid that
+ * which we store in fw_groups[1] (matches O_JAIL) and fw_groups[2]
+ * (no matches yet)
+ *
+ * Note- for locally generated, outgoing packets we should not need
+ * need a lookup because the sk_buff already points to the socket where
* the info is.
*/
extern struct inet_hashinfo tcp_hashinfo;
*/
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24)
#define _OPT_NET_ARG
-#else /* 2.6.25 and above */
+#else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
+/* there is no dev_net() on 2.6.25 */
+#define _OPT_NET_ARG (skb->dev->nd_net),
+#else /* 2.6.26 and above */
#define _OPT_NET_ARG dev_net(skb->dev),
+#endif
#endif
+ if (0 && skb->sk) {
+ sk=skb->sk;
+ } else {
sk = (dir) ?
inet_lookup(_OPT_NET_ARG &tcp_hashinfo,
daddr, dport, saddr, sport, // matches outgoing for server sockets
inet_lookup(_OPT_NET_ARG &tcp_hashinfo,
saddr, sport, daddr, dport, // matches incoming for server sockets
skb->dev->ifindex);
+ }
#undef _OPT_NET_ARG
/* no match, nothing to be done */
sk->sk_socket && sk->sk_socket->file) {
ugp->fw_uid = sk->sk_socket->file->_CURR_UID;
uid = ugp->fw_uid;
+ ugp->fw_groups[0] = sk->sk_socket->file->_CURR_GID;
+#ifdef CONFIG_VSERVER
+ ugp->fw_groups[1] = sk->sk_xid;
+ ugp->fw_groups[2] = sk->sk_nid;
+#endif
ret = 1;
}
- sock_put(sk);
+ if (1 || !skb->sk) /* the reference came from the lookup */
+ sock_put(sk);
#undef _CURR_UID
#undef _CURR_GID