Skip to contentSkip to conversation

NetLabel

RFC In review Paul Moore 1 participant 1 message May 25, 2006

Subsystems (5)
lore
Share & tools
lore

Paul Moore

author
#0 lore raw

RFC 3/4 NetLabel

This patch adds IPv4 CIPSO support to NetLabel subsystem. It includes hooks into the core network stack as well as the required NetLabel components.

include/linux/ip.h               |    1
include/net/cipso_ipv4.h         |  179 +++
include/net/inet_sock.h          |    2
net/ipv4/cipso_ipv4.c            | 1568 +++++++++++++++++++++++++++++++
net/ipv4/ip_fragment.c           |   38
net/ipv4/ip_options.c            |   19
net/netlabel/netlabel_cipso_v4.c |  519 ++++++++++
net/netlabel/netlabel_cipso_v4.h |  185 +++
8 files changed, 2510 insertions(+), 1 deletion(-)
include/linux/ip.h +0 -0
@@ -57,6 +57,7 @@

#define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT)
+#define IPOPT_CIPSO (6 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_RR (7 |IPOPT_CONTROL)
#define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY)

include/net/cipso_ipv4.h +172 -0

172 lines not on this page · raw message

include/net/inet_sock.h +0 -0
@@ -52,7 +52,7 @@ struct ip_options {
			ts_needtime:1,
			ts_needaddr:1;
	unsigned char	router_alert;
-	unsigned char	__pad1;
+	unsigned char	cipso;
	unsigned char	__pad2;
	unsigned char	__data[0];
};
net/ipv4/cipso_ipv4.c +1547 -0

1,547 lines not on this page · raw message

net/ipv4/ip_fragment.c +0 -0
@@ -73,6 +73,11 @@ struct ipfrag_skb_cb
 

#define FRAG_CB(skb) ((struct ipfrag_skb_cb*)((skb)->cb))

+/* Track critical IP options that must be the same in each fragment. */ +struct ipq_opts {
+ unsigned char *cipso;
+};
+
/* Describe an entry in the "incomplete datagrams" queue. */

struct ipq {
	struct hlist_node list;
@@ -97,6 +102,7 @@ struct ipq {
	int             iif;
	unsigned int    rid;
	struct inet_peer *peer;

+ struct ipq_opts opt;
};

/* Hash table. */
@@ -177,6 +183,8 @@ static __inline__ void frag_free_queue(s

	if (work)
		*work -= sizeof(struct ipq);
	atomic_sub(sizeof(struct ipq), &ip_frag_mem);
+	if (qp->opt.cipso)
+		kfree(qp->opt.cipso);
	kfree(qp);
}

@@ -368,6 +376,8 @@ static struct ipq *ip_frag_create(struct

	qp->iif = 0;
	qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;

+ qp->opt.cipso = NULL;
+

	/* Initialize a timer for this entry. */
	init_timer(&qp->timer);
	qp->timer.data = (unsigned long) qp;	/* pointer to queue	*/
@@ -514,6 +524,34 @@ static void ip_frag_queue(struct ipq *qp
	if (end == offset)
		goto err;

+ /* If this is the first packet fragment we have seen then
+ * record any _critical_ options in qp->opt. Otherwise,
+ * verify that the _critical_ options in the current fragment
+ * match with what is stored in qp->opt.
+ */
+ if (qp->fragments != NULL) {
+ if (qp->opt.cipso) {
+ char cipso_len;
+ cipso_len = skb->nh.raw[FRAG_CB(skb)->h.opt.cipso + 1];
+ if (cipso_len != qp->opt.cipso[1] ||
+ memcmp(qp->opt.cipso, + skb->nh.raw + FRAG_CB(skb)->h.opt.cipso,
+ cipso_len) != 0)
+ goto err;
+ }
+ } else if (qp->fragments == NULL && ihl > 20) {
+ if (FRAG_CB(skb)->h.opt.cipso) {
+ char cipso_len;
+ cipso_len = skb->nh.raw[FRAG_CB(skb)->h.opt.cipso + 1];
+ qp->opt.cipso = kmalloc(cipso_len, GFP_ATOMIC);
+ if (qp->opt.cipso == NULL)
+ goto err;
+ memcpy(qp->opt.cipso,
+ skb->nh.raw + FRAG_CB(skb)->h.opt.cipso,
+ cipso_len);
+ }
+ }
+

	if (pskb_pull(skb, ihl) == NULL)
		goto err;
	if (pskb_trim_rcsum(skb, end-offset))
net/ipv4/ip_options.c +0 -0
@@ -24,6 +24,7 @@

#include <net/ip.h>
#include <net/icmp.h>
#include <net/route.h>
+#include <net/cipso_ipv4.h>

/*
* Write options to IP header, record destination address to
@@ -194,6 +195,15 @@ int ip_options_echo(struct ip_options *

			dopt->is_strictroute = sopt->is_strictroute;
		}
	}

+#ifdef CONFIG_NETLABEL_CIPSOV4
+ if (sopt->cipso) {
+ optlen = sptr[sopt->cipso+1];
+ dopt->cipso = dopt->optlen+sizeof(struct iphdr);
+ memcpy(dptr, sptr+sopt->cipso, optlen);
+ dptr += optlen;
+ dopt->optlen += optlen;
+ }
+#endif /* CONFIG_NETLABEL_CIPSOV4 */

	while (dopt->optlen & 3) {
		*dptr++ = IPOPT_END;
		dopt->optlen++;
@@ -435,6 +445,15 @@ int ip_options_compile(struct ip_options
			if (optptr[2] == 0 && optptr[3] == 0)
				opt->router_alert = optptr - iph;
			break;

+#ifdef CONFIG_NETLABEL_CIPSOV4
+ case IPOPT_CIPSO:
+ if (opt->cipso || cipso_v4_validate(&optptr)) {
+ pp_ptr = optptr;
+ goto error;
+ }
+ opt->cipso = optptr - iph;
+ break;
+#endif /* CONFIG_NETLABEL_CIPSOV4 */
case IPOPT_SEC:
case IPOPT_SID:
default:

net/netlabel/netlabel_cipso_v4.c +510 -0

510 lines not on this page · raw message

net/netlabel/netlabel_cipso_v4.h +181 -0

181 lines not on this page · raw message