Index: net/dccp/dccp_options.c
===================================================================
--- net/dccp/dccp_options.c.orig	2005-05-06 09:16:34.000000000 -0300
+++ net/dccp/dccp_options.c	2005-05-06 10:44:27.000000000 -0300
@@ -144,6 +144,33 @@
 	return rc;
 }
 
+static int dccp_negotiate_feature(struct sk_buff *skb, char *opt)
+{
+	int rc = 0;
+
+	switch (opt[1]) {
+	case DCCPF_CCID:
+	case DCCPF_ALLOW_SHORT_SEQNOS:
+	case DCCPF_SEQUENCE_WINDOW:
+	case DCCPF_ECN_INCAPABLE:
+	case DCCPF_ACK_RATIO:
+	case DCCPF_SEND_ACK_VECTOR:
+	case DCCPF_SEND_NDP_COUNT:
+	case DCCPF_MIN_CRC_COVERAGE:
+	case DCCPF_CHECK_DATA:
+		break;
+	/* we should silently ignore these features as we
+	 * don't understand it unless marked as mandatory */
+	case DCCPF_RESERVED:
+	case DCCPF_MIN_CCID_SPECIFIC:
+	case DCCPF_MAX_CCID_SPECIFIC:
+		if (mandatory)
+			rc = 1;
+	}
+
+	return rc;
+}
+
 /* TODO
  * - we must check if the packet type may carry options
  * - we must check for repeated options
@@ -225,14 +252,22 @@
 			dccp_pr_debug("slow receiver\n");
 			break;
 		case DCCPO_CHANGE_L:
-			dccp_pr_debug("change L\n");
+ 		case DCCPO_CHANGE_R:
+ 			dccp_pr_debug("change %c\n",
+					(opt[i] == DCCPO_CHANGE_L)? 'L':'R');
+ 			if (dccp_negotiate_feature(opt + i, next_mandatory)) {
+ 				DCCP_SKB_CB(skb)->dccpd_reset_code =
+ 			       		DCCP_RESET_CODE_MANDATORY_ERROR;
+ 				dccp_pr_debug("mandatory option not "
+					      "recognized!\n");
+ 				DCCP_INC_STATS_BH(DCCP_MIB_OPTMANDATORYERROR);
+ 				rc = -1; /* Caller will do the reset for us */
+ 				goto out;
+ 			}
 			break;
 		case DCCPO_CONFIRM_L:
 			dccp_pr_debug("confirm L\n");
 			break;
-		case DCCPO_CHANGE_R:
-			dccp_pr_debug("change R\n");
-			break;
 		case DCCPO_CONFIRM_R:
 			dccp_pr_debug("confirm R\n");
 			break;
