diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..b60b1f102 --- /dev/null +++ b/.clang-format @@ -0,0 +1,95 @@ +--- +Language: Cpp +# BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: true +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: All +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: true +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeCategories: + - Regex: '^<.*\.h>' + Priority: 1 + - Regex: '^<.*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentCaseLabels: true +IndentWidth: 8 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 8 +UseTab: Never +... + diff --git a/examples/aes_decrypt/aes.c b/examples/aes_decrypt/aes.c index 61848c10f..874797209 100644 --- a/examples/aes_decrypt/aes.c +++ b/examples/aes_decrypt/aes.c @@ -54,82 +54,94 @@ * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf * Source: https://github.com/B-Con/crypto-algorithms *********************************************************************/ - + /*************************** HEADER FILES ***************************/ -#include -#include #include "aes.h" - +#include +#include + #include - + /****************************** MACROS ******************************/ // The least significant byte of the word is rotated to the end. #define KE_ROTWORD(x) (((x) << 8) | ((x) >> 24)) - -#define TRUE 1 + +#define TRUE 1 #define FALSE 0 - + /**************************** DATA TYPES ****************************/ #define AES_128_ROUNDS 10 #define AES_192_ROUNDS 12 #define AES_256_ROUNDS 14 - + /*********************** FUNCTION DECLARATIONS **********************/ -void ccm_prepare_first_ctr_blk(BYTE counter[], const BYTE nonce[], int nonce_len, int payload_len_store_size); -void ccm_prepare_first_format_blk(BYTE buf[], int assoc_len, int payload_len, int payload_len_store_size, int mac_len, const BYTE nonce[], int nonce_len); -void ccm_format_assoc_data(BYTE buf[], int *end_of_buf, const BYTE assoc[], int assoc_len); -void ccm_format_payload_data(BYTE buf[], int *end_of_buf, const BYTE payload[], int payload_len); -void xor_buf(const BYTE in[], BYTE out[], size_t len); -WORD SubWord(WORD word); -void AddRoundKey(BYTE state[][4], const WORD w[]); -void SubBytes(BYTE state[][4]); -void InvSubBytes(BYTE state[][4]); -void ShiftRows(BYTE state[][4]); -void MixColumns(BYTE state[][4]); -void InvMixColumns(BYTE state[][4]); -void InvShiftRows(BYTE state[][4]); - +void +ccm_prepare_first_ctr_blk(BYTE counter[], const BYTE nonce[], int nonce_len, int payload_len_store_size); +void +ccm_prepare_first_format_blk(BYTE buf[], int assoc_len, int payload_len, int payload_len_store_size, int mac_len, + const BYTE nonce[], int nonce_len); +void +ccm_format_assoc_data(BYTE buf[], int *end_of_buf, const BYTE assoc[], int assoc_len); +void +ccm_format_payload_data(BYTE buf[], int *end_of_buf, const BYTE payload[], int payload_len); +void +xor_buf(const BYTE in[], BYTE out[], size_t len); +WORD +SubWord(WORD word); +void +AddRoundKey(BYTE state[][4], const WORD w[]); +void +SubBytes(BYTE state[][4]); +void +InvSubBytes(BYTE state[][4]); +void +ShiftRows(BYTE state[][4]); +void +MixColumns(BYTE state[][4]); +void +InvMixColumns(BYTE state[][4]); +void +InvShiftRows(BYTE state[][4]); + /**************************** VARIABLES *****************************/ // This is the specified AES SBox. To look up a substitution value, put the first // nibble in the first index (row) and the second nibble in the second index (column). static const BYTE aes_sbox[16][16] = { - {0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76}, - {0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0}, - {0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15}, - {0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75}, - {0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84}, - {0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF}, - {0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8}, - {0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2}, - {0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73}, - {0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB}, - {0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79}, - {0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08}, - {0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A}, - {0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E}, - {0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF}, - {0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16} -}; - + {0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76}, + {0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0}, + {0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15}, + {0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75}, + {0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84}, + {0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF}, + {0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8}, + {0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2}, + {0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73}, + {0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB}, + {0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79}, + {0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08}, + {0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A}, + {0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E}, + {0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF}, + {0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16}}; + static const BYTE aes_invsbox[16][16] = { - {0x52,0x09,0x6A,0xD5,0x30,0x36,0xA5,0x38,0xBF,0x40,0xA3,0x9E,0x81,0xF3,0xD7,0xFB}, - {0x7C,0xE3,0x39,0x82,0x9B,0x2F,0xFF,0x87,0x34,0x8E,0x43,0x44,0xC4,0xDE,0xE9,0xCB}, - {0x54,0x7B,0x94,0x32,0xA6,0xC2,0x23,0x3D,0xEE,0x4C,0x95,0x0B,0x42,0xFA,0xC3,0x4E}, - {0x08,0x2E,0xA1,0x66,0x28,0xD9,0x24,0xB2,0x76,0x5B,0xA2,0x49,0x6D,0x8B,0xD1,0x25}, - {0x72,0xF8,0xF6,0x64,0x86,0x68,0x98,0x16,0xD4,0xA4,0x5C,0xCC,0x5D,0x65,0xB6,0x92}, - {0x6C,0x70,0x48,0x50,0xFD,0xED,0xB9,0xDA,0x5E,0x15,0x46,0x57,0xA7,0x8D,0x9D,0x84}, - {0x90,0xD8,0xAB,0x00,0x8C,0xBC,0xD3,0x0A,0xF7,0xE4,0x58,0x05,0xB8,0xB3,0x45,0x06}, - {0xD0,0x2C,0x1E,0x8F,0xCA,0x3F,0x0F,0x02,0xC1,0xAF,0xBD,0x03,0x01,0x13,0x8A,0x6B}, - {0x3A,0x91,0x11,0x41,0x4F,0x67,0xDC,0xEA,0x97,0xF2,0xCF,0xCE,0xF0,0xB4,0xE6,0x73}, - {0x96,0xAC,0x74,0x22,0xE7,0xAD,0x35,0x85,0xE2,0xF9,0x37,0xE8,0x1C,0x75,0xDF,0x6E}, - {0x47,0xF1,0x1A,0x71,0x1D,0x29,0xC5,0x89,0x6F,0xB7,0x62,0x0E,0xAA,0x18,0xBE,0x1B}, - {0xFC,0x56,0x3E,0x4B,0xC6,0xD2,0x79,0x20,0x9A,0xDB,0xC0,0xFE,0x78,0xCD,0x5A,0xF4}, - {0x1F,0xDD,0xA8,0x33,0x88,0x07,0xC7,0x31,0xB1,0x12,0x10,0x59,0x27,0x80,0xEC,0x5F}, - {0x60,0x51,0x7F,0xA9,0x19,0xB5,0x4A,0x0D,0x2D,0xE5,0x7A,0x9F,0x93,0xC9,0x9C,0xEF}, - {0xA0,0xE0,0x3B,0x4D,0xAE,0x2A,0xF5,0xB0,0xC8,0xEB,0xBB,0x3C,0x83,0x53,0x99,0x61}, - {0x17,0x2B,0x04,0x7E,0xBA,0x77,0xD6,0x26,0xE1,0x69,0x14,0x63,0x55,0x21,0x0C,0x7D} -}; - + {0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB}, + {0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB}, + {0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E}, + {0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25}, + {0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92}, + {0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84}, + {0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06}, + {0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B}, + {0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73}, + {0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E}, + {0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B}, + {0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4}, + {0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F}, + {0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF}, + {0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61}, + {0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D}}; + // This table stores pre-calculated values for all possible GF(2^8) calculations.This // table is only used by the (Inv)MixColumns steps. // USAGE: The second index (column) is the coefficient of multiplication. Only 7 different @@ -137,986 +149,1041 @@ static const BYTE aes_invsbox[16][16] = { // 1 is negligible leaving only 6 coefficients. Each column of the table is devoted to one // of these coefficients, in the ascending order of value, from values 0x00 to 0xFF. static const BYTE gf_mul[256][6] = { - {0x00,0x00,0x00,0x00,0x00,0x00},{0x02,0x03,0x09,0x0b,0x0d,0x0e}, - {0x04,0x06,0x12,0x16,0x1a,0x1c},{0x06,0x05,0x1b,0x1d,0x17,0x12}, - {0x08,0x0c,0x24,0x2c,0x34,0x38},{0x0a,0x0f,0x2d,0x27,0x39,0x36}, - {0x0c,0x0a,0x36,0x3a,0x2e,0x24},{0x0e,0x09,0x3f,0x31,0x23,0x2a}, - {0x10,0x18,0x48,0x58,0x68,0x70},{0x12,0x1b,0x41,0x53,0x65,0x7e}, - {0x14,0x1e,0x5a,0x4e,0x72,0x6c},{0x16,0x1d,0x53,0x45,0x7f,0x62}, - {0x18,0x14,0x6c,0x74,0x5c,0x48},{0x1a,0x17,0x65,0x7f,0x51,0x46}, - {0x1c,0x12,0x7e,0x62,0x46,0x54},{0x1e,0x11,0x77,0x69,0x4b,0x5a}, - {0x20,0x30,0x90,0xb0,0xd0,0xe0},{0x22,0x33,0x99,0xbb,0xdd,0xee}, - {0x24,0x36,0x82,0xa6,0xca,0xfc},{0x26,0x35,0x8b,0xad,0xc7,0xf2}, - {0x28,0x3c,0xb4,0x9c,0xe4,0xd8},{0x2a,0x3f,0xbd,0x97,0xe9,0xd6}, - {0x2c,0x3a,0xa6,0x8a,0xfe,0xc4},{0x2e,0x39,0xaf,0x81,0xf3,0xca}, - {0x30,0x28,0xd8,0xe8,0xb8,0x90},{0x32,0x2b,0xd1,0xe3,0xb5,0x9e}, - {0x34,0x2e,0xca,0xfe,0xa2,0x8c},{0x36,0x2d,0xc3,0xf5,0xaf,0x82}, - {0x38,0x24,0xfc,0xc4,0x8c,0xa8},{0x3a,0x27,0xf5,0xcf,0x81,0xa6}, - {0x3c,0x22,0xee,0xd2,0x96,0xb4},{0x3e,0x21,0xe7,0xd9,0x9b,0xba}, - {0x40,0x60,0x3b,0x7b,0xbb,0xdb},{0x42,0x63,0x32,0x70,0xb6,0xd5}, - {0x44,0x66,0x29,0x6d,0xa1,0xc7},{0x46,0x65,0x20,0x66,0xac,0xc9}, - {0x48,0x6c,0x1f,0x57,0x8f,0xe3},{0x4a,0x6f,0x16,0x5c,0x82,0xed}, - {0x4c,0x6a,0x0d,0x41,0x95,0xff},{0x4e,0x69,0x04,0x4a,0x98,0xf1}, - {0x50,0x78,0x73,0x23,0xd3,0xab},{0x52,0x7b,0x7a,0x28,0xde,0xa5}, - {0x54,0x7e,0x61,0x35,0xc9,0xb7},{0x56,0x7d,0x68,0x3e,0xc4,0xb9}, - {0x58,0x74,0x57,0x0f,0xe7,0x93},{0x5a,0x77,0x5e,0x04,0xea,0x9d}, - {0x5c,0x72,0x45,0x19,0xfd,0x8f},{0x5e,0x71,0x4c,0x12,0xf0,0x81}, - {0x60,0x50,0xab,0xcb,0x6b,0x3b},{0x62,0x53,0xa2,0xc0,0x66,0x35}, - {0x64,0x56,0xb9,0xdd,0x71,0x27},{0x66,0x55,0xb0,0xd6,0x7c,0x29}, - {0x68,0x5c,0x8f,0xe7,0x5f,0x03},{0x6a,0x5f,0x86,0xec,0x52,0x0d}, - {0x6c,0x5a,0x9d,0xf1,0x45,0x1f},{0x6e,0x59,0x94,0xfa,0x48,0x11}, - {0x70,0x48,0xe3,0x93,0x03,0x4b},{0x72,0x4b,0xea,0x98,0x0e,0x45}, - {0x74,0x4e,0xf1,0x85,0x19,0x57},{0x76,0x4d,0xf8,0x8e,0x14,0x59}, - {0x78,0x44,0xc7,0xbf,0x37,0x73},{0x7a,0x47,0xce,0xb4,0x3a,0x7d}, - {0x7c,0x42,0xd5,0xa9,0x2d,0x6f},{0x7e,0x41,0xdc,0xa2,0x20,0x61}, - {0x80,0xc0,0x76,0xf6,0x6d,0xad},{0x82,0xc3,0x7f,0xfd,0x60,0xa3}, - {0x84,0xc6,0x64,0xe0,0x77,0xb1},{0x86,0xc5,0x6d,0xeb,0x7a,0xbf}, - {0x88,0xcc,0x52,0xda,0x59,0x95},{0x8a,0xcf,0x5b,0xd1,0x54,0x9b}, - {0x8c,0xca,0x40,0xcc,0x43,0x89},{0x8e,0xc9,0x49,0xc7,0x4e,0x87}, - {0x90,0xd8,0x3e,0xae,0x05,0xdd},{0x92,0xdb,0x37,0xa5,0x08,0xd3}, - {0x94,0xde,0x2c,0xb8,0x1f,0xc1},{0x96,0xdd,0x25,0xb3,0x12,0xcf}, - {0x98,0xd4,0x1a,0x82,0x31,0xe5},{0x9a,0xd7,0x13,0x89,0x3c,0xeb}, - {0x9c,0xd2,0x08,0x94,0x2b,0xf9},{0x9e,0xd1,0x01,0x9f,0x26,0xf7}, - {0xa0,0xf0,0xe6,0x46,0xbd,0x4d},{0xa2,0xf3,0xef,0x4d,0xb0,0x43}, - {0xa4,0xf6,0xf4,0x50,0xa7,0x51},{0xa6,0xf5,0xfd,0x5b,0xaa,0x5f}, - {0xa8,0xfc,0xc2,0x6a,0x89,0x75},{0xaa,0xff,0xcb,0x61,0x84,0x7b}, - {0xac,0xfa,0xd0,0x7c,0x93,0x69},{0xae,0xf9,0xd9,0x77,0x9e,0x67}, - {0xb0,0xe8,0xae,0x1e,0xd5,0x3d},{0xb2,0xeb,0xa7,0x15,0xd8,0x33}, - {0xb4,0xee,0xbc,0x08,0xcf,0x21},{0xb6,0xed,0xb5,0x03,0xc2,0x2f}, - {0xb8,0xe4,0x8a,0x32,0xe1,0x05},{0xba,0xe7,0x83,0x39,0xec,0x0b}, - {0xbc,0xe2,0x98,0x24,0xfb,0x19},{0xbe,0xe1,0x91,0x2f,0xf6,0x17}, - {0xc0,0xa0,0x4d,0x8d,0xd6,0x76},{0xc2,0xa3,0x44,0x86,0xdb,0x78}, - {0xc4,0xa6,0x5f,0x9b,0xcc,0x6a},{0xc6,0xa5,0x56,0x90,0xc1,0x64}, - {0xc8,0xac,0x69,0xa1,0xe2,0x4e},{0xca,0xaf,0x60,0xaa,0xef,0x40}, - {0xcc,0xaa,0x7b,0xb7,0xf8,0x52},{0xce,0xa9,0x72,0xbc,0xf5,0x5c}, - {0xd0,0xb8,0x05,0xd5,0xbe,0x06},{0xd2,0xbb,0x0c,0xde,0xb3,0x08}, - {0xd4,0xbe,0x17,0xc3,0xa4,0x1a},{0xd6,0xbd,0x1e,0xc8,0xa9,0x14}, - {0xd8,0xb4,0x21,0xf9,0x8a,0x3e},{0xda,0xb7,0x28,0xf2,0x87,0x30}, - {0xdc,0xb2,0x33,0xef,0x90,0x22},{0xde,0xb1,0x3a,0xe4,0x9d,0x2c}, - {0xe0,0x90,0xdd,0x3d,0x06,0x96},{0xe2,0x93,0xd4,0x36,0x0b,0x98}, - {0xe4,0x96,0xcf,0x2b,0x1c,0x8a},{0xe6,0x95,0xc6,0x20,0x11,0x84}, - {0xe8,0x9c,0xf9,0x11,0x32,0xae},{0xea,0x9f,0xf0,0x1a,0x3f,0xa0}, - {0xec,0x9a,0xeb,0x07,0x28,0xb2},{0xee,0x99,0xe2,0x0c,0x25,0xbc}, - {0xf0,0x88,0x95,0x65,0x6e,0xe6},{0xf2,0x8b,0x9c,0x6e,0x63,0xe8}, - {0xf4,0x8e,0x87,0x73,0x74,0xfa},{0xf6,0x8d,0x8e,0x78,0x79,0xf4}, - {0xf8,0x84,0xb1,0x49,0x5a,0xde},{0xfa,0x87,0xb8,0x42,0x57,0xd0}, - {0xfc,0x82,0xa3,0x5f,0x40,0xc2},{0xfe,0x81,0xaa,0x54,0x4d,0xcc}, - {0x1b,0x9b,0xec,0xf7,0xda,0x41},{0x19,0x98,0xe5,0xfc,0xd7,0x4f}, - {0x1f,0x9d,0xfe,0xe1,0xc0,0x5d},{0x1d,0x9e,0xf7,0xea,0xcd,0x53}, - {0x13,0x97,0xc8,0xdb,0xee,0x79},{0x11,0x94,0xc1,0xd0,0xe3,0x77}, - {0x17,0x91,0xda,0xcd,0xf4,0x65},{0x15,0x92,0xd3,0xc6,0xf9,0x6b}, - {0x0b,0x83,0xa4,0xaf,0xb2,0x31},{0x09,0x80,0xad,0xa4,0xbf,0x3f}, - {0x0f,0x85,0xb6,0xb9,0xa8,0x2d},{0x0d,0x86,0xbf,0xb2,0xa5,0x23}, - {0x03,0x8f,0x80,0x83,0x86,0x09},{0x01,0x8c,0x89,0x88,0x8b,0x07}, - {0x07,0x89,0x92,0x95,0x9c,0x15},{0x05,0x8a,0x9b,0x9e,0x91,0x1b}, - {0x3b,0xab,0x7c,0x47,0x0a,0xa1},{0x39,0xa8,0x75,0x4c,0x07,0xaf}, - {0x3f,0xad,0x6e,0x51,0x10,0xbd},{0x3d,0xae,0x67,0x5a,0x1d,0xb3}, - {0x33,0xa7,0x58,0x6b,0x3e,0x99},{0x31,0xa4,0x51,0x60,0x33,0x97}, - {0x37,0xa1,0x4a,0x7d,0x24,0x85},{0x35,0xa2,0x43,0x76,0x29,0x8b}, - {0x2b,0xb3,0x34,0x1f,0x62,0xd1},{0x29,0xb0,0x3d,0x14,0x6f,0xdf}, - {0x2f,0xb5,0x26,0x09,0x78,0xcd},{0x2d,0xb6,0x2f,0x02,0x75,0xc3}, - {0x23,0xbf,0x10,0x33,0x56,0xe9},{0x21,0xbc,0x19,0x38,0x5b,0xe7}, - {0x27,0xb9,0x02,0x25,0x4c,0xf5},{0x25,0xba,0x0b,0x2e,0x41,0xfb}, - {0x5b,0xfb,0xd7,0x8c,0x61,0x9a},{0x59,0xf8,0xde,0x87,0x6c,0x94}, - {0x5f,0xfd,0xc5,0x9a,0x7b,0x86},{0x5d,0xfe,0xcc,0x91,0x76,0x88}, - {0x53,0xf7,0xf3,0xa0,0x55,0xa2},{0x51,0xf4,0xfa,0xab,0x58,0xac}, - {0x57,0xf1,0xe1,0xb6,0x4f,0xbe},{0x55,0xf2,0xe8,0xbd,0x42,0xb0}, - {0x4b,0xe3,0x9f,0xd4,0x09,0xea},{0x49,0xe0,0x96,0xdf,0x04,0xe4}, - {0x4f,0xe5,0x8d,0xc2,0x13,0xf6},{0x4d,0xe6,0x84,0xc9,0x1e,0xf8}, - {0x43,0xef,0xbb,0xf8,0x3d,0xd2},{0x41,0xec,0xb2,0xf3,0x30,0xdc}, - {0x47,0xe9,0xa9,0xee,0x27,0xce},{0x45,0xea,0xa0,0xe5,0x2a,0xc0}, - {0x7b,0xcb,0x47,0x3c,0xb1,0x7a},{0x79,0xc8,0x4e,0x37,0xbc,0x74}, - {0x7f,0xcd,0x55,0x2a,0xab,0x66},{0x7d,0xce,0x5c,0x21,0xa6,0x68}, - {0x73,0xc7,0x63,0x10,0x85,0x42},{0x71,0xc4,0x6a,0x1b,0x88,0x4c}, - {0x77,0xc1,0x71,0x06,0x9f,0x5e},{0x75,0xc2,0x78,0x0d,0x92,0x50}, - {0x6b,0xd3,0x0f,0x64,0xd9,0x0a},{0x69,0xd0,0x06,0x6f,0xd4,0x04}, - {0x6f,0xd5,0x1d,0x72,0xc3,0x16},{0x6d,0xd6,0x14,0x79,0xce,0x18}, - {0x63,0xdf,0x2b,0x48,0xed,0x32},{0x61,0xdc,0x22,0x43,0xe0,0x3c}, - {0x67,0xd9,0x39,0x5e,0xf7,0x2e},{0x65,0xda,0x30,0x55,0xfa,0x20}, - {0x9b,0x5b,0x9a,0x01,0xb7,0xec},{0x99,0x58,0x93,0x0a,0xba,0xe2}, - {0x9f,0x5d,0x88,0x17,0xad,0xf0},{0x9d,0x5e,0x81,0x1c,0xa0,0xfe}, - {0x93,0x57,0xbe,0x2d,0x83,0xd4},{0x91,0x54,0xb7,0x26,0x8e,0xda}, - {0x97,0x51,0xac,0x3b,0x99,0xc8},{0x95,0x52,0xa5,0x30,0x94,0xc6}, - {0x8b,0x43,0xd2,0x59,0xdf,0x9c},{0x89,0x40,0xdb,0x52,0xd2,0x92}, - {0x8f,0x45,0xc0,0x4f,0xc5,0x80},{0x8d,0x46,0xc9,0x44,0xc8,0x8e}, - {0x83,0x4f,0xf6,0x75,0xeb,0xa4},{0x81,0x4c,0xff,0x7e,0xe6,0xaa}, - {0x87,0x49,0xe4,0x63,0xf1,0xb8},{0x85,0x4a,0xed,0x68,0xfc,0xb6}, - {0xbb,0x6b,0x0a,0xb1,0x67,0x0c},{0xb9,0x68,0x03,0xba,0x6a,0x02}, - {0xbf,0x6d,0x18,0xa7,0x7d,0x10},{0xbd,0x6e,0x11,0xac,0x70,0x1e}, - {0xb3,0x67,0x2e,0x9d,0x53,0x34},{0xb1,0x64,0x27,0x96,0x5e,0x3a}, - {0xb7,0x61,0x3c,0x8b,0x49,0x28},{0xb5,0x62,0x35,0x80,0x44,0x26}, - {0xab,0x73,0x42,0xe9,0x0f,0x7c},{0xa9,0x70,0x4b,0xe2,0x02,0x72}, - {0xaf,0x75,0x50,0xff,0x15,0x60},{0xad,0x76,0x59,0xf4,0x18,0x6e}, - {0xa3,0x7f,0x66,0xc5,0x3b,0x44},{0xa1,0x7c,0x6f,0xce,0x36,0x4a}, - {0xa7,0x79,0x74,0xd3,0x21,0x58},{0xa5,0x7a,0x7d,0xd8,0x2c,0x56}, - {0xdb,0x3b,0xa1,0x7a,0x0c,0x37},{0xd9,0x38,0xa8,0x71,0x01,0x39}, - {0xdf,0x3d,0xb3,0x6c,0x16,0x2b},{0xdd,0x3e,0xba,0x67,0x1b,0x25}, - {0xd3,0x37,0x85,0x56,0x38,0x0f},{0xd1,0x34,0x8c,0x5d,0x35,0x01}, - {0xd7,0x31,0x97,0x40,0x22,0x13},{0xd5,0x32,0x9e,0x4b,0x2f,0x1d}, - {0xcb,0x23,0xe9,0x22,0x64,0x47},{0xc9,0x20,0xe0,0x29,0x69,0x49}, - {0xcf,0x25,0xfb,0x34,0x7e,0x5b},{0xcd,0x26,0xf2,0x3f,0x73,0x55}, - {0xc3,0x2f,0xcd,0x0e,0x50,0x7f},{0xc1,0x2c,0xc4,0x05,0x5d,0x71}, - {0xc7,0x29,0xdf,0x18,0x4a,0x63},{0xc5,0x2a,0xd6,0x13,0x47,0x6d}, - {0xfb,0x0b,0x31,0xca,0xdc,0xd7},{0xf9,0x08,0x38,0xc1,0xd1,0xd9}, - {0xff,0x0d,0x23,0xdc,0xc6,0xcb},{0xfd,0x0e,0x2a,0xd7,0xcb,0xc5}, - {0xf3,0x07,0x15,0xe6,0xe8,0xef},{0xf1,0x04,0x1c,0xed,0xe5,0xe1}, - {0xf7,0x01,0x07,0xf0,0xf2,0xf3},{0xf5,0x02,0x0e,0xfb,0xff,0xfd}, - {0xeb,0x13,0x79,0x92,0xb4,0xa7},{0xe9,0x10,0x70,0x99,0xb9,0xa9}, - {0xef,0x15,0x6b,0x84,0xae,0xbb},{0xed,0x16,0x62,0x8f,0xa3,0xb5}, - {0xe3,0x1f,0x5d,0xbe,0x80,0x9f},{0xe1,0x1c,0x54,0xb5,0x8d,0x91}, - {0xe7,0x19,0x4f,0xa8,0x9a,0x83},{0xe5,0x1a,0x46,0xa3,0x97,0x8d} -}; - + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x02, 0x03, 0x09, 0x0b, 0x0d, 0x0e}, {0x04, 0x06, 0x12, 0x16, 0x1a, 0x1c}, + {0x06, 0x05, 0x1b, 0x1d, 0x17, 0x12}, {0x08, 0x0c, 0x24, 0x2c, 0x34, 0x38}, {0x0a, 0x0f, 0x2d, 0x27, 0x39, 0x36}, + {0x0c, 0x0a, 0x36, 0x3a, 0x2e, 0x24}, {0x0e, 0x09, 0x3f, 0x31, 0x23, 0x2a}, {0x10, 0x18, 0x48, 0x58, 0x68, 0x70}, + {0x12, 0x1b, 0x41, 0x53, 0x65, 0x7e}, {0x14, 0x1e, 0x5a, 0x4e, 0x72, 0x6c}, {0x16, 0x1d, 0x53, 0x45, 0x7f, 0x62}, + {0x18, 0x14, 0x6c, 0x74, 0x5c, 0x48}, {0x1a, 0x17, 0x65, 0x7f, 0x51, 0x46}, {0x1c, 0x12, 0x7e, 0x62, 0x46, 0x54}, + {0x1e, 0x11, 0x77, 0x69, 0x4b, 0x5a}, {0x20, 0x30, 0x90, 0xb0, 0xd0, 0xe0}, {0x22, 0x33, 0x99, 0xbb, 0xdd, 0xee}, + {0x24, 0x36, 0x82, 0xa6, 0xca, 0xfc}, {0x26, 0x35, 0x8b, 0xad, 0xc7, 0xf2}, {0x28, 0x3c, 0xb4, 0x9c, 0xe4, 0xd8}, + {0x2a, 0x3f, 0xbd, 0x97, 0xe9, 0xd6}, {0x2c, 0x3a, 0xa6, 0x8a, 0xfe, 0xc4}, {0x2e, 0x39, 0xaf, 0x81, 0xf3, 0xca}, + {0x30, 0x28, 0xd8, 0xe8, 0xb8, 0x90}, {0x32, 0x2b, 0xd1, 0xe3, 0xb5, 0x9e}, {0x34, 0x2e, 0xca, 0xfe, 0xa2, 0x8c}, + {0x36, 0x2d, 0xc3, 0xf5, 0xaf, 0x82}, {0x38, 0x24, 0xfc, 0xc4, 0x8c, 0xa8}, {0x3a, 0x27, 0xf5, 0xcf, 0x81, 0xa6}, + {0x3c, 0x22, 0xee, 0xd2, 0x96, 0xb4}, {0x3e, 0x21, 0xe7, 0xd9, 0x9b, 0xba}, {0x40, 0x60, 0x3b, 0x7b, 0xbb, 0xdb}, + {0x42, 0x63, 0x32, 0x70, 0xb6, 0xd5}, {0x44, 0x66, 0x29, 0x6d, 0xa1, 0xc7}, {0x46, 0x65, 0x20, 0x66, 0xac, 0xc9}, + {0x48, 0x6c, 0x1f, 0x57, 0x8f, 0xe3}, {0x4a, 0x6f, 0x16, 0x5c, 0x82, 0xed}, {0x4c, 0x6a, 0x0d, 0x41, 0x95, 0xff}, + {0x4e, 0x69, 0x04, 0x4a, 0x98, 0xf1}, {0x50, 0x78, 0x73, 0x23, 0xd3, 0xab}, {0x52, 0x7b, 0x7a, 0x28, 0xde, 0xa5}, + {0x54, 0x7e, 0x61, 0x35, 0xc9, 0xb7}, {0x56, 0x7d, 0x68, 0x3e, 0xc4, 0xb9}, {0x58, 0x74, 0x57, 0x0f, 0xe7, 0x93}, + {0x5a, 0x77, 0x5e, 0x04, 0xea, 0x9d}, {0x5c, 0x72, 0x45, 0x19, 0xfd, 0x8f}, {0x5e, 0x71, 0x4c, 0x12, 0xf0, 0x81}, + {0x60, 0x50, 0xab, 0xcb, 0x6b, 0x3b}, {0x62, 0x53, 0xa2, 0xc0, 0x66, 0x35}, {0x64, 0x56, 0xb9, 0xdd, 0x71, 0x27}, + {0x66, 0x55, 0xb0, 0xd6, 0x7c, 0x29}, {0x68, 0x5c, 0x8f, 0xe7, 0x5f, 0x03}, {0x6a, 0x5f, 0x86, 0xec, 0x52, 0x0d}, + {0x6c, 0x5a, 0x9d, 0xf1, 0x45, 0x1f}, {0x6e, 0x59, 0x94, 0xfa, 0x48, 0x11}, {0x70, 0x48, 0xe3, 0x93, 0x03, 0x4b}, + {0x72, 0x4b, 0xea, 0x98, 0x0e, 0x45}, {0x74, 0x4e, 0xf1, 0x85, 0x19, 0x57}, {0x76, 0x4d, 0xf8, 0x8e, 0x14, 0x59}, + {0x78, 0x44, 0xc7, 0xbf, 0x37, 0x73}, {0x7a, 0x47, 0xce, 0xb4, 0x3a, 0x7d}, {0x7c, 0x42, 0xd5, 0xa9, 0x2d, 0x6f}, + {0x7e, 0x41, 0xdc, 0xa2, 0x20, 0x61}, {0x80, 0xc0, 0x76, 0xf6, 0x6d, 0xad}, {0x82, 0xc3, 0x7f, 0xfd, 0x60, 0xa3}, + {0x84, 0xc6, 0x64, 0xe0, 0x77, 0xb1}, {0x86, 0xc5, 0x6d, 0xeb, 0x7a, 0xbf}, {0x88, 0xcc, 0x52, 0xda, 0x59, 0x95}, + {0x8a, 0xcf, 0x5b, 0xd1, 0x54, 0x9b}, {0x8c, 0xca, 0x40, 0xcc, 0x43, 0x89}, {0x8e, 0xc9, 0x49, 0xc7, 0x4e, 0x87}, + {0x90, 0xd8, 0x3e, 0xae, 0x05, 0xdd}, {0x92, 0xdb, 0x37, 0xa5, 0x08, 0xd3}, {0x94, 0xde, 0x2c, 0xb8, 0x1f, 0xc1}, + {0x96, 0xdd, 0x25, 0xb3, 0x12, 0xcf}, {0x98, 0xd4, 0x1a, 0x82, 0x31, 0xe5}, {0x9a, 0xd7, 0x13, 0x89, 0x3c, 0xeb}, + {0x9c, 0xd2, 0x08, 0x94, 0x2b, 0xf9}, {0x9e, 0xd1, 0x01, 0x9f, 0x26, 0xf7}, {0xa0, 0xf0, 0xe6, 0x46, 0xbd, 0x4d}, + {0xa2, 0xf3, 0xef, 0x4d, 0xb0, 0x43}, {0xa4, 0xf6, 0xf4, 0x50, 0xa7, 0x51}, {0xa6, 0xf5, 0xfd, 0x5b, 0xaa, 0x5f}, + {0xa8, 0xfc, 0xc2, 0x6a, 0x89, 0x75}, {0xaa, 0xff, 0xcb, 0x61, 0x84, 0x7b}, {0xac, 0xfa, 0xd0, 0x7c, 0x93, 0x69}, + {0xae, 0xf9, 0xd9, 0x77, 0x9e, 0x67}, {0xb0, 0xe8, 0xae, 0x1e, 0xd5, 0x3d}, {0xb2, 0xeb, 0xa7, 0x15, 0xd8, 0x33}, + {0xb4, 0xee, 0xbc, 0x08, 0xcf, 0x21}, {0xb6, 0xed, 0xb5, 0x03, 0xc2, 0x2f}, {0xb8, 0xe4, 0x8a, 0x32, 0xe1, 0x05}, + {0xba, 0xe7, 0x83, 0x39, 0xec, 0x0b}, {0xbc, 0xe2, 0x98, 0x24, 0xfb, 0x19}, {0xbe, 0xe1, 0x91, 0x2f, 0xf6, 0x17}, + {0xc0, 0xa0, 0x4d, 0x8d, 0xd6, 0x76}, {0xc2, 0xa3, 0x44, 0x86, 0xdb, 0x78}, {0xc4, 0xa6, 0x5f, 0x9b, 0xcc, 0x6a}, + {0xc6, 0xa5, 0x56, 0x90, 0xc1, 0x64}, {0xc8, 0xac, 0x69, 0xa1, 0xe2, 0x4e}, {0xca, 0xaf, 0x60, 0xaa, 0xef, 0x40}, + {0xcc, 0xaa, 0x7b, 0xb7, 0xf8, 0x52}, {0xce, 0xa9, 0x72, 0xbc, 0xf5, 0x5c}, {0xd0, 0xb8, 0x05, 0xd5, 0xbe, 0x06}, + {0xd2, 0xbb, 0x0c, 0xde, 0xb3, 0x08}, {0xd4, 0xbe, 0x17, 0xc3, 0xa4, 0x1a}, {0xd6, 0xbd, 0x1e, 0xc8, 0xa9, 0x14}, + {0xd8, 0xb4, 0x21, 0xf9, 0x8a, 0x3e}, {0xda, 0xb7, 0x28, 0xf2, 0x87, 0x30}, {0xdc, 0xb2, 0x33, 0xef, 0x90, 0x22}, + {0xde, 0xb1, 0x3a, 0xe4, 0x9d, 0x2c}, {0xe0, 0x90, 0xdd, 0x3d, 0x06, 0x96}, {0xe2, 0x93, 0xd4, 0x36, 0x0b, 0x98}, + {0xe4, 0x96, 0xcf, 0x2b, 0x1c, 0x8a}, {0xe6, 0x95, 0xc6, 0x20, 0x11, 0x84}, {0xe8, 0x9c, 0xf9, 0x11, 0x32, 0xae}, + {0xea, 0x9f, 0xf0, 0x1a, 0x3f, 0xa0}, {0xec, 0x9a, 0xeb, 0x07, 0x28, 0xb2}, {0xee, 0x99, 0xe2, 0x0c, 0x25, 0xbc}, + {0xf0, 0x88, 0x95, 0x65, 0x6e, 0xe6}, {0xf2, 0x8b, 0x9c, 0x6e, 0x63, 0xe8}, {0xf4, 0x8e, 0x87, 0x73, 0x74, 0xfa}, + {0xf6, 0x8d, 0x8e, 0x78, 0x79, 0xf4}, {0xf8, 0x84, 0xb1, 0x49, 0x5a, 0xde}, {0xfa, 0x87, 0xb8, 0x42, 0x57, 0xd0}, + {0xfc, 0x82, 0xa3, 0x5f, 0x40, 0xc2}, {0xfe, 0x81, 0xaa, 0x54, 0x4d, 0xcc}, {0x1b, 0x9b, 0xec, 0xf7, 0xda, 0x41}, + {0x19, 0x98, 0xe5, 0xfc, 0xd7, 0x4f}, {0x1f, 0x9d, 0xfe, 0xe1, 0xc0, 0x5d}, {0x1d, 0x9e, 0xf7, 0xea, 0xcd, 0x53}, + {0x13, 0x97, 0xc8, 0xdb, 0xee, 0x79}, {0x11, 0x94, 0xc1, 0xd0, 0xe3, 0x77}, {0x17, 0x91, 0xda, 0xcd, 0xf4, 0x65}, + {0x15, 0x92, 0xd3, 0xc6, 0xf9, 0x6b}, {0x0b, 0x83, 0xa4, 0xaf, 0xb2, 0x31}, {0x09, 0x80, 0xad, 0xa4, 0xbf, 0x3f}, + {0x0f, 0x85, 0xb6, 0xb9, 0xa8, 0x2d}, {0x0d, 0x86, 0xbf, 0xb2, 0xa5, 0x23}, {0x03, 0x8f, 0x80, 0x83, 0x86, 0x09}, + {0x01, 0x8c, 0x89, 0x88, 0x8b, 0x07}, {0x07, 0x89, 0x92, 0x95, 0x9c, 0x15}, {0x05, 0x8a, 0x9b, 0x9e, 0x91, 0x1b}, + {0x3b, 0xab, 0x7c, 0x47, 0x0a, 0xa1}, {0x39, 0xa8, 0x75, 0x4c, 0x07, 0xaf}, {0x3f, 0xad, 0x6e, 0x51, 0x10, 0xbd}, + {0x3d, 0xae, 0x67, 0x5a, 0x1d, 0xb3}, {0x33, 0xa7, 0x58, 0x6b, 0x3e, 0x99}, {0x31, 0xa4, 0x51, 0x60, 0x33, 0x97}, + {0x37, 0xa1, 0x4a, 0x7d, 0x24, 0x85}, {0x35, 0xa2, 0x43, 0x76, 0x29, 0x8b}, {0x2b, 0xb3, 0x34, 0x1f, 0x62, 0xd1}, + {0x29, 0xb0, 0x3d, 0x14, 0x6f, 0xdf}, {0x2f, 0xb5, 0x26, 0x09, 0x78, 0xcd}, {0x2d, 0xb6, 0x2f, 0x02, 0x75, 0xc3}, + {0x23, 0xbf, 0x10, 0x33, 0x56, 0xe9}, {0x21, 0xbc, 0x19, 0x38, 0x5b, 0xe7}, {0x27, 0xb9, 0x02, 0x25, 0x4c, 0xf5}, + {0x25, 0xba, 0x0b, 0x2e, 0x41, 0xfb}, {0x5b, 0xfb, 0xd7, 0x8c, 0x61, 0x9a}, {0x59, 0xf8, 0xde, 0x87, 0x6c, 0x94}, + {0x5f, 0xfd, 0xc5, 0x9a, 0x7b, 0x86}, {0x5d, 0xfe, 0xcc, 0x91, 0x76, 0x88}, {0x53, 0xf7, 0xf3, 0xa0, 0x55, 0xa2}, + {0x51, 0xf4, 0xfa, 0xab, 0x58, 0xac}, {0x57, 0xf1, 0xe1, 0xb6, 0x4f, 0xbe}, {0x55, 0xf2, 0xe8, 0xbd, 0x42, 0xb0}, + {0x4b, 0xe3, 0x9f, 0xd4, 0x09, 0xea}, {0x49, 0xe0, 0x96, 0xdf, 0x04, 0xe4}, {0x4f, 0xe5, 0x8d, 0xc2, 0x13, 0xf6}, + {0x4d, 0xe6, 0x84, 0xc9, 0x1e, 0xf8}, {0x43, 0xef, 0xbb, 0xf8, 0x3d, 0xd2}, {0x41, 0xec, 0xb2, 0xf3, 0x30, 0xdc}, + {0x47, 0xe9, 0xa9, 0xee, 0x27, 0xce}, {0x45, 0xea, 0xa0, 0xe5, 0x2a, 0xc0}, {0x7b, 0xcb, 0x47, 0x3c, 0xb1, 0x7a}, + {0x79, 0xc8, 0x4e, 0x37, 0xbc, 0x74}, {0x7f, 0xcd, 0x55, 0x2a, 0xab, 0x66}, {0x7d, 0xce, 0x5c, 0x21, 0xa6, 0x68}, + {0x73, 0xc7, 0x63, 0x10, 0x85, 0x42}, {0x71, 0xc4, 0x6a, 0x1b, 0x88, 0x4c}, {0x77, 0xc1, 0x71, 0x06, 0x9f, 0x5e}, + {0x75, 0xc2, 0x78, 0x0d, 0x92, 0x50}, {0x6b, 0xd3, 0x0f, 0x64, 0xd9, 0x0a}, {0x69, 0xd0, 0x06, 0x6f, 0xd4, 0x04}, + {0x6f, 0xd5, 0x1d, 0x72, 0xc3, 0x16}, {0x6d, 0xd6, 0x14, 0x79, 0xce, 0x18}, {0x63, 0xdf, 0x2b, 0x48, 0xed, 0x32}, + {0x61, 0xdc, 0x22, 0x43, 0xe0, 0x3c}, {0x67, 0xd9, 0x39, 0x5e, 0xf7, 0x2e}, {0x65, 0xda, 0x30, 0x55, 0xfa, 0x20}, + {0x9b, 0x5b, 0x9a, 0x01, 0xb7, 0xec}, {0x99, 0x58, 0x93, 0x0a, 0xba, 0xe2}, {0x9f, 0x5d, 0x88, 0x17, 0xad, 0xf0}, + {0x9d, 0x5e, 0x81, 0x1c, 0xa0, 0xfe}, {0x93, 0x57, 0xbe, 0x2d, 0x83, 0xd4}, {0x91, 0x54, 0xb7, 0x26, 0x8e, 0xda}, + {0x97, 0x51, 0xac, 0x3b, 0x99, 0xc8}, {0x95, 0x52, 0xa5, 0x30, 0x94, 0xc6}, {0x8b, 0x43, 0xd2, 0x59, 0xdf, 0x9c}, + {0x89, 0x40, 0xdb, 0x52, 0xd2, 0x92}, {0x8f, 0x45, 0xc0, 0x4f, 0xc5, 0x80}, {0x8d, 0x46, 0xc9, 0x44, 0xc8, 0x8e}, + {0x83, 0x4f, 0xf6, 0x75, 0xeb, 0xa4}, {0x81, 0x4c, 0xff, 0x7e, 0xe6, 0xaa}, {0x87, 0x49, 0xe4, 0x63, 0xf1, 0xb8}, + {0x85, 0x4a, 0xed, 0x68, 0xfc, 0xb6}, {0xbb, 0x6b, 0x0a, 0xb1, 0x67, 0x0c}, {0xb9, 0x68, 0x03, 0xba, 0x6a, 0x02}, + {0xbf, 0x6d, 0x18, 0xa7, 0x7d, 0x10}, {0xbd, 0x6e, 0x11, 0xac, 0x70, 0x1e}, {0xb3, 0x67, 0x2e, 0x9d, 0x53, 0x34}, + {0xb1, 0x64, 0x27, 0x96, 0x5e, 0x3a}, {0xb7, 0x61, 0x3c, 0x8b, 0x49, 0x28}, {0xb5, 0x62, 0x35, 0x80, 0x44, 0x26}, + {0xab, 0x73, 0x42, 0xe9, 0x0f, 0x7c}, {0xa9, 0x70, 0x4b, 0xe2, 0x02, 0x72}, {0xaf, 0x75, 0x50, 0xff, 0x15, 0x60}, + {0xad, 0x76, 0x59, 0xf4, 0x18, 0x6e}, {0xa3, 0x7f, 0x66, 0xc5, 0x3b, 0x44}, {0xa1, 0x7c, 0x6f, 0xce, 0x36, 0x4a}, + {0xa7, 0x79, 0x74, 0xd3, 0x21, 0x58}, {0xa5, 0x7a, 0x7d, 0xd8, 0x2c, 0x56}, {0xdb, 0x3b, 0xa1, 0x7a, 0x0c, 0x37}, + {0xd9, 0x38, 0xa8, 0x71, 0x01, 0x39}, {0xdf, 0x3d, 0xb3, 0x6c, 0x16, 0x2b}, {0xdd, 0x3e, 0xba, 0x67, 0x1b, 0x25}, + {0xd3, 0x37, 0x85, 0x56, 0x38, 0x0f}, {0xd1, 0x34, 0x8c, 0x5d, 0x35, 0x01}, {0xd7, 0x31, 0x97, 0x40, 0x22, 0x13}, + {0xd5, 0x32, 0x9e, 0x4b, 0x2f, 0x1d}, {0xcb, 0x23, 0xe9, 0x22, 0x64, 0x47}, {0xc9, 0x20, 0xe0, 0x29, 0x69, 0x49}, + {0xcf, 0x25, 0xfb, 0x34, 0x7e, 0x5b}, {0xcd, 0x26, 0xf2, 0x3f, 0x73, 0x55}, {0xc3, 0x2f, 0xcd, 0x0e, 0x50, 0x7f}, + {0xc1, 0x2c, 0xc4, 0x05, 0x5d, 0x71}, {0xc7, 0x29, 0xdf, 0x18, 0x4a, 0x63}, {0xc5, 0x2a, 0xd6, 0x13, 0x47, 0x6d}, + {0xfb, 0x0b, 0x31, 0xca, 0xdc, 0xd7}, {0xf9, 0x08, 0x38, 0xc1, 0xd1, 0xd9}, {0xff, 0x0d, 0x23, 0xdc, 0xc6, 0xcb}, + {0xfd, 0x0e, 0x2a, 0xd7, 0xcb, 0xc5}, {0xf3, 0x07, 0x15, 0xe6, 0xe8, 0xef}, {0xf1, 0x04, 0x1c, 0xed, 0xe5, 0xe1}, + {0xf7, 0x01, 0x07, 0xf0, 0xf2, 0xf3}, {0xf5, 0x02, 0x0e, 0xfb, 0xff, 0xfd}, {0xeb, 0x13, 0x79, 0x92, 0xb4, 0xa7}, + {0xe9, 0x10, 0x70, 0x99, 0xb9, 0xa9}, {0xef, 0x15, 0x6b, 0x84, 0xae, 0xbb}, {0xed, 0x16, 0x62, 0x8f, 0xa3, 0xb5}, + {0xe3, 0x1f, 0x5d, 0xbe, 0x80, 0x9f}, {0xe1, 0x1c, 0x54, 0xb5, 0x8d, 0x91}, {0xe7, 0x19, 0x4f, 0xa8, 0x9a, 0x83}, + {0xe5, 0x1a, 0x46, 0xa3, 0x97, 0x8d}}; + /*********************** FUNCTION DEFINITIONS ***********************/ // XORs the in and out buffers, storing the result in out. Length is in bytes. -void xor_buf(const BYTE in[], BYTE out[], size_t len) -{ - size_t idx; - - for (idx = 0; idx < len; idx++) - out[idx] ^= in[idx]; +void +xor_buf(const BYTE in[], BYTE out[], size_t len) { + size_t idx; + + for (idx = 0; idx < len; idx++) + out[idx] ^= in[idx]; } - + /******************* * AES - CBC *******************/ -int aes_encrypt_cbc(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) -{ - BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; - int blocks, idx; - - if (in_len % AES_BLOCK_SIZE != 0) - return(FALSE); - - blocks = in_len / AES_BLOCK_SIZE; - - memcpy(iv_buf, iv, AES_BLOCK_SIZE); - - for (idx = 0; idx < blocks; idx++) { - memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); - xor_buf(iv_buf, buf_in, AES_BLOCK_SIZE); - aes_encrypt(buf_in, buf_out, key, keysize); - memcpy(&out[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); - memcpy(iv_buf, buf_out, AES_BLOCK_SIZE); - } - - return(TRUE); +int +aes_encrypt_cbc(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) { + BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; + int blocks, idx; + + if (in_len % AES_BLOCK_SIZE != 0) + return (FALSE); + + blocks = in_len / AES_BLOCK_SIZE; + + memcpy(iv_buf, iv, AES_BLOCK_SIZE); + + for (idx = 0; idx < blocks; idx++) { + memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); + xor_buf(iv_buf, buf_in, AES_BLOCK_SIZE); + aes_encrypt(buf_in, buf_out, key, keysize); + memcpy(&out[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); + memcpy(iv_buf, buf_out, AES_BLOCK_SIZE); + } + + return (TRUE); } - -int aes_encrypt_cbc_mac(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) -{ - BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; - int blocks, idx; - - if (in_len % AES_BLOCK_SIZE != 0) - return(FALSE); - - blocks = in_len / AES_BLOCK_SIZE; - - memcpy(iv_buf, iv, AES_BLOCK_SIZE); - - for (idx = 0; idx < blocks; idx++) { - memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); - xor_buf(iv_buf, buf_in, AES_BLOCK_SIZE); - aes_encrypt(buf_in, buf_out, key, keysize); - memcpy(iv_buf, buf_out, AES_BLOCK_SIZE); - // Do not output all encrypted blocks. - } - - memcpy(out, buf_out, AES_BLOCK_SIZE); // Only output the last block. - - return(TRUE); + +int +aes_encrypt_cbc_mac(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) { + BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; + int blocks, idx; + + if (in_len % AES_BLOCK_SIZE != 0) + return (FALSE); + + blocks = in_len / AES_BLOCK_SIZE; + + memcpy(iv_buf, iv, AES_BLOCK_SIZE); + + for (idx = 0; idx < blocks; idx++) { + memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); + xor_buf(iv_buf, buf_in, AES_BLOCK_SIZE); + aes_encrypt(buf_in, buf_out, key, keysize); + memcpy(iv_buf, buf_out, AES_BLOCK_SIZE); + // Do not output all encrypted blocks. + } + + memcpy(out, buf_out, AES_BLOCK_SIZE); // Only output the last block. + + return (TRUE); } - -int aes_decrypt_cbc(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) -{ - BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; - int blocks, idx; - - if (in_len % AES_BLOCK_SIZE != 0) - return(FALSE); - - blocks = in_len / AES_BLOCK_SIZE; - - memcpy(iv_buf, iv, AES_BLOCK_SIZE); - - for (idx = 0; idx < blocks; idx++) { - memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); - aes_decrypt(buf_in, buf_out, key, keysize); - xor_buf(iv_buf, buf_out, AES_BLOCK_SIZE); - memcpy(&out[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); - memcpy(iv_buf, buf_in, AES_BLOCK_SIZE); - } - - return(TRUE); + +int +aes_decrypt_cbc(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) { + BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; + int blocks, idx; + + if (in_len % AES_BLOCK_SIZE != 0) + return (FALSE); + + blocks = in_len / AES_BLOCK_SIZE; + + memcpy(iv_buf, iv, AES_BLOCK_SIZE); + + for (idx = 0; idx < blocks; idx++) { + memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); + aes_decrypt(buf_in, buf_out, key, keysize); + xor_buf(iv_buf, buf_out, AES_BLOCK_SIZE); + memcpy(&out[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); + memcpy(iv_buf, buf_in, AES_BLOCK_SIZE); + } + + return (TRUE); } - + /******************* * AES - CTR *******************/ -void increment_iv(BYTE iv[], int counter_size) -{ - int idx; - - // Use counter_size bytes at the end of the IV as the big-endian integer to increment. - for (idx = AES_BLOCK_SIZE - 1; idx >= AES_BLOCK_SIZE - counter_size; idx--) { - iv[idx]++; - if (iv[idx] != 0 || idx == AES_BLOCK_SIZE - counter_size) - break; - } +void +increment_iv(BYTE iv[], int counter_size) { + int idx; + + // Use counter_size bytes at the end of the IV as the big-endian integer to increment. + for (idx = AES_BLOCK_SIZE - 1; idx >= AES_BLOCK_SIZE - counter_size; idx--) { + iv[idx]++; + if (iv[idx] != 0 || idx == AES_BLOCK_SIZE - counter_size) + break; + } } - + // Performs the encryption in-place, the input and output buffers may be the same. // Input may be an arbitrary length (in bytes). -void aes_encrypt_ctr(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) -{ - size_t idx = 0, last_block_length; - BYTE iv_buf[AES_BLOCK_SIZE], out_buf[AES_BLOCK_SIZE]; - - if (in != out) - memcpy(out, in, in_len); - - memcpy(iv_buf, iv, AES_BLOCK_SIZE); - last_block_length = in_len - AES_BLOCK_SIZE; - - if (in_len > AES_BLOCK_SIZE) { - for (idx = 0; idx < last_block_length; idx += AES_BLOCK_SIZE) { - aes_encrypt(iv_buf, out_buf, key, keysize); - xor_buf(out_buf, &out[idx], AES_BLOCK_SIZE); - increment_iv(iv_buf, AES_BLOCK_SIZE); +void +aes_encrypt_ctr(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) { + size_t idx = 0, last_block_length; + BYTE iv_buf[AES_BLOCK_SIZE], out_buf[AES_BLOCK_SIZE]; + + if (in != out) + memcpy(out, in, in_len); + + memcpy(iv_buf, iv, AES_BLOCK_SIZE); + last_block_length = in_len - AES_BLOCK_SIZE; + + if (in_len > AES_BLOCK_SIZE) { + for (idx = 0; idx < last_block_length; idx += AES_BLOCK_SIZE) { + aes_encrypt(iv_buf, out_buf, key, keysize); + xor_buf(out_buf, &out[idx], AES_BLOCK_SIZE); + increment_iv(iv_buf, AES_BLOCK_SIZE); + } } - } - - aes_encrypt(iv_buf, out_buf, key, keysize); - xor_buf(out_buf, &out[idx], in_len - idx); // Use the Most Significant bytes. + + aes_encrypt(iv_buf, out_buf, key, keysize); + xor_buf(out_buf, &out[idx], in_len - idx); // Use the Most Significant bytes. } - -void aes_decrypt_ctr(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) -{ - // CTR encryption is its own inverse function. - aes_encrypt_ctr(in, in_len, out, key, keysize, iv); + +void +aes_decrypt_ctr(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) { + // CTR encryption is its own inverse function. + aes_encrypt_ctr(in, in_len, out, key, keysize, iv); } - + /******************* * AES - CCM *******************/ // out_len = payload_len + assoc_len -int aes_encrypt_ccm(const BYTE payload[], WORD payload_len, const BYTE assoc[], unsigned short assoc_len, - const BYTE nonce[], unsigned short nonce_len, BYTE out[], WORD *out_len, - WORD mac_len, const BYTE key_str[], int keysize) -{ - BYTE temp_iv[AES_BLOCK_SIZE], counter[AES_BLOCK_SIZE], mac[16], *buf; - int end_of_buf, payload_len_store_size; - WORD key[60]; - - if (mac_len != 4 && mac_len != 6 && mac_len != 8 && mac_len != 10 && - mac_len != 12 && mac_len != 14 && mac_len != 16) - return(FALSE); - - if (nonce_len < 7 || nonce_len > 13) - return(FALSE); - - if (assoc_len > 32768 /* = 2^15 */) - return(FALSE); - - buf = (BYTE*)malloc(payload_len + assoc_len + 48 /*Round both payload and associated data up a block size and add an extra block.*/); - if (! buf) - return(FALSE); - - // Prepare the key for usage. - aes_key_setup(key_str, key, keysize); - - // Format the first block of the formatted data. - payload_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; - ccm_prepare_first_format_blk(buf, assoc_len, payload_len, payload_len_store_size, mac_len, nonce, nonce_len); - end_of_buf = AES_BLOCK_SIZE; - - // Format the Associated Data, aka, assoc[]. - ccm_format_assoc_data(buf, &end_of_buf, assoc, assoc_len); - - // Format the Payload, aka payload[]. - ccm_format_payload_data(buf, &end_of_buf, payload, payload_len); - - // Create the first counter block. - ccm_prepare_first_ctr_blk(counter, nonce, nonce_len, payload_len_store_size); - - // Perform the CBC operation with an IV of zeros on the formatted buffer to calculate the MAC. - memset(temp_iv, 0, AES_BLOCK_SIZE); - aes_encrypt_cbc_mac(buf, end_of_buf, mac, key, keysize, temp_iv); - - // Copy the Payload and MAC to the output buffer. - memcpy(out, payload, payload_len); - memcpy(&out[payload_len], mac, mac_len); - - // Encrypt the Payload with CTR mode with a counter starting at 1. - memcpy(temp_iv, counter, AES_BLOCK_SIZE); - increment_iv(temp_iv, AES_BLOCK_SIZE - 1 - mac_len); // Last argument is the byte size of the counting portion of the counter block. /*BUG?*/ - aes_encrypt_ctr(out, payload_len, out, key, keysize, temp_iv); - - // Encrypt the MAC with CTR mode with a counter starting at 0. - aes_encrypt_ctr(&out[payload_len], mac_len, &out[payload_len], key, keysize, counter); - - free(buf); - *out_len = payload_len + mac_len; - - return(TRUE); -} - -// plaintext_len = ciphertext_len - mac_len -// Needs a flag for whether the MAC matches. -int aes_decrypt_ccm(const BYTE ciphertext[], WORD ciphertext_len, const BYTE assoc[], unsigned short assoc_len, - const BYTE nonce[], unsigned short nonce_len, BYTE plaintext[], WORD *plaintext_len, - WORD mac_len, int *mac_auth, const BYTE key_str[], int keysize) -{ - BYTE temp_iv[AES_BLOCK_SIZE], counter[AES_BLOCK_SIZE], mac[16], mac_buf[16], *buf; - int end_of_buf, plaintext_len_store_size; - WORD key[60]; - - if (ciphertext_len <= mac_len) - return(FALSE); - - buf = (BYTE*)malloc(assoc_len + ciphertext_len /*ciphertext_len = plaintext_len + mac_len*/ + 48); - if (! buf) - return(FALSE); - - // Prepare the key for usage. - aes_key_setup(key_str, key, keysize); - - // Copy the plaintext and MAC to the output buffers. - *plaintext_len = ciphertext_len - mac_len; - plaintext_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; - memcpy(plaintext, ciphertext, *plaintext_len); - memcpy(mac, &ciphertext[*plaintext_len], mac_len); - - // Prepare the first counter block for use in decryption. - ccm_prepare_first_ctr_blk(counter, nonce, nonce_len, plaintext_len_store_size); - - // Decrypt the Payload with CTR mode with a counter starting at 1. - memcpy(temp_iv, counter, AES_BLOCK_SIZE); - increment_iv(temp_iv, AES_BLOCK_SIZE - 1 - mac_len); // (AES_BLOCK_SIZE - 1 - mac_len) is the byte size of the counting portion of the counter block. - aes_decrypt_ctr(plaintext, *plaintext_len, plaintext, key, keysize, temp_iv); - - // Setting mac_auth to NULL disables the authentication check. - if (mac_auth != NULL) { - // Decrypt the MAC with CTR mode with a counter starting at 0. - aes_decrypt_ctr(mac, mac_len, mac, key, keysize, counter); - +int +aes_encrypt_ccm(const BYTE payload[], WORD payload_len, const BYTE assoc[], unsigned short assoc_len, + const BYTE nonce[], unsigned short nonce_len, BYTE out[], WORD *out_len, WORD mac_len, + const BYTE key_str[], int keysize) { + BYTE temp_iv[AES_BLOCK_SIZE], counter[AES_BLOCK_SIZE], mac[16], *buf; + int end_of_buf, payload_len_store_size; + WORD key[60]; + + if (mac_len != 4 && mac_len != 6 && mac_len != 8 && mac_len != 10 && mac_len != 12 && mac_len != 14 && + mac_len != 16) + return (FALSE); + + if (nonce_len < 7 || nonce_len > 13) + return (FALSE); + + if (assoc_len > 32768 /* = 2^15 */) + return (FALSE); + + buf = (BYTE *)malloc(payload_len + assoc_len + + 48 /*Round both payload and associated data up a block size and add an extra block.*/); + if (!buf) + return (FALSE); + + // Prepare the key for usage. + aes_key_setup(key_str, key, keysize); + // Format the first block of the formatted data. - plaintext_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; - ccm_prepare_first_format_blk(buf, assoc_len, *plaintext_len, plaintext_len_store_size, mac_len, nonce, nonce_len); + payload_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; + ccm_prepare_first_format_blk(buf, assoc_len, payload_len, payload_len_store_size, mac_len, nonce, nonce_len); end_of_buf = AES_BLOCK_SIZE; - - // Format the Associated Data into the authentication buffer. + + // Format the Associated Data, aka, assoc[]. ccm_format_assoc_data(buf, &end_of_buf, assoc, assoc_len); - - // Format the Payload into the authentication buffer. - ccm_format_payload_data(buf, &end_of_buf, plaintext, *plaintext_len); - + + // Format the Payload, aka payload[]. + ccm_format_payload_data(buf, &end_of_buf, payload, payload_len); + + // Create the first counter block. + ccm_prepare_first_ctr_blk(counter, nonce, nonce_len, payload_len_store_size); + // Perform the CBC operation with an IV of zeros on the formatted buffer to calculate the MAC. memset(temp_iv, 0, AES_BLOCK_SIZE); - aes_encrypt_cbc_mac(buf, end_of_buf, mac_buf, key, keysize, temp_iv); - - // Compare the calculated MAC against the MAC embedded in the ciphertext to see if they are the same. - if (! memcmp(mac, mac_buf, mac_len)) { - *mac_auth = TRUE; - } - else { - *mac_auth = FALSE; - memset(plaintext, 0, *plaintext_len); + aes_encrypt_cbc_mac(buf, end_of_buf, mac, key, keysize, temp_iv); + + // Copy the Payload and MAC to the output buffer. + memcpy(out, payload, payload_len); + memcpy(&out[payload_len], mac, mac_len); + + // Encrypt the Payload with CTR mode with a counter starting at 1. + memcpy(temp_iv, counter, AES_BLOCK_SIZE); + increment_iv( + temp_iv, + AES_BLOCK_SIZE - 1 - + mac_len); // Last argument is the byte size of the counting portion of the counter block. /*BUG?*/ + aes_encrypt_ctr(out, payload_len, out, key, keysize, temp_iv); + + // Encrypt the MAC with CTR mode with a counter starting at 0. + aes_encrypt_ctr(&out[payload_len], mac_len, &out[payload_len], key, keysize, counter); + + free(buf); + *out_len = payload_len + mac_len; + + return (TRUE); +} + +// plaintext_len = ciphertext_len - mac_len +// Needs a flag for whether the MAC matches. +int +aes_decrypt_ccm(const BYTE ciphertext[], WORD ciphertext_len, const BYTE assoc[], unsigned short assoc_len, + const BYTE nonce[], unsigned short nonce_len, BYTE plaintext[], WORD *plaintext_len, WORD mac_len, + int *mac_auth, const BYTE key_str[], int keysize) { + BYTE temp_iv[AES_BLOCK_SIZE], counter[AES_BLOCK_SIZE], mac[16], mac_buf[16], *buf; + int end_of_buf, plaintext_len_store_size; + WORD key[60]; + + if (ciphertext_len <= mac_len) + return (FALSE); + + buf = (BYTE *)malloc(assoc_len + ciphertext_len /*ciphertext_len = plaintext_len + mac_len*/ + 48); + if (!buf) + return (FALSE); + + // Prepare the key for usage. + aes_key_setup(key_str, key, keysize); + + // Copy the plaintext and MAC to the output buffers. + *plaintext_len = ciphertext_len - mac_len; + plaintext_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; + memcpy(plaintext, ciphertext, *plaintext_len); + memcpy(mac, &ciphertext[*plaintext_len], mac_len); + + // Prepare the first counter block for use in decryption. + ccm_prepare_first_ctr_blk(counter, nonce, nonce_len, plaintext_len_store_size); + + // Decrypt the Payload with CTR mode with a counter starting at 1. + memcpy(temp_iv, counter, AES_BLOCK_SIZE); + increment_iv(temp_iv, AES_BLOCK_SIZE - 1 - mac_len); // (AES_BLOCK_SIZE - 1 - mac_len) is the byte size of the + // counting portion of the counter block. + aes_decrypt_ctr(plaintext, *plaintext_len, plaintext, key, keysize, temp_iv); + + // Setting mac_auth to NULL disables the authentication check. + if (mac_auth != NULL) { + // Decrypt the MAC with CTR mode with a counter starting at 0. + aes_decrypt_ctr(mac, mac_len, mac, key, keysize, counter); + + // Format the first block of the formatted data. + plaintext_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; + ccm_prepare_first_format_blk(buf, assoc_len, *plaintext_len, plaintext_len_store_size, mac_len, nonce, + nonce_len); + end_of_buf = AES_BLOCK_SIZE; + + // Format the Associated Data into the authentication buffer. + ccm_format_assoc_data(buf, &end_of_buf, assoc, assoc_len); + + // Format the Payload into the authentication buffer. + ccm_format_payload_data(buf, &end_of_buf, plaintext, *plaintext_len); + + // Perform the CBC operation with an IV of zeros on the formatted buffer to calculate the MAC. + memset(temp_iv, 0, AES_BLOCK_SIZE); + aes_encrypt_cbc_mac(buf, end_of_buf, mac_buf, key, keysize, temp_iv); + + // Compare the calculated MAC against the MAC embedded in the ciphertext to see if they are the same. + if (!memcmp(mac, mac_buf, mac_len)) { + *mac_auth = TRUE; + } else { + *mac_auth = FALSE; + memset(plaintext, 0, *plaintext_len); + } } - } - - free(buf); - - return(TRUE); + + free(buf); + + return (TRUE); } - + // Creates the first counter block. First byte is flags, then the nonce, then the incremented part. -void ccm_prepare_first_ctr_blk(BYTE counter[], const BYTE nonce[], int nonce_len, int payload_len_store_size) -{ - memset(counter, 0, AES_BLOCK_SIZE); - counter[0] = (payload_len_store_size - 1) & 0x07; - memcpy(&counter[1], nonce, nonce_len); +void +ccm_prepare_first_ctr_blk(BYTE counter[], const BYTE nonce[], int nonce_len, int payload_len_store_size) { + memset(counter, 0, AES_BLOCK_SIZE); + counter[0] = (payload_len_store_size - 1) & 0x07; + memcpy(&counter[1], nonce, nonce_len); } - -void ccm_prepare_first_format_blk(BYTE buf[], int assoc_len, int payload_len, int payload_len_store_size, int mac_len, const BYTE nonce[], int nonce_len) -{ - // Set the flags for the first byte of the first block. - buf[0] = ((((mac_len - 2) / 2) & 0x07) << 3) | ((payload_len_store_size - 1) & 0x07); - if (assoc_len > 0) - buf[0] += 0x40; - // Format the rest of the first block, storing the nonce and the size of the payload. - memcpy(&buf[1], nonce, nonce_len); - memset(&buf[1 + nonce_len], 0, AES_BLOCK_SIZE - 1 - nonce_len); - buf[15] = payload_len & 0x000000FF; - buf[14] = (payload_len >> 8) & 0x000000FF; + +void +ccm_prepare_first_format_blk(BYTE buf[], int assoc_len, int payload_len, int payload_len_store_size, int mac_len, + const BYTE nonce[], int nonce_len) { + // Set the flags for the first byte of the first block. + buf[0] = ((((mac_len - 2) / 2) & 0x07) << 3) | ((payload_len_store_size - 1) & 0x07); + if (assoc_len > 0) + buf[0] += 0x40; + // Format the rest of the first block, storing the nonce and the size of the payload. + memcpy(&buf[1], nonce, nonce_len); + memset(&buf[1 + nonce_len], 0, AES_BLOCK_SIZE - 1 - nonce_len); + buf[15] = payload_len & 0x000000FF; + buf[14] = (payload_len >> 8) & 0x000000FF; } - -void ccm_format_assoc_data(BYTE buf[], int *end_of_buf, const BYTE assoc[], int assoc_len) -{ - int pad; - - buf[*end_of_buf + 1] = assoc_len & 0x00FF; - buf[*end_of_buf] = (assoc_len >> 8) & 0x00FF; - *end_of_buf += 2; - memcpy(&buf[*end_of_buf], assoc, assoc_len); - *end_of_buf += assoc_len; - pad = AES_BLOCK_SIZE - (*end_of_buf % AES_BLOCK_SIZE); /*BUG?*/ - memset(&buf[*end_of_buf], 0, pad); - *end_of_buf += pad; + +void +ccm_format_assoc_data(BYTE buf[], int *end_of_buf, const BYTE assoc[], int assoc_len) { + int pad; + + buf[*end_of_buf + 1] = assoc_len & 0x00FF; + buf[*end_of_buf] = (assoc_len >> 8) & 0x00FF; + *end_of_buf += 2; + memcpy(&buf[*end_of_buf], assoc, assoc_len); + *end_of_buf += assoc_len; + pad = AES_BLOCK_SIZE - (*end_of_buf % AES_BLOCK_SIZE); /*BUG?*/ + memset(&buf[*end_of_buf], 0, pad); + *end_of_buf += pad; } - -void ccm_format_payload_data(BYTE buf[], int *end_of_buf, const BYTE payload[], int payload_len) -{ - int pad; - - memcpy(&buf[*end_of_buf], payload, payload_len); - *end_of_buf += payload_len; - pad = *end_of_buf % AES_BLOCK_SIZE; - if (pad != 0) - pad = AES_BLOCK_SIZE - pad; - memset(&buf[*end_of_buf], 0, pad); - *end_of_buf += pad; + +void +ccm_format_payload_data(BYTE buf[], int *end_of_buf, const BYTE payload[], int payload_len) { + int pad; + + memcpy(&buf[*end_of_buf], payload, payload_len); + *end_of_buf += payload_len; + pad = *end_of_buf % AES_BLOCK_SIZE; + if (pad != 0) + pad = AES_BLOCK_SIZE - pad; + memset(&buf[*end_of_buf], 0, pad); + *end_of_buf += pad; } - + /******************* * AES *******************/ ///////////////// // KEY EXPANSION ///////////////// - + // Substitutes a word using the AES S-Box. -WORD SubWord(WORD word) -{ - unsigned int result; - - result = (int)aes_sbox[(word >> 4) & 0x0000000F][word & 0x0000000F]; - result += (int)aes_sbox[(word >> 12) & 0x0000000F][(word >> 8) & 0x0000000F] << 8; - result += (int)aes_sbox[(word >> 20) & 0x0000000F][(word >> 16) & 0x0000000F] << 16; - result += (int)aes_sbox[(word >> 28) & 0x0000000F][(word >> 24) & 0x0000000F] << 24; - return(result); +WORD +SubWord(WORD word) { + unsigned int result; + + result = (int)aes_sbox[(word >> 4) & 0x0000000F][word & 0x0000000F]; + result += (int)aes_sbox[(word >> 12) & 0x0000000F][(word >> 8) & 0x0000000F] << 8; + result += (int)aes_sbox[(word >> 20) & 0x0000000F][(word >> 16) & 0x0000000F] << 16; + result += (int)aes_sbox[(word >> 28) & 0x0000000F][(word >> 24) & 0x0000000F] << 24; + return (result); } - + // Performs the action of generating the keys that will be used in every round of // encryption. "key" is the user-supplied input key, "w" is the output key schedule, // "keysize" is the length in bits of "key", must be 128, 192, or 256. -void aes_key_setup(const BYTE key[], WORD w[], int keysize) -{ - int Nb=4,Nr,Nk,idx; - WORD temp,Rcon[]={0x01000000,0x02000000,0x04000000,0x08000000,0x10000000,0x20000000, - 0x40000000,0x80000000,0x1b000000,0x36000000,0x6c000000,0xd8000000, - 0xab000000,0x4d000000,0x9a000000}; - - switch (keysize) { - case 128: Nr = 10; Nk = 4; break; - case 192: Nr = 12; Nk = 6; break; - case 256: Nr = 14; Nk = 8; break; - default: return; - } - - for (idx=0; idx < Nk; ++idx) { - w[idx] = ((key[4 * idx]) << 24) | ((key[4 * idx + 1]) << 16) | - ((key[4 * idx + 2]) << 8) | ((key[4 * idx + 3])); - } - - for (idx = Nk; idx < Nb * (Nr+1); ++idx) { - temp = w[idx - 1]; - if ((idx % Nk) == 0) - temp = SubWord(KE_ROTWORD(temp)) ^ Rcon[(idx-1)/Nk]; - else if (Nk > 6 && (idx % Nk) == 4) - temp = SubWord(temp); - w[idx] = w[idx-Nk] ^ temp; - } +void +aes_key_setup(const BYTE key[], WORD w[], int keysize) { + int Nb = 4, Nr, Nk, idx; + WORD temp, + Rcon[] = {0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1b000000, 0x36000000, 0x6c000000, 0xd8000000, 0xab000000, 0x4d000000, 0x9a000000}; + + switch (keysize) { + case 128: + Nr = 10; + Nk = 4; + break; + case 192: + Nr = 12; + Nk = 6; + break; + case 256: + Nr = 14; + Nk = 8; + break; + default: + return; + } + + for (idx = 0; idx < Nk; ++idx) { + w[idx] = ((key[4 * idx]) << 24) | ((key[4 * idx + 1]) << 16) | ((key[4 * idx + 2]) << 8) | + ((key[4 * idx + 3])); + } + + for (idx = Nk; idx < Nb * (Nr + 1); ++idx) { + temp = w[idx - 1]; + if ((idx % Nk) == 0) + temp = SubWord(KE_ROTWORD(temp)) ^ Rcon[(idx - 1) / Nk]; + else if (Nk > 6 && (idx % Nk) == 4) + temp = SubWord(temp); + w[idx] = w[idx - Nk] ^ temp; + } } - + ///////////////// // ADD ROUND KEY ///////////////// - + // Performs the AddRoundKey step. Each round has its own pre-generated 16-byte key in the // form of 4 integers (the "w" array). Each integer is XOR'd by one column of the state. // Also performs the job of InvAddRoundKey(); since the function is a simple XOR process, // it is its own inverse. -void AddRoundKey(BYTE state[][4], const WORD w[]) -{ - BYTE subkey[4]; - - // memcpy(subkey,&w[idx],4); // Not accurate for big endian machines - // Subkey 1 - subkey[0] = w[0] >> 24; - subkey[1] = w[0] >> 16; - subkey[2] = w[0] >> 8; - subkey[3] = w[0]; - state[0][0] ^= subkey[0]; - state[1][0] ^= subkey[1]; - state[2][0] ^= subkey[2]; - state[3][0] ^= subkey[3]; - // Subkey 2 - subkey[0] = w[1] >> 24; - subkey[1] = w[1] >> 16; - subkey[2] = w[1] >> 8; - subkey[3] = w[1]; - state[0][1] ^= subkey[0]; - state[1][1] ^= subkey[1]; - state[2][1] ^= subkey[2]; - state[3][1] ^= subkey[3]; - // Subkey 3 - subkey[0] = w[2] >> 24; - subkey[1] = w[2] >> 16; - subkey[2] = w[2] >> 8; - subkey[3] = w[2]; - state[0][2] ^= subkey[0]; - state[1][2] ^= subkey[1]; - state[2][2] ^= subkey[2]; - state[3][2] ^= subkey[3]; - // Subkey 4 - subkey[0] = w[3] >> 24; - subkey[1] = w[3] >> 16; - subkey[2] = w[3] >> 8; - subkey[3] = w[3]; - state[0][3] ^= subkey[0]; - state[1][3] ^= subkey[1]; - state[2][3] ^= subkey[2]; - state[3][3] ^= subkey[3]; +void +AddRoundKey(BYTE state[][4], const WORD w[]) { + BYTE subkey[4]; + + // memcpy(subkey,&w[idx],4); // Not accurate for big endian machines + // Subkey 1 + subkey[0] = w[0] >> 24; + subkey[1] = w[0] >> 16; + subkey[2] = w[0] >> 8; + subkey[3] = w[0]; + state[0][0] ^= subkey[0]; + state[1][0] ^= subkey[1]; + state[2][0] ^= subkey[2]; + state[3][0] ^= subkey[3]; + // Subkey 2 + subkey[0] = w[1] >> 24; + subkey[1] = w[1] >> 16; + subkey[2] = w[1] >> 8; + subkey[3] = w[1]; + state[0][1] ^= subkey[0]; + state[1][1] ^= subkey[1]; + state[2][1] ^= subkey[2]; + state[3][1] ^= subkey[3]; + // Subkey 3 + subkey[0] = w[2] >> 24; + subkey[1] = w[2] >> 16; + subkey[2] = w[2] >> 8; + subkey[3] = w[2]; + state[0][2] ^= subkey[0]; + state[1][2] ^= subkey[1]; + state[2][2] ^= subkey[2]; + state[3][2] ^= subkey[3]; + // Subkey 4 + subkey[0] = w[3] >> 24; + subkey[1] = w[3] >> 16; + subkey[2] = w[3] >> 8; + subkey[3] = w[3]; + state[0][3] ^= subkey[0]; + state[1][3] ^= subkey[1]; + state[2][3] ^= subkey[2]; + state[3][3] ^= subkey[3]; } - + ///////////////// // (Inv)SubBytes ///////////////// - + // Performs the SubBytes step. All bytes in the state are substituted with a // pre-calculated value from a lookup table. -void SubBytes(BYTE state[][4]) -{ - state[0][0] = aes_sbox[state[0][0] >> 4][state[0][0] & 0x0F]; - state[0][1] = aes_sbox[state[0][1] >> 4][state[0][1] & 0x0F]; - state[0][2] = aes_sbox[state[0][2] >> 4][state[0][2] & 0x0F]; - state[0][3] = aes_sbox[state[0][3] >> 4][state[0][3] & 0x0F]; - state[1][0] = aes_sbox[state[1][0] >> 4][state[1][0] & 0x0F]; - state[1][1] = aes_sbox[state[1][1] >> 4][state[1][1] & 0x0F]; - state[1][2] = aes_sbox[state[1][2] >> 4][state[1][2] & 0x0F]; - state[1][3] = aes_sbox[state[1][3] >> 4][state[1][3] & 0x0F]; - state[2][0] = aes_sbox[state[2][0] >> 4][state[2][0] & 0x0F]; - state[2][1] = aes_sbox[state[2][1] >> 4][state[2][1] & 0x0F]; - state[2][2] = aes_sbox[state[2][2] >> 4][state[2][2] & 0x0F]; - state[2][3] = aes_sbox[state[2][3] >> 4][state[2][3] & 0x0F]; - state[3][0] = aes_sbox[state[3][0] >> 4][state[3][0] & 0x0F]; - state[3][1] = aes_sbox[state[3][1] >> 4][state[3][1] & 0x0F]; - state[3][2] = aes_sbox[state[3][2] >> 4][state[3][2] & 0x0F]; - state[3][3] = aes_sbox[state[3][3] >> 4][state[3][3] & 0x0F]; +void +SubBytes(BYTE state[][4]) { + state[0][0] = aes_sbox[state[0][0] >> 4][state[0][0] & 0x0F]; + state[0][1] = aes_sbox[state[0][1] >> 4][state[0][1] & 0x0F]; + state[0][2] = aes_sbox[state[0][2] >> 4][state[0][2] & 0x0F]; + state[0][3] = aes_sbox[state[0][3] >> 4][state[0][3] & 0x0F]; + state[1][0] = aes_sbox[state[1][0] >> 4][state[1][0] & 0x0F]; + state[1][1] = aes_sbox[state[1][1] >> 4][state[1][1] & 0x0F]; + state[1][2] = aes_sbox[state[1][2] >> 4][state[1][2] & 0x0F]; + state[1][3] = aes_sbox[state[1][3] >> 4][state[1][3] & 0x0F]; + state[2][0] = aes_sbox[state[2][0] >> 4][state[2][0] & 0x0F]; + state[2][1] = aes_sbox[state[2][1] >> 4][state[2][1] & 0x0F]; + state[2][2] = aes_sbox[state[2][2] >> 4][state[2][2] & 0x0F]; + state[2][3] = aes_sbox[state[2][3] >> 4][state[2][3] & 0x0F]; + state[3][0] = aes_sbox[state[3][0] >> 4][state[3][0] & 0x0F]; + state[3][1] = aes_sbox[state[3][1] >> 4][state[3][1] & 0x0F]; + state[3][2] = aes_sbox[state[3][2] >> 4][state[3][2] & 0x0F]; + state[3][3] = aes_sbox[state[3][3] >> 4][state[3][3] & 0x0F]; } - -void InvSubBytes(BYTE state[][4]) -{ - state[0][0] = aes_invsbox[state[0][0] >> 4][state[0][0] & 0x0F]; - state[0][1] = aes_invsbox[state[0][1] >> 4][state[0][1] & 0x0F]; - state[0][2] = aes_invsbox[state[0][2] >> 4][state[0][2] & 0x0F]; - state[0][3] = aes_invsbox[state[0][3] >> 4][state[0][3] & 0x0F]; - state[1][0] = aes_invsbox[state[1][0] >> 4][state[1][0] & 0x0F]; - state[1][1] = aes_invsbox[state[1][1] >> 4][state[1][1] & 0x0F]; - state[1][2] = aes_invsbox[state[1][2] >> 4][state[1][2] & 0x0F]; - state[1][3] = aes_invsbox[state[1][3] >> 4][state[1][3] & 0x0F]; - state[2][0] = aes_invsbox[state[2][0] >> 4][state[2][0] & 0x0F]; - state[2][1] = aes_invsbox[state[2][1] >> 4][state[2][1] & 0x0F]; - state[2][2] = aes_invsbox[state[2][2] >> 4][state[2][2] & 0x0F]; - state[2][3] = aes_invsbox[state[2][3] >> 4][state[2][3] & 0x0F]; - state[3][0] = aes_invsbox[state[3][0] >> 4][state[3][0] & 0x0F]; - state[3][1] = aes_invsbox[state[3][1] >> 4][state[3][1] & 0x0F]; - state[3][2] = aes_invsbox[state[3][2] >> 4][state[3][2] & 0x0F]; - state[3][3] = aes_invsbox[state[3][3] >> 4][state[3][3] & 0x0F]; + +void +InvSubBytes(BYTE state[][4]) { + state[0][0] = aes_invsbox[state[0][0] >> 4][state[0][0] & 0x0F]; + state[0][1] = aes_invsbox[state[0][1] >> 4][state[0][1] & 0x0F]; + state[0][2] = aes_invsbox[state[0][2] >> 4][state[0][2] & 0x0F]; + state[0][3] = aes_invsbox[state[0][3] >> 4][state[0][3] & 0x0F]; + state[1][0] = aes_invsbox[state[1][0] >> 4][state[1][0] & 0x0F]; + state[1][1] = aes_invsbox[state[1][1] >> 4][state[1][1] & 0x0F]; + state[1][2] = aes_invsbox[state[1][2] >> 4][state[1][2] & 0x0F]; + state[1][3] = aes_invsbox[state[1][3] >> 4][state[1][3] & 0x0F]; + state[2][0] = aes_invsbox[state[2][0] >> 4][state[2][0] & 0x0F]; + state[2][1] = aes_invsbox[state[2][1] >> 4][state[2][1] & 0x0F]; + state[2][2] = aes_invsbox[state[2][2] >> 4][state[2][2] & 0x0F]; + state[2][3] = aes_invsbox[state[2][3] >> 4][state[2][3] & 0x0F]; + state[3][0] = aes_invsbox[state[3][0] >> 4][state[3][0] & 0x0F]; + state[3][1] = aes_invsbox[state[3][1] >> 4][state[3][1] & 0x0F]; + state[3][2] = aes_invsbox[state[3][2] >> 4][state[3][2] & 0x0F]; + state[3][3] = aes_invsbox[state[3][3] >> 4][state[3][3] & 0x0F]; } - + ///////////////// // (Inv)ShiftRows ///////////////// - + // Performs the ShiftRows step. All rows are shifted cylindrically to the left. -void ShiftRows(BYTE state[][4]) -{ - int t; - - // Shift left by 1 - t = state[1][0]; - state[1][0] = state[1][1]; - state[1][1] = state[1][2]; - state[1][2] = state[1][3]; - state[1][3] = t; - // Shift left by 2 - t = state[2][0]; - state[2][0] = state[2][2]; - state[2][2] = t; - t = state[2][1]; - state[2][1] = state[2][3]; - state[2][3] = t; - // Shift left by 3 - t = state[3][0]; - state[3][0] = state[3][3]; - state[3][3] = state[3][2]; - state[3][2] = state[3][1]; - state[3][1] = t; +void +ShiftRows(BYTE state[][4]) { + int t; + + // Shift left by 1 + t = state[1][0]; + state[1][0] = state[1][1]; + state[1][1] = state[1][2]; + state[1][2] = state[1][3]; + state[1][3] = t; + // Shift left by 2 + t = state[2][0]; + state[2][0] = state[2][2]; + state[2][2] = t; + t = state[2][1]; + state[2][1] = state[2][3]; + state[2][3] = t; + // Shift left by 3 + t = state[3][0]; + state[3][0] = state[3][3]; + state[3][3] = state[3][2]; + state[3][2] = state[3][1]; + state[3][1] = t; } - + // All rows are shifted cylindrically to the right. -void InvShiftRows(BYTE state[][4]) -{ - int t; - - // Shift right by 1 - t = state[1][3]; - state[1][3] = state[1][2]; - state[1][2] = state[1][1]; - state[1][1] = state[1][0]; - state[1][0] = t; - // Shift right by 2 - t = state[2][3]; - state[2][3] = state[2][1]; - state[2][1] = t; - t = state[2][2]; - state[2][2] = state[2][0]; - state[2][0] = t; - // Shift right by 3 - t = state[3][3]; - state[3][3] = state[3][0]; - state[3][0] = state[3][1]; - state[3][1] = state[3][2]; - state[3][2] = t; +void +InvShiftRows(BYTE state[][4]) { + int t; + + // Shift right by 1 + t = state[1][3]; + state[1][3] = state[1][2]; + state[1][2] = state[1][1]; + state[1][1] = state[1][0]; + state[1][0] = t; + // Shift right by 2 + t = state[2][3]; + state[2][3] = state[2][1]; + state[2][1] = t; + t = state[2][2]; + state[2][2] = state[2][0]; + state[2][0] = t; + // Shift right by 3 + t = state[3][3]; + state[3][3] = state[3][0]; + state[3][0] = state[3][1]; + state[3][1] = state[3][2]; + state[3][2] = t; } - + ///////////////// // (Inv)MixColumns ///////////////// - + // Performs the MixColums step. The state is multiplied by itself using matrix // multiplication in a Galios Field 2^8. All multiplication is pre-computed in a table. // Addition is equivilent to XOR. (Must always make a copy of the column as the original // values will be destoyed.) -void MixColumns(BYTE state[][4]) -{ - BYTE col[4]; - - // Column 1 - col[0] = state[0][0]; - col[1] = state[1][0]; - col[2] = state[2][0]; - col[3] = state[3][0]; - state[0][0] = gf_mul[col[0]][0]; - state[0][0] ^= gf_mul[col[1]][1]; - state[0][0] ^= col[2]; - state[0][0] ^= col[3]; - state[1][0] = col[0]; - state[1][0] ^= gf_mul[col[1]][0]; - state[1][0] ^= gf_mul[col[2]][1]; - state[1][0] ^= col[3]; - state[2][0] = col[0]; - state[2][0] ^= col[1]; - state[2][0] ^= gf_mul[col[2]][0]; - state[2][0] ^= gf_mul[col[3]][1]; - state[3][0] = gf_mul[col[0]][1]; - state[3][0] ^= col[1]; - state[3][0] ^= col[2]; - state[3][0] ^= gf_mul[col[3]][0]; - // Column 2 - col[0] = state[0][1]; - col[1] = state[1][1]; - col[2] = state[2][1]; - col[3] = state[3][1]; - state[0][1] = gf_mul[col[0]][0]; - state[0][1] ^= gf_mul[col[1]][1]; - state[0][1] ^= col[2]; - state[0][1] ^= col[3]; - state[1][1] = col[0]; - state[1][1] ^= gf_mul[col[1]][0]; - state[1][1] ^= gf_mul[col[2]][1]; - state[1][1] ^= col[3]; - state[2][1] = col[0]; - state[2][1] ^= col[1]; - state[2][1] ^= gf_mul[col[2]][0]; - state[2][1] ^= gf_mul[col[3]][1]; - state[3][1] = gf_mul[col[0]][1]; - state[3][1] ^= col[1]; - state[3][1] ^= col[2]; - state[3][1] ^= gf_mul[col[3]][0]; - // Column 3 - col[0] = state[0][2]; - col[1] = state[1][2]; - col[2] = state[2][2]; - col[3] = state[3][2]; - state[0][2] = gf_mul[col[0]][0]; - state[0][2] ^= gf_mul[col[1]][1]; - state[0][2] ^= col[2]; - state[0][2] ^= col[3]; - state[1][2] = col[0]; - state[1][2] ^= gf_mul[col[1]][0]; - state[1][2] ^= gf_mul[col[2]][1]; - state[1][2] ^= col[3]; - state[2][2] = col[0]; - state[2][2] ^= col[1]; - state[2][2] ^= gf_mul[col[2]][0]; - state[2][2] ^= gf_mul[col[3]][1]; - state[3][2] = gf_mul[col[0]][1]; - state[3][2] ^= col[1]; - state[3][2] ^= col[2]; - state[3][2] ^= gf_mul[col[3]][0]; - // Column 4 - col[0] = state[0][3]; - col[1] = state[1][3]; - col[2] = state[2][3]; - col[3] = state[3][3]; - state[0][3] = gf_mul[col[0]][0]; - state[0][3] ^= gf_mul[col[1]][1]; - state[0][3] ^= col[2]; - state[0][3] ^= col[3]; - state[1][3] = col[0]; - state[1][3] ^= gf_mul[col[1]][0]; - state[1][3] ^= gf_mul[col[2]][1]; - state[1][3] ^= col[3]; - state[2][3] = col[0]; - state[2][3] ^= col[1]; - state[2][3] ^= gf_mul[col[2]][0]; - state[2][3] ^= gf_mul[col[3]][1]; - state[3][3] = gf_mul[col[0]][1]; - state[3][3] ^= col[1]; - state[3][3] ^= col[2]; - state[3][3] ^= gf_mul[col[3]][0]; +void +MixColumns(BYTE state[][4]) { + BYTE col[4]; + + // Column 1 + col[0] = state[0][0]; + col[1] = state[1][0]; + col[2] = state[2][0]; + col[3] = state[3][0]; + state[0][0] = gf_mul[col[0]][0]; + state[0][0] ^= gf_mul[col[1]][1]; + state[0][0] ^= col[2]; + state[0][0] ^= col[3]; + state[1][0] = col[0]; + state[1][0] ^= gf_mul[col[1]][0]; + state[1][0] ^= gf_mul[col[2]][1]; + state[1][0] ^= col[3]; + state[2][0] = col[0]; + state[2][0] ^= col[1]; + state[2][0] ^= gf_mul[col[2]][0]; + state[2][0] ^= gf_mul[col[3]][1]; + state[3][0] = gf_mul[col[0]][1]; + state[3][0] ^= col[1]; + state[3][0] ^= col[2]; + state[3][0] ^= gf_mul[col[3]][0]; + // Column 2 + col[0] = state[0][1]; + col[1] = state[1][1]; + col[2] = state[2][1]; + col[3] = state[3][1]; + state[0][1] = gf_mul[col[0]][0]; + state[0][1] ^= gf_mul[col[1]][1]; + state[0][1] ^= col[2]; + state[0][1] ^= col[3]; + state[1][1] = col[0]; + state[1][1] ^= gf_mul[col[1]][0]; + state[1][1] ^= gf_mul[col[2]][1]; + state[1][1] ^= col[3]; + state[2][1] = col[0]; + state[2][1] ^= col[1]; + state[2][1] ^= gf_mul[col[2]][0]; + state[2][1] ^= gf_mul[col[3]][1]; + state[3][1] = gf_mul[col[0]][1]; + state[3][1] ^= col[1]; + state[3][1] ^= col[2]; + state[3][1] ^= gf_mul[col[3]][0]; + // Column 3 + col[0] = state[0][2]; + col[1] = state[1][2]; + col[2] = state[2][2]; + col[3] = state[3][2]; + state[0][2] = gf_mul[col[0]][0]; + state[0][2] ^= gf_mul[col[1]][1]; + state[0][2] ^= col[2]; + state[0][2] ^= col[3]; + state[1][2] = col[0]; + state[1][2] ^= gf_mul[col[1]][0]; + state[1][2] ^= gf_mul[col[2]][1]; + state[1][2] ^= col[3]; + state[2][2] = col[0]; + state[2][2] ^= col[1]; + state[2][2] ^= gf_mul[col[2]][0]; + state[2][2] ^= gf_mul[col[3]][1]; + state[3][2] = gf_mul[col[0]][1]; + state[3][2] ^= col[1]; + state[3][2] ^= col[2]; + state[3][2] ^= gf_mul[col[3]][0]; + // Column 4 + col[0] = state[0][3]; + col[1] = state[1][3]; + col[2] = state[2][3]; + col[3] = state[3][3]; + state[0][3] = gf_mul[col[0]][0]; + state[0][3] ^= gf_mul[col[1]][1]; + state[0][3] ^= col[2]; + state[0][3] ^= col[3]; + state[1][3] = col[0]; + state[1][3] ^= gf_mul[col[1]][0]; + state[1][3] ^= gf_mul[col[2]][1]; + state[1][3] ^= col[3]; + state[2][3] = col[0]; + state[2][3] ^= col[1]; + state[2][3] ^= gf_mul[col[2]][0]; + state[2][3] ^= gf_mul[col[3]][1]; + state[3][3] = gf_mul[col[0]][1]; + state[3][3] ^= col[1]; + state[3][3] ^= col[2]; + state[3][3] ^= gf_mul[col[3]][0]; } - -void InvMixColumns(BYTE state[][4]) -{ - BYTE col[4]; - - // Column 1 - col[0] = state[0][0]; - col[1] = state[1][0]; - col[2] = state[2][0]; - col[3] = state[3][0]; - state[0][0] = gf_mul[col[0]][5]; - state[0][0] ^= gf_mul[col[1]][3]; - state[0][0] ^= gf_mul[col[2]][4]; - state[0][0] ^= gf_mul[col[3]][2]; - state[1][0] = gf_mul[col[0]][2]; - state[1][0] ^= gf_mul[col[1]][5]; - state[1][0] ^= gf_mul[col[2]][3]; - state[1][0] ^= gf_mul[col[3]][4]; - state[2][0] = gf_mul[col[0]][4]; - state[2][0] ^= gf_mul[col[1]][2]; - state[2][0] ^= gf_mul[col[2]][5]; - state[2][0] ^= gf_mul[col[3]][3]; - state[3][0] = gf_mul[col[0]][3]; - state[3][0] ^= gf_mul[col[1]][4]; - state[3][0] ^= gf_mul[col[2]][2]; - state[3][0] ^= gf_mul[col[3]][5]; - // Column 2 - col[0] = state[0][1]; - col[1] = state[1][1]; - col[2] = state[2][1]; - col[3] = state[3][1]; - state[0][1] = gf_mul[col[0]][5]; - state[0][1] ^= gf_mul[col[1]][3]; - state[0][1] ^= gf_mul[col[2]][4]; - state[0][1] ^= gf_mul[col[3]][2]; - state[1][1] = gf_mul[col[0]][2]; - state[1][1] ^= gf_mul[col[1]][5]; - state[1][1] ^= gf_mul[col[2]][3]; - state[1][1] ^= gf_mul[col[3]][4]; - state[2][1] = gf_mul[col[0]][4]; - state[2][1] ^= gf_mul[col[1]][2]; - state[2][1] ^= gf_mul[col[2]][5]; - state[2][1] ^= gf_mul[col[3]][3]; - state[3][1] = gf_mul[col[0]][3]; - state[3][1] ^= gf_mul[col[1]][4]; - state[3][1] ^= gf_mul[col[2]][2]; - state[3][1] ^= gf_mul[col[3]][5]; - // Column 3 - col[0] = state[0][2]; - col[1] = state[1][2]; - col[2] = state[2][2]; - col[3] = state[3][2]; - state[0][2] = gf_mul[col[0]][5]; - state[0][2] ^= gf_mul[col[1]][3]; - state[0][2] ^= gf_mul[col[2]][4]; - state[0][2] ^= gf_mul[col[3]][2]; - state[1][2] = gf_mul[col[0]][2]; - state[1][2] ^= gf_mul[col[1]][5]; - state[1][2] ^= gf_mul[col[2]][3]; - state[1][2] ^= gf_mul[col[3]][4]; - state[2][2] = gf_mul[col[0]][4]; - state[2][2] ^= gf_mul[col[1]][2]; - state[2][2] ^= gf_mul[col[2]][5]; - state[2][2] ^= gf_mul[col[3]][3]; - state[3][2] = gf_mul[col[0]][3]; - state[3][2] ^= gf_mul[col[1]][4]; - state[3][2] ^= gf_mul[col[2]][2]; - state[3][2] ^= gf_mul[col[3]][5]; - // Column 4 - col[0] = state[0][3]; - col[1] = state[1][3]; - col[2] = state[2][3]; - col[3] = state[3][3]; - state[0][3] = gf_mul[col[0]][5]; - state[0][3] ^= gf_mul[col[1]][3]; - state[0][3] ^= gf_mul[col[2]][4]; - state[0][3] ^= gf_mul[col[3]][2]; - state[1][3] = gf_mul[col[0]][2]; - state[1][3] ^= gf_mul[col[1]][5]; - state[1][3] ^= gf_mul[col[2]][3]; - state[1][3] ^= gf_mul[col[3]][4]; - state[2][3] = gf_mul[col[0]][4]; - state[2][3] ^= gf_mul[col[1]][2]; - state[2][3] ^= gf_mul[col[2]][5]; - state[2][3] ^= gf_mul[col[3]][3]; - state[3][3] = gf_mul[col[0]][3]; - state[3][3] ^= gf_mul[col[1]][4]; - state[3][3] ^= gf_mul[col[2]][2]; - state[3][3] ^= gf_mul[col[3]][5]; + +void +InvMixColumns(BYTE state[][4]) { + BYTE col[4]; + + // Column 1 + col[0] = state[0][0]; + col[1] = state[1][0]; + col[2] = state[2][0]; + col[3] = state[3][0]; + state[0][0] = gf_mul[col[0]][5]; + state[0][0] ^= gf_mul[col[1]][3]; + state[0][0] ^= gf_mul[col[2]][4]; + state[0][0] ^= gf_mul[col[3]][2]; + state[1][0] = gf_mul[col[0]][2]; + state[1][0] ^= gf_mul[col[1]][5]; + state[1][0] ^= gf_mul[col[2]][3]; + state[1][0] ^= gf_mul[col[3]][4]; + state[2][0] = gf_mul[col[0]][4]; + state[2][0] ^= gf_mul[col[1]][2]; + state[2][0] ^= gf_mul[col[2]][5]; + state[2][0] ^= gf_mul[col[3]][3]; + state[3][0] = gf_mul[col[0]][3]; + state[3][0] ^= gf_mul[col[1]][4]; + state[3][0] ^= gf_mul[col[2]][2]; + state[3][0] ^= gf_mul[col[3]][5]; + // Column 2 + col[0] = state[0][1]; + col[1] = state[1][1]; + col[2] = state[2][1]; + col[3] = state[3][1]; + state[0][1] = gf_mul[col[0]][5]; + state[0][1] ^= gf_mul[col[1]][3]; + state[0][1] ^= gf_mul[col[2]][4]; + state[0][1] ^= gf_mul[col[3]][2]; + state[1][1] = gf_mul[col[0]][2]; + state[1][1] ^= gf_mul[col[1]][5]; + state[1][1] ^= gf_mul[col[2]][3]; + state[1][1] ^= gf_mul[col[3]][4]; + state[2][1] = gf_mul[col[0]][4]; + state[2][1] ^= gf_mul[col[1]][2]; + state[2][1] ^= gf_mul[col[2]][5]; + state[2][1] ^= gf_mul[col[3]][3]; + state[3][1] = gf_mul[col[0]][3]; + state[3][1] ^= gf_mul[col[1]][4]; + state[3][1] ^= gf_mul[col[2]][2]; + state[3][1] ^= gf_mul[col[3]][5]; + // Column 3 + col[0] = state[0][2]; + col[1] = state[1][2]; + col[2] = state[2][2]; + col[3] = state[3][2]; + state[0][2] = gf_mul[col[0]][5]; + state[0][2] ^= gf_mul[col[1]][3]; + state[0][2] ^= gf_mul[col[2]][4]; + state[0][2] ^= gf_mul[col[3]][2]; + state[1][2] = gf_mul[col[0]][2]; + state[1][2] ^= gf_mul[col[1]][5]; + state[1][2] ^= gf_mul[col[2]][3]; + state[1][2] ^= gf_mul[col[3]][4]; + state[2][2] = gf_mul[col[0]][4]; + state[2][2] ^= gf_mul[col[1]][2]; + state[2][2] ^= gf_mul[col[2]][5]; + state[2][2] ^= gf_mul[col[3]][3]; + state[3][2] = gf_mul[col[0]][3]; + state[3][2] ^= gf_mul[col[1]][4]; + state[3][2] ^= gf_mul[col[2]][2]; + state[3][2] ^= gf_mul[col[3]][5]; + // Column 4 + col[0] = state[0][3]; + col[1] = state[1][3]; + col[2] = state[2][3]; + col[3] = state[3][3]; + state[0][3] = gf_mul[col[0]][5]; + state[0][3] ^= gf_mul[col[1]][3]; + state[0][3] ^= gf_mul[col[2]][4]; + state[0][3] ^= gf_mul[col[3]][2]; + state[1][3] = gf_mul[col[0]][2]; + state[1][3] ^= gf_mul[col[1]][5]; + state[1][3] ^= gf_mul[col[2]][3]; + state[1][3] ^= gf_mul[col[3]][4]; + state[2][3] = gf_mul[col[0]][4]; + state[2][3] ^= gf_mul[col[1]][2]; + state[2][3] ^= gf_mul[col[2]][5]; + state[2][3] ^= gf_mul[col[3]][3]; + state[3][3] = gf_mul[col[0]][3]; + state[3][3] ^= gf_mul[col[1]][4]; + state[3][3] ^= gf_mul[col[2]][2]; + state[3][3] ^= gf_mul[col[3]][5]; } - + ///////////////// // (En/De)Crypt ///////////////// - -void aes_encrypt(const BYTE in[], BYTE out[], const WORD key[], int keysize) -{ - BYTE state[4][4]; - - // Copy input array (should be 16 bytes long) to a matrix (sequential bytes are ordered - // by row, not col) called "state" for processing. - // *** Implementation note: The official AES documentation references the state by - // column, then row. Accessing an element in C requires row then column. Thus, all state - // references in AES must have the column and row indexes reversed for C implementation. - state[0][0] = in[0]; - state[1][0] = in[1]; - state[2][0] = in[2]; - state[3][0] = in[3]; - state[0][1] = in[4]; - state[1][1] = in[5]; - state[2][1] = in[6]; - state[3][1] = in[7]; - state[0][2] = in[8]; - state[1][2] = in[9]; - state[2][2] = in[10]; - state[3][2] = in[11]; - state[0][3] = in[12]; - state[1][3] = in[13]; - state[2][3] = in[14]; - state[3][3] = in[15]; - - // Perform the necessary number of rounds. The round key is added first. - // The last round does not perform the MixColumns step. - AddRoundKey(state,&key[0]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[4]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[8]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[12]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[16]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[20]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[24]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[28]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[32]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[36]); - if (keysize != 128) { - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[40]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[44]); - if (keysize != 192) { - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[48]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[52]); - SubBytes(state); ShiftRows(state); AddRoundKey(state,&key[56]); - } - else { - SubBytes(state); ShiftRows(state); AddRoundKey(state,&key[48]); + +void +aes_encrypt(const BYTE in[], BYTE out[], const WORD key[], int keysize) { + BYTE state[4][4]; + + // Copy input array (should be 16 bytes long) to a matrix (sequential bytes are ordered + // by row, not col) called "state" for processing. + // *** Implementation note: The official AES documentation references the state by + // column, then row. Accessing an element in C requires row then column. Thus, all state + // references in AES must have the column and row indexes reversed for C implementation. + state[0][0] = in[0]; + state[1][0] = in[1]; + state[2][0] = in[2]; + state[3][0] = in[3]; + state[0][1] = in[4]; + state[1][1] = in[5]; + state[2][1] = in[6]; + state[3][1] = in[7]; + state[0][2] = in[8]; + state[1][2] = in[9]; + state[2][2] = in[10]; + state[3][2] = in[11]; + state[0][3] = in[12]; + state[1][3] = in[13]; + state[2][3] = in[14]; + state[3][3] = in[15]; + + // Perform the necessary number of rounds. The round key is added first. + // The last round does not perform the MixColumns step. + AddRoundKey(state, &key[0]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[4]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[8]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[12]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[16]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[20]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[24]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[28]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[32]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[36]); + if (keysize != 128) { + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[40]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[44]); + if (keysize != 192) { + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[48]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[52]); + SubBytes(state); + ShiftRows(state); + AddRoundKey(state, &key[56]); + } else { + SubBytes(state); + ShiftRows(state); + AddRoundKey(state, &key[48]); + } + } else { + SubBytes(state); + ShiftRows(state); + AddRoundKey(state, &key[40]); } - } - else { - SubBytes(state); ShiftRows(state); AddRoundKey(state,&key[40]); - } - - // Copy the state to the output array. - out[0] = state[0][0]; - out[1] = state[1][0]; - out[2] = state[2][0]; - out[3] = state[3][0]; - out[4] = state[0][1]; - out[5] = state[1][1]; - out[6] = state[2][1]; - out[7] = state[3][1]; - out[8] = state[0][2]; - out[9] = state[1][2]; - out[10] = state[2][2]; - out[11] = state[3][2]; - out[12] = state[0][3]; - out[13] = state[1][3]; - out[14] = state[2][3]; - out[15] = state[3][3]; + + // Copy the state to the output array. + out[0] = state[0][0]; + out[1] = state[1][0]; + out[2] = state[2][0]; + out[3] = state[3][0]; + out[4] = state[0][1]; + out[5] = state[1][1]; + out[6] = state[2][1]; + out[7] = state[3][1]; + out[8] = state[0][2]; + out[9] = state[1][2]; + out[10] = state[2][2]; + out[11] = state[3][2]; + out[12] = state[0][3]; + out[13] = state[1][3]; + out[14] = state[2][3]; + out[15] = state[3][3]; } - -void aes_decrypt(const BYTE in[], BYTE out[], const WORD key[], int keysize) -{ - BYTE state[4][4]; - - // Copy the input to the state. - state[0][0] = in[0]; - state[1][0] = in[1]; - state[2][0] = in[2]; - state[3][0] = in[3]; - state[0][1] = in[4]; - state[1][1] = in[5]; - state[2][1] = in[6]; - state[3][1] = in[7]; - state[0][2] = in[8]; - state[1][2] = in[9]; - state[2][2] = in[10]; - state[3][2] = in[11]; - state[0][3] = in[12]; - state[1][3] = in[13]; - state[2][3] = in[14]; - state[3][3] = in[15]; - - // Perform the necessary number of rounds. The round key is added first. - // The last round does not perform the MixColumns step. - if (keysize > 128) { - if (keysize > 192) { - AddRoundKey(state,&key[56]); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[52]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[48]);InvMixColumns(state); - } - else { - AddRoundKey(state,&key[48]); + +void +aes_decrypt(const BYTE in[], BYTE out[], const WORD key[], int keysize) { + BYTE state[4][4]; + + // Copy the input to the state. + state[0][0] = in[0]; + state[1][0] = in[1]; + state[2][0] = in[2]; + state[3][0] = in[3]; + state[0][1] = in[4]; + state[1][1] = in[5]; + state[2][1] = in[6]; + state[3][1] = in[7]; + state[0][2] = in[8]; + state[1][2] = in[9]; + state[2][2] = in[10]; + state[3][2] = in[11]; + state[0][3] = in[12]; + state[1][3] = in[13]; + state[2][3] = in[14]; + state[3][3] = in[15]; + + // Perform the necessary number of rounds. The round key is added first. + // The last round does not perform the MixColumns step. + if (keysize > 128) { + if (keysize > 192) { + AddRoundKey(state, &key[56]); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[52]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[48]); + InvMixColumns(state); + } else { + AddRoundKey(state, &key[48]); + } + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[44]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[40]); + InvMixColumns(state); + } else { + AddRoundKey(state, &key[40]); } - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[44]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[40]);InvMixColumns(state); - } - else { - AddRoundKey(state,&key[40]); - } - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[36]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[32]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[28]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[24]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[20]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[16]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[12]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[8]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[4]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[0]); - - // Copy the state to the output array. - out[0] = state[0][0]; - out[1] = state[1][0]; - out[2] = state[2][0]; - out[3] = state[3][0]; - out[4] = state[0][1]; - out[5] = state[1][1]; - out[6] = state[2][1]; - out[7] = state[3][1]; - out[8] = state[0][2]; - out[9] = state[1][2]; - out[10] = state[2][2]; - out[11] = state[3][2]; - out[12] = state[0][3]; - out[13] = state[1][3]; - out[14] = state[2][3]; - out[15] = state[3][3]; + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[36]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[32]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[28]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[24]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[20]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[16]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[12]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[8]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[4]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[0]); + + // Copy the state to the output array. + out[0] = state[0][0]; + out[1] = state[1][0]; + out[2] = state[2][0]; + out[3] = state[3][0]; + out[4] = state[0][1]; + out[5] = state[1][1]; + out[6] = state[2][1]; + out[7] = state[3][1]; + out[8] = state[0][2]; + out[9] = state[1][2]; + out[10] = state[2][2]; + out[11] = state[3][2]; + out[12] = state[0][3]; + out[13] = state[1][3]; + out[14] = state[2][3]; + out[15] = state[3][3]; } - + /******************* ** AES DEBUGGING FUNCTIONS *******************/ @@ -1125,18 +1192,18 @@ void aes_decrypt(const BYTE in[], BYTE out[], const WORD key[], int keysize) void print_state(BYTE state[][4]) { int idx,idx2; - + for (idx=0; idx < 4; idx++) for (idx2=0; idx2 < 4; idx2++) printf("%02x",state[idx2][idx]); printf("\n"); } - + // This prints the key (4 consecutive ints) used for a given round as a linear hex string. void print_rnd_key(WORD key[]) { int idx; - + for (idx=0; idx < 4; idx++) printf("%08x",key[idx]); printf("\n"); diff --git a/examples/aes_decrypt/aes.h b/examples/aes_decrypt/aes.h index 1121c1629..17a571620 100644 --- a/examples/aes_decrypt/aes.h +++ b/examples/aes_decrypt/aes.h @@ -43,120 +43,134 @@ * Copyright: * Disclaimer: This code is presented "as is" without any guarantees. * Details: Defines the API for the corresponding AES implementation. -* Source: https://github.com/B-Con/crypto-algorithms +* Source: https://github.com/B-Con/crypto-algorithms *********************************************************************/ - + #ifndef AES_H #define AES_H - + /*************************** HEADER FILES ***************************/ #include - + /****************************** MACROS ******************************/ -#define AES_BLOCK_SIZE 16 // AES operates on 16 bytes at a time - +#define AES_BLOCK_SIZE 16 // AES operates on 16 bytes at a time + /**************************** DATA TYPES ****************************/ -typedef unsigned char BYTE; // 8-bit byte -typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines - +typedef unsigned char BYTE; // 8-bit byte +typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines + /*********************** FUNCTION DECLARATIONS **********************/ /////////////////// // AES /////////////////// // Key setup must be done before any AES en/de-cryption functions can be used. -void aes_key_setup(const BYTE key[], // The key, must be 128, 192, or 256 bits - WORD w[], // Output key schedule to be used later - int keysize); // Bit length of the key, 128, 192, or 256 - -void aes_encrypt(const BYTE in[], // 16 bytes of plaintext - BYTE out[], // 16 bytes of ciphertext - const WORD key[], // From the key setup - int keysize); // Bit length of the key, 128, 192, or 256 - -void aes_decrypt(const BYTE in[], // 16 bytes of ciphertext - BYTE out[], // 16 bytes of plaintext - const WORD key[], // From the key setup - int keysize); // Bit length of the key, 128, 192, or 256 - +void +aes_key_setup(const BYTE key[], // The key, must be 128, 192, or 256 bits + WORD w[], // Output key schedule to be used later + int keysize); // Bit length of the key, 128, 192, or 256 + +void +aes_encrypt(const BYTE in[], // 16 bytes of plaintext + BYTE out[], // 16 bytes of ciphertext + const WORD key[], // From the key setup + int keysize); // Bit length of the key, 128, 192, or 256 + +void +aes_decrypt(const BYTE in[], // 16 bytes of ciphertext + BYTE out[], // 16 bytes of plaintext + const WORD key[], // From the key setup + int keysize); // Bit length of the key, 128, 192, or 256 + /////////////////// // AES - CBC /////////////////// -int aes_encrypt_cbc(const BYTE in[], // Plaintext - size_t in_len, // Must be a multiple of AES_BLOCK_SIZE - BYTE out[], // Ciphertext, same length as plaintext - const WORD key[], // From the key setup - int keysize, // Bit length of the key, 128, 192, or 256 - const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long - +int +aes_encrypt_cbc(const BYTE in[], // Plaintext + size_t in_len, // Must be a multiple of AES_BLOCK_SIZE + BYTE out[], // Ciphertext, same length as plaintext + const WORD key[], // From the key setup + int keysize, // Bit length of the key, 128, 192, or 256 + const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long + // Only output the CBC-MAC of the input. -int aes_encrypt_cbc_mac(const BYTE in[], // plaintext - size_t in_len, // Must be a multiple of AES_BLOCK_SIZE - BYTE out[], // Output MAC - const WORD key[], // From the key setup - int keysize, // Bit length of the key, 128, 192, or 256 - const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long +int +aes_encrypt_cbc_mac(const BYTE in[], // plaintext + size_t in_len, // Must be a multiple of AES_BLOCK_SIZE + BYTE out[], // Output MAC + const WORD key[], // From the key setup + int keysize, // Bit length of the key, 128, 192, or 256 + const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long // Only output the CBC-MAC of the input. -int aes_decrypt_cbc(const BYTE in[], // plaintext - size_t in_len, // Must be a multiple of AES_BLOCK_SIZE - BYTE out[], // Output MAC - const WORD key[], // From the key setup - int keysize, // Bit length of the key, 128, 192, or 256 - const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long - +int +aes_decrypt_cbc(const BYTE in[], // plaintext + size_t in_len, // Must be a multiple of AES_BLOCK_SIZE + BYTE out[], // Output MAC + const WORD key[], // From the key setup + int keysize, // Bit length of the key, 128, 192, or 256 + const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long + /////////////////// // AES - CTR /////////////////// -void increment_iv(BYTE iv[], // Must be a multiple of AES_BLOCK_SIZE - int counter_size); // Bytes of the IV used for counting (low end) - -void aes_encrypt_ctr(const BYTE in[], // Plaintext - size_t in_len, // Any byte length - BYTE out[], // Ciphertext, same length as plaintext - const WORD key[], // From the key setup - int keysize, // Bit length of the key, 128, 192, or 256 - const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long - -void aes_decrypt_ctr(const BYTE in[], // Ciphertext - size_t in_len, // Any byte length - BYTE out[], // Plaintext, same length as ciphertext - const WORD key[], // From the key setup - int keysize, // Bit length of the key, 128, 192, or 256 - const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long - +void +increment_iv(BYTE iv[], // Must be a multiple of AES_BLOCK_SIZE + int counter_size); // Bytes of the IV used for counting (low end) + +void +aes_encrypt_ctr(const BYTE in[], // Plaintext + size_t in_len, // Any byte length + BYTE out[], // Ciphertext, same length as plaintext + const WORD key[], // From the key setup + int keysize, // Bit length of the key, 128, 192, or 256 + const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long + +void +aes_decrypt_ctr(const BYTE in[], // Ciphertext + size_t in_len, // Any byte length + BYTE out[], // Plaintext, same length as ciphertext + const WORD key[], // From the key setup + int keysize, // Bit length of the key, 128, 192, or 256 + const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long + /////////////////// // AES - CCM /////////////////// // Returns True if the input parameters do not violate any constraint. -int aes_encrypt_ccm(const BYTE plaintext[], // IN - Plaintext. - WORD plaintext_len, // IN - Plaintext length. - const BYTE associated_data[], // IN - Associated Data included in authentication, but not encryption. - unsigned short associated_data_len, // IN - Associated Data length in bytes. - const BYTE nonce[], // IN - The Nonce to be used for encryption. - unsigned short nonce_len, // IN - Nonce length in bytes. - BYTE ciphertext[], // OUT - Ciphertext, a concatination of the plaintext and the MAC. - WORD *ciphertext_len, // OUT - The length of the ciphertext, always plaintext_len + mac_len. - WORD mac_len, // IN - The desired length of the MAC, must be 4, 6, 8, 10, 12, 14, or 16. - const BYTE key[], // IN - The AES key for encryption. - int keysize); // IN - The length of the key in bits. Valid values are 128, 192, 256. - +int +aes_encrypt_ccm(const BYTE plaintext[], // IN - Plaintext. + WORD plaintext_len, // IN - Plaintext length. + const BYTE associated_data[], // IN - Associated Data included in authentication, but not encryption. + unsigned short associated_data_len, // IN - Associated Data length in bytes. + const BYTE nonce[], // IN - The Nonce to be used for encryption. + unsigned short nonce_len, // IN - Nonce length in bytes. + BYTE ciphertext[], // OUT - Ciphertext, a concatination of the plaintext and the MAC. + WORD *ciphertext_len, // OUT - The length of the ciphertext, always plaintext_len + mac_len. + WORD mac_len, // IN - The desired length of the MAC, must be 4, 6, 8, 10, 12, 14, or 16. + const BYTE key[], // IN - The AES key for encryption. + int keysize); // IN - The length of the key in bits. Valid values are 128, 192, 256. + // Returns True if the input parameters do not violate any constraint. // Use mac_auth to ensure decryption/validation was preformed correctly. // If authentication does not succeed, the plaintext is zeroed out. To overwride // this, call with mac_auth = NULL. The proper proceedure is to decrypt with // authentication enabled (mac_auth != NULL) and make a second call to that // ignores authentication explicitly if the first call failes. -int aes_decrypt_ccm(const BYTE ciphertext[], // IN - Ciphertext, the concatination of encrypted plaintext and MAC. - WORD ciphertext_len, // IN - Ciphertext length in bytes. - const BYTE assoc[], // IN - The Associated Data, required for authentication. - unsigned short assoc_len, // IN - Associated Data length in bytes. - const BYTE nonce[], // IN - The Nonce to use for decryption, same one as for encryption. - unsigned short nonce_len, // IN - Nonce length in bytes. - BYTE plaintext[], // OUT - The plaintext that was decrypted. Will need to be large enough to hold ciphertext_len - mac_len. - WORD *plaintext_len, // OUT - Length in bytes of the output plaintext, always ciphertext_len - mac_len . - WORD mac_len, // IN - The length of the MAC that was calculated. - int *mac_auth, // OUT - TRUE if authentication succeeded, FALSE if it did not. NULL pointer will ignore the authentication. - const BYTE key[], // IN - The AES key for decryption. - int keysize); // IN - The length of the key in BITS. Valid values are 128, 192, 256. - -#endif // AES_H +int +aes_decrypt_ccm( + const BYTE ciphertext[], // IN - Ciphertext, the concatination of encrypted plaintext and MAC. + WORD ciphertext_len, // IN - Ciphertext length in bytes. + const BYTE assoc[], // IN - The Associated Data, required for authentication. + unsigned short assoc_len, // IN - Associated Data length in bytes. + const BYTE nonce[], // IN - The Nonce to use for decryption, same one as for encryption. + unsigned short nonce_len, // IN - Nonce length in bytes. + BYTE plaintext[], // OUT - The plaintext that was decrypted. Will need to be large enough to hold ciphertext_len - + // mac_len. + WORD *plaintext_len, // OUT - Length in bytes of the output plaintext, always ciphertext_len - mac_len . + WORD mac_len, // IN - The length of the MAC that was calculated. + int *mac_auth, // OUT - TRUE if authentication succeeded, FALSE if it did not. NULL pointer will ignore the + // authentication. + const BYTE key[], // IN - The AES key for decryption. + int keysize); // IN - The length of the key in BITS. Valid values are 128, 192, 256. + +#endif // AES_H diff --git a/examples/aes_decrypt/aesdecrypt.c b/examples/aes_decrypt/aesdecrypt.c index c36a46ec9..74d04195f 100644 --- a/examples/aes_decrypt/aesdecrypt.c +++ b/examples/aes_decrypt/aesdecrypt.c @@ -39,26 +39,26 @@ * aesdecrypt.c - Decrypts UDP packets encrypted with AES ********************************************************************/ -#include -#include -#include +#include +#include #include #include -#include -#include +#include +#include #include -#include #include +#include +#include #include -#include +#include #include +#include #include -#include +#include "aes.h" #include "onvm_nflib.h" #include "onvm_pkt_helper.h" -#include "aes.h" #define NF_TAG "aes_encrypt" @@ -68,17 +68,13 @@ struct onvm_nf_info *nf_info; /* number of package between each print */ static uint32_t print_delay = 1000000; - static uint32_t destination; /* AES encryption parameters */ -BYTE key[1][32] = { - {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4} -}; -BYTE iv[1][16] = { - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f} -}; -WORD key_schedule[60]; //word Schedule +BYTE key[1][32] = {{0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4}}; +BYTE iv[1][16] = {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}}; +WORD key_schedule[60]; // word Schedule /* * Print a usage message @@ -102,27 +98,27 @@ parse_app_args(int argc, char *argv[], const char *progname) { while ((c = getopt(argc, argv, "d:p:")) != -1) { switch (c) { - case 'd': - destination = strtoul(optarg, NULL, 10); - dst_flag = 1; - break; - case 'p': - print_delay = strtoul(optarg, NULL, 10); - break; - case '?': - usage(progname); - if (optopt == 'd') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (optopt == 'p') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (isprint(optopt)) - RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); - else - RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); - return -1; - default: - usage(progname); - return -1; + case 'd': + destination = strtoul(optarg, NULL, 10); + dst_flag = 1; + break; + case 'p': + print_delay = strtoul(optarg, NULL, 10); + break; + case '?': + usage(progname); + if (optopt == 'd') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (optopt == 'p') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (isprint(optopt)) + RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); + else + RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); + return -1; + default: + usage(progname); + return -1; } } @@ -141,11 +137,11 @@ parse_app_args(int argc, char *argv[], const char *progname) { * than one lcore enabled. */ static void -do_stats_display(struct rte_mbuf* pkt) { - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; +do_stats_display(struct rte_mbuf *pkt) { + const char clr[] = {27, '[', '2', 'J', '\0'}; + const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'}; static uint64_t pkt_process = 0; - struct ipv4_hdr* ip; + struct ipv4_hdr *ip; pkt_process += print_delay; @@ -156,21 +152,21 @@ do_stats_display(struct rte_mbuf* pkt) { printf("-----\n"); printf("Port : %d\n", pkt->port); printf("Size : %d\n", pkt->pkt_len); - printf("N° : %"PRIu64"\n", pkt_process); + printf("N° : %" PRIu64 "\n", pkt_process); printf("\n\n"); ip = onvm_pkt_ipv4_hdr(pkt); if (ip != NULL) { - struct udp_hdr *udp; + struct udp_hdr *udp; onvm_pkt_print(pkt); - /* Check if we have a valid UDP packet */ - udp = onvm_pkt_udp_hdr(pkt); - if (udp != NULL) { - uint8_t * pkt_data; - pkt_data = ((uint8_t *) udp) + sizeof(struct udp_hdr); - printf("Payload : %.32s\n", pkt_data); - } + /* Check if we have a valid UDP packet */ + udp = onvm_pkt_udp_hdr(pkt); + if (udp != NULL) { + uint8_t *pkt_data; + pkt_data = ((uint8_t *)udp) + sizeof(struct udp_hdr); + printf("Payload : %.32s\n", pkt_data); + } } else { printf("No IP4 header found\n"); } @@ -178,33 +174,33 @@ do_stats_display(struct rte_mbuf* pkt) { static int packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__((unused)) struct onvm_nf_info *nf_info) { - struct udp_hdr *udp; + struct udp_hdr *udp; static uint32_t counter = 0; - /* Check if we have a valid UDP packet */ - udp = onvm_pkt_udp_hdr(pkt); - if (udp != NULL) { - uint8_t * pkt_data; - uint8_t * eth; - uint16_t plen; - uint16_t hlen; - - /* Get at the payload */ - pkt_data = ((uint8_t *) udp) + sizeof(struct udp_hdr); - /* Calculate length */ - eth = rte_pktmbuf_mtod(pkt, uint8_t *); - hlen = pkt_data - eth; - plen = pkt->pkt_len - hlen; - - /* Encrypt. */ - /* IV should change with every packet, but we don't have any - * way to send it to the other side. */ - aes_decrypt_ctr(pkt_data, plen, pkt_data, key_schedule, 256, iv[0]); - if (counter == 0) { - printf("Decrypted %d bytes at offset %d (%ld)\n", - plen, hlen, sizeof(struct ether_hdr) + sizeof(struct ipv4_hdr) + sizeof(struct udp_hdr)); - } - } + /* Check if we have a valid UDP packet */ + udp = onvm_pkt_udp_hdr(pkt); + if (udp != NULL) { + uint8_t *pkt_data; + uint8_t *eth; + uint16_t plen; + uint16_t hlen; + + /* Get at the payload */ + pkt_data = ((uint8_t *)udp) + sizeof(struct udp_hdr); + /* Calculate length */ + eth = rte_pktmbuf_mtod(pkt, uint8_t *); + hlen = pkt_data - eth; + plen = pkt->pkt_len - hlen; + + /* Encrypt. */ + /* IV should change with every packet, but we don't have any + * way to send it to the other side. */ + aes_decrypt_ctr(pkt_data, plen, pkt_data, key_schedule, 256, iv[0]); + if (counter == 0) { + printf("Decrypted %d bytes at offset %d (%ld)\n", plen, hlen, + sizeof(struct ether_hdr) + sizeof(struct ipv4_hdr) + sizeof(struct udp_hdr)); + } + } if (++counter == print_delay) { do_stats_display(pkt); @@ -216,8 +212,8 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( return 0; } - -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; @@ -232,10 +228,10 @@ int main(int argc, char *argv[]) { rte_exit(EXIT_FAILURE, "Invalid command-line arguments\n"); } - /* Initialise encryption engine. Key should be configurable. */ - aes_key_setup(key[0], key_schedule, 256); + /* Initialise encryption engine. Key should be configurable. */ + aes_key_setup(key[0], key_schedule, 256); - onvm_nflib_run(nf_info, &packet_handler); + onvm_nflib_run(nf_info, &packet_handler); printf("If we reach here, program is ending\n"); return 0; } diff --git a/examples/aes_encrypt/aes.c b/examples/aes_encrypt/aes.c index 61848c10f..874797209 100644 --- a/examples/aes_encrypt/aes.c +++ b/examples/aes_encrypt/aes.c @@ -54,82 +54,94 @@ * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf * Source: https://github.com/B-Con/crypto-algorithms *********************************************************************/ - + /*************************** HEADER FILES ***************************/ -#include -#include #include "aes.h" - +#include +#include + #include - + /****************************** MACROS ******************************/ // The least significant byte of the word is rotated to the end. #define KE_ROTWORD(x) (((x) << 8) | ((x) >> 24)) - -#define TRUE 1 + +#define TRUE 1 #define FALSE 0 - + /**************************** DATA TYPES ****************************/ #define AES_128_ROUNDS 10 #define AES_192_ROUNDS 12 #define AES_256_ROUNDS 14 - + /*********************** FUNCTION DECLARATIONS **********************/ -void ccm_prepare_first_ctr_blk(BYTE counter[], const BYTE nonce[], int nonce_len, int payload_len_store_size); -void ccm_prepare_first_format_blk(BYTE buf[], int assoc_len, int payload_len, int payload_len_store_size, int mac_len, const BYTE nonce[], int nonce_len); -void ccm_format_assoc_data(BYTE buf[], int *end_of_buf, const BYTE assoc[], int assoc_len); -void ccm_format_payload_data(BYTE buf[], int *end_of_buf, const BYTE payload[], int payload_len); -void xor_buf(const BYTE in[], BYTE out[], size_t len); -WORD SubWord(WORD word); -void AddRoundKey(BYTE state[][4], const WORD w[]); -void SubBytes(BYTE state[][4]); -void InvSubBytes(BYTE state[][4]); -void ShiftRows(BYTE state[][4]); -void MixColumns(BYTE state[][4]); -void InvMixColumns(BYTE state[][4]); -void InvShiftRows(BYTE state[][4]); - +void +ccm_prepare_first_ctr_blk(BYTE counter[], const BYTE nonce[], int nonce_len, int payload_len_store_size); +void +ccm_prepare_first_format_blk(BYTE buf[], int assoc_len, int payload_len, int payload_len_store_size, int mac_len, + const BYTE nonce[], int nonce_len); +void +ccm_format_assoc_data(BYTE buf[], int *end_of_buf, const BYTE assoc[], int assoc_len); +void +ccm_format_payload_data(BYTE buf[], int *end_of_buf, const BYTE payload[], int payload_len); +void +xor_buf(const BYTE in[], BYTE out[], size_t len); +WORD +SubWord(WORD word); +void +AddRoundKey(BYTE state[][4], const WORD w[]); +void +SubBytes(BYTE state[][4]); +void +InvSubBytes(BYTE state[][4]); +void +ShiftRows(BYTE state[][4]); +void +MixColumns(BYTE state[][4]); +void +InvMixColumns(BYTE state[][4]); +void +InvShiftRows(BYTE state[][4]); + /**************************** VARIABLES *****************************/ // This is the specified AES SBox. To look up a substitution value, put the first // nibble in the first index (row) and the second nibble in the second index (column). static const BYTE aes_sbox[16][16] = { - {0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76}, - {0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0}, - {0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15}, - {0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75}, - {0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84}, - {0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF}, - {0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8}, - {0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2}, - {0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73}, - {0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB}, - {0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79}, - {0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08}, - {0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A}, - {0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E}, - {0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF}, - {0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16} -}; - + {0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76}, + {0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0}, + {0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15}, + {0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75}, + {0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84}, + {0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF}, + {0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8}, + {0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2}, + {0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73}, + {0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB}, + {0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79}, + {0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08}, + {0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A}, + {0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E}, + {0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF}, + {0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16}}; + static const BYTE aes_invsbox[16][16] = { - {0x52,0x09,0x6A,0xD5,0x30,0x36,0xA5,0x38,0xBF,0x40,0xA3,0x9E,0x81,0xF3,0xD7,0xFB}, - {0x7C,0xE3,0x39,0x82,0x9B,0x2F,0xFF,0x87,0x34,0x8E,0x43,0x44,0xC4,0xDE,0xE9,0xCB}, - {0x54,0x7B,0x94,0x32,0xA6,0xC2,0x23,0x3D,0xEE,0x4C,0x95,0x0B,0x42,0xFA,0xC3,0x4E}, - {0x08,0x2E,0xA1,0x66,0x28,0xD9,0x24,0xB2,0x76,0x5B,0xA2,0x49,0x6D,0x8B,0xD1,0x25}, - {0x72,0xF8,0xF6,0x64,0x86,0x68,0x98,0x16,0xD4,0xA4,0x5C,0xCC,0x5D,0x65,0xB6,0x92}, - {0x6C,0x70,0x48,0x50,0xFD,0xED,0xB9,0xDA,0x5E,0x15,0x46,0x57,0xA7,0x8D,0x9D,0x84}, - {0x90,0xD8,0xAB,0x00,0x8C,0xBC,0xD3,0x0A,0xF7,0xE4,0x58,0x05,0xB8,0xB3,0x45,0x06}, - {0xD0,0x2C,0x1E,0x8F,0xCA,0x3F,0x0F,0x02,0xC1,0xAF,0xBD,0x03,0x01,0x13,0x8A,0x6B}, - {0x3A,0x91,0x11,0x41,0x4F,0x67,0xDC,0xEA,0x97,0xF2,0xCF,0xCE,0xF0,0xB4,0xE6,0x73}, - {0x96,0xAC,0x74,0x22,0xE7,0xAD,0x35,0x85,0xE2,0xF9,0x37,0xE8,0x1C,0x75,0xDF,0x6E}, - {0x47,0xF1,0x1A,0x71,0x1D,0x29,0xC5,0x89,0x6F,0xB7,0x62,0x0E,0xAA,0x18,0xBE,0x1B}, - {0xFC,0x56,0x3E,0x4B,0xC6,0xD2,0x79,0x20,0x9A,0xDB,0xC0,0xFE,0x78,0xCD,0x5A,0xF4}, - {0x1F,0xDD,0xA8,0x33,0x88,0x07,0xC7,0x31,0xB1,0x12,0x10,0x59,0x27,0x80,0xEC,0x5F}, - {0x60,0x51,0x7F,0xA9,0x19,0xB5,0x4A,0x0D,0x2D,0xE5,0x7A,0x9F,0x93,0xC9,0x9C,0xEF}, - {0xA0,0xE0,0x3B,0x4D,0xAE,0x2A,0xF5,0xB0,0xC8,0xEB,0xBB,0x3C,0x83,0x53,0x99,0x61}, - {0x17,0x2B,0x04,0x7E,0xBA,0x77,0xD6,0x26,0xE1,0x69,0x14,0x63,0x55,0x21,0x0C,0x7D} -}; - + {0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB}, + {0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB}, + {0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E}, + {0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25}, + {0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92}, + {0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84}, + {0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06}, + {0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B}, + {0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73}, + {0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E}, + {0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B}, + {0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4}, + {0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F}, + {0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF}, + {0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61}, + {0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D}}; + // This table stores pre-calculated values for all possible GF(2^8) calculations.This // table is only used by the (Inv)MixColumns steps. // USAGE: The second index (column) is the coefficient of multiplication. Only 7 different @@ -137,986 +149,1041 @@ static const BYTE aes_invsbox[16][16] = { // 1 is negligible leaving only 6 coefficients. Each column of the table is devoted to one // of these coefficients, in the ascending order of value, from values 0x00 to 0xFF. static const BYTE gf_mul[256][6] = { - {0x00,0x00,0x00,0x00,0x00,0x00},{0x02,0x03,0x09,0x0b,0x0d,0x0e}, - {0x04,0x06,0x12,0x16,0x1a,0x1c},{0x06,0x05,0x1b,0x1d,0x17,0x12}, - {0x08,0x0c,0x24,0x2c,0x34,0x38},{0x0a,0x0f,0x2d,0x27,0x39,0x36}, - {0x0c,0x0a,0x36,0x3a,0x2e,0x24},{0x0e,0x09,0x3f,0x31,0x23,0x2a}, - {0x10,0x18,0x48,0x58,0x68,0x70},{0x12,0x1b,0x41,0x53,0x65,0x7e}, - {0x14,0x1e,0x5a,0x4e,0x72,0x6c},{0x16,0x1d,0x53,0x45,0x7f,0x62}, - {0x18,0x14,0x6c,0x74,0x5c,0x48},{0x1a,0x17,0x65,0x7f,0x51,0x46}, - {0x1c,0x12,0x7e,0x62,0x46,0x54},{0x1e,0x11,0x77,0x69,0x4b,0x5a}, - {0x20,0x30,0x90,0xb0,0xd0,0xe0},{0x22,0x33,0x99,0xbb,0xdd,0xee}, - {0x24,0x36,0x82,0xa6,0xca,0xfc},{0x26,0x35,0x8b,0xad,0xc7,0xf2}, - {0x28,0x3c,0xb4,0x9c,0xe4,0xd8},{0x2a,0x3f,0xbd,0x97,0xe9,0xd6}, - {0x2c,0x3a,0xa6,0x8a,0xfe,0xc4},{0x2e,0x39,0xaf,0x81,0xf3,0xca}, - {0x30,0x28,0xd8,0xe8,0xb8,0x90},{0x32,0x2b,0xd1,0xe3,0xb5,0x9e}, - {0x34,0x2e,0xca,0xfe,0xa2,0x8c},{0x36,0x2d,0xc3,0xf5,0xaf,0x82}, - {0x38,0x24,0xfc,0xc4,0x8c,0xa8},{0x3a,0x27,0xf5,0xcf,0x81,0xa6}, - {0x3c,0x22,0xee,0xd2,0x96,0xb4},{0x3e,0x21,0xe7,0xd9,0x9b,0xba}, - {0x40,0x60,0x3b,0x7b,0xbb,0xdb},{0x42,0x63,0x32,0x70,0xb6,0xd5}, - {0x44,0x66,0x29,0x6d,0xa1,0xc7},{0x46,0x65,0x20,0x66,0xac,0xc9}, - {0x48,0x6c,0x1f,0x57,0x8f,0xe3},{0x4a,0x6f,0x16,0x5c,0x82,0xed}, - {0x4c,0x6a,0x0d,0x41,0x95,0xff},{0x4e,0x69,0x04,0x4a,0x98,0xf1}, - {0x50,0x78,0x73,0x23,0xd3,0xab},{0x52,0x7b,0x7a,0x28,0xde,0xa5}, - {0x54,0x7e,0x61,0x35,0xc9,0xb7},{0x56,0x7d,0x68,0x3e,0xc4,0xb9}, - {0x58,0x74,0x57,0x0f,0xe7,0x93},{0x5a,0x77,0x5e,0x04,0xea,0x9d}, - {0x5c,0x72,0x45,0x19,0xfd,0x8f},{0x5e,0x71,0x4c,0x12,0xf0,0x81}, - {0x60,0x50,0xab,0xcb,0x6b,0x3b},{0x62,0x53,0xa2,0xc0,0x66,0x35}, - {0x64,0x56,0xb9,0xdd,0x71,0x27},{0x66,0x55,0xb0,0xd6,0x7c,0x29}, - {0x68,0x5c,0x8f,0xe7,0x5f,0x03},{0x6a,0x5f,0x86,0xec,0x52,0x0d}, - {0x6c,0x5a,0x9d,0xf1,0x45,0x1f},{0x6e,0x59,0x94,0xfa,0x48,0x11}, - {0x70,0x48,0xe3,0x93,0x03,0x4b},{0x72,0x4b,0xea,0x98,0x0e,0x45}, - {0x74,0x4e,0xf1,0x85,0x19,0x57},{0x76,0x4d,0xf8,0x8e,0x14,0x59}, - {0x78,0x44,0xc7,0xbf,0x37,0x73},{0x7a,0x47,0xce,0xb4,0x3a,0x7d}, - {0x7c,0x42,0xd5,0xa9,0x2d,0x6f},{0x7e,0x41,0xdc,0xa2,0x20,0x61}, - {0x80,0xc0,0x76,0xf6,0x6d,0xad},{0x82,0xc3,0x7f,0xfd,0x60,0xa3}, - {0x84,0xc6,0x64,0xe0,0x77,0xb1},{0x86,0xc5,0x6d,0xeb,0x7a,0xbf}, - {0x88,0xcc,0x52,0xda,0x59,0x95},{0x8a,0xcf,0x5b,0xd1,0x54,0x9b}, - {0x8c,0xca,0x40,0xcc,0x43,0x89},{0x8e,0xc9,0x49,0xc7,0x4e,0x87}, - {0x90,0xd8,0x3e,0xae,0x05,0xdd},{0x92,0xdb,0x37,0xa5,0x08,0xd3}, - {0x94,0xde,0x2c,0xb8,0x1f,0xc1},{0x96,0xdd,0x25,0xb3,0x12,0xcf}, - {0x98,0xd4,0x1a,0x82,0x31,0xe5},{0x9a,0xd7,0x13,0x89,0x3c,0xeb}, - {0x9c,0xd2,0x08,0x94,0x2b,0xf9},{0x9e,0xd1,0x01,0x9f,0x26,0xf7}, - {0xa0,0xf0,0xe6,0x46,0xbd,0x4d},{0xa2,0xf3,0xef,0x4d,0xb0,0x43}, - {0xa4,0xf6,0xf4,0x50,0xa7,0x51},{0xa6,0xf5,0xfd,0x5b,0xaa,0x5f}, - {0xa8,0xfc,0xc2,0x6a,0x89,0x75},{0xaa,0xff,0xcb,0x61,0x84,0x7b}, - {0xac,0xfa,0xd0,0x7c,0x93,0x69},{0xae,0xf9,0xd9,0x77,0x9e,0x67}, - {0xb0,0xe8,0xae,0x1e,0xd5,0x3d},{0xb2,0xeb,0xa7,0x15,0xd8,0x33}, - {0xb4,0xee,0xbc,0x08,0xcf,0x21},{0xb6,0xed,0xb5,0x03,0xc2,0x2f}, - {0xb8,0xe4,0x8a,0x32,0xe1,0x05},{0xba,0xe7,0x83,0x39,0xec,0x0b}, - {0xbc,0xe2,0x98,0x24,0xfb,0x19},{0xbe,0xe1,0x91,0x2f,0xf6,0x17}, - {0xc0,0xa0,0x4d,0x8d,0xd6,0x76},{0xc2,0xa3,0x44,0x86,0xdb,0x78}, - {0xc4,0xa6,0x5f,0x9b,0xcc,0x6a},{0xc6,0xa5,0x56,0x90,0xc1,0x64}, - {0xc8,0xac,0x69,0xa1,0xe2,0x4e},{0xca,0xaf,0x60,0xaa,0xef,0x40}, - {0xcc,0xaa,0x7b,0xb7,0xf8,0x52},{0xce,0xa9,0x72,0xbc,0xf5,0x5c}, - {0xd0,0xb8,0x05,0xd5,0xbe,0x06},{0xd2,0xbb,0x0c,0xde,0xb3,0x08}, - {0xd4,0xbe,0x17,0xc3,0xa4,0x1a},{0xd6,0xbd,0x1e,0xc8,0xa9,0x14}, - {0xd8,0xb4,0x21,0xf9,0x8a,0x3e},{0xda,0xb7,0x28,0xf2,0x87,0x30}, - {0xdc,0xb2,0x33,0xef,0x90,0x22},{0xde,0xb1,0x3a,0xe4,0x9d,0x2c}, - {0xe0,0x90,0xdd,0x3d,0x06,0x96},{0xe2,0x93,0xd4,0x36,0x0b,0x98}, - {0xe4,0x96,0xcf,0x2b,0x1c,0x8a},{0xe6,0x95,0xc6,0x20,0x11,0x84}, - {0xe8,0x9c,0xf9,0x11,0x32,0xae},{0xea,0x9f,0xf0,0x1a,0x3f,0xa0}, - {0xec,0x9a,0xeb,0x07,0x28,0xb2},{0xee,0x99,0xe2,0x0c,0x25,0xbc}, - {0xf0,0x88,0x95,0x65,0x6e,0xe6},{0xf2,0x8b,0x9c,0x6e,0x63,0xe8}, - {0xf4,0x8e,0x87,0x73,0x74,0xfa},{0xf6,0x8d,0x8e,0x78,0x79,0xf4}, - {0xf8,0x84,0xb1,0x49,0x5a,0xde},{0xfa,0x87,0xb8,0x42,0x57,0xd0}, - {0xfc,0x82,0xa3,0x5f,0x40,0xc2},{0xfe,0x81,0xaa,0x54,0x4d,0xcc}, - {0x1b,0x9b,0xec,0xf7,0xda,0x41},{0x19,0x98,0xe5,0xfc,0xd7,0x4f}, - {0x1f,0x9d,0xfe,0xe1,0xc0,0x5d},{0x1d,0x9e,0xf7,0xea,0xcd,0x53}, - {0x13,0x97,0xc8,0xdb,0xee,0x79},{0x11,0x94,0xc1,0xd0,0xe3,0x77}, - {0x17,0x91,0xda,0xcd,0xf4,0x65},{0x15,0x92,0xd3,0xc6,0xf9,0x6b}, - {0x0b,0x83,0xa4,0xaf,0xb2,0x31},{0x09,0x80,0xad,0xa4,0xbf,0x3f}, - {0x0f,0x85,0xb6,0xb9,0xa8,0x2d},{0x0d,0x86,0xbf,0xb2,0xa5,0x23}, - {0x03,0x8f,0x80,0x83,0x86,0x09},{0x01,0x8c,0x89,0x88,0x8b,0x07}, - {0x07,0x89,0x92,0x95,0x9c,0x15},{0x05,0x8a,0x9b,0x9e,0x91,0x1b}, - {0x3b,0xab,0x7c,0x47,0x0a,0xa1},{0x39,0xa8,0x75,0x4c,0x07,0xaf}, - {0x3f,0xad,0x6e,0x51,0x10,0xbd},{0x3d,0xae,0x67,0x5a,0x1d,0xb3}, - {0x33,0xa7,0x58,0x6b,0x3e,0x99},{0x31,0xa4,0x51,0x60,0x33,0x97}, - {0x37,0xa1,0x4a,0x7d,0x24,0x85},{0x35,0xa2,0x43,0x76,0x29,0x8b}, - {0x2b,0xb3,0x34,0x1f,0x62,0xd1},{0x29,0xb0,0x3d,0x14,0x6f,0xdf}, - {0x2f,0xb5,0x26,0x09,0x78,0xcd},{0x2d,0xb6,0x2f,0x02,0x75,0xc3}, - {0x23,0xbf,0x10,0x33,0x56,0xe9},{0x21,0xbc,0x19,0x38,0x5b,0xe7}, - {0x27,0xb9,0x02,0x25,0x4c,0xf5},{0x25,0xba,0x0b,0x2e,0x41,0xfb}, - {0x5b,0xfb,0xd7,0x8c,0x61,0x9a},{0x59,0xf8,0xde,0x87,0x6c,0x94}, - {0x5f,0xfd,0xc5,0x9a,0x7b,0x86},{0x5d,0xfe,0xcc,0x91,0x76,0x88}, - {0x53,0xf7,0xf3,0xa0,0x55,0xa2},{0x51,0xf4,0xfa,0xab,0x58,0xac}, - {0x57,0xf1,0xe1,0xb6,0x4f,0xbe},{0x55,0xf2,0xe8,0xbd,0x42,0xb0}, - {0x4b,0xe3,0x9f,0xd4,0x09,0xea},{0x49,0xe0,0x96,0xdf,0x04,0xe4}, - {0x4f,0xe5,0x8d,0xc2,0x13,0xf6},{0x4d,0xe6,0x84,0xc9,0x1e,0xf8}, - {0x43,0xef,0xbb,0xf8,0x3d,0xd2},{0x41,0xec,0xb2,0xf3,0x30,0xdc}, - {0x47,0xe9,0xa9,0xee,0x27,0xce},{0x45,0xea,0xa0,0xe5,0x2a,0xc0}, - {0x7b,0xcb,0x47,0x3c,0xb1,0x7a},{0x79,0xc8,0x4e,0x37,0xbc,0x74}, - {0x7f,0xcd,0x55,0x2a,0xab,0x66},{0x7d,0xce,0x5c,0x21,0xa6,0x68}, - {0x73,0xc7,0x63,0x10,0x85,0x42},{0x71,0xc4,0x6a,0x1b,0x88,0x4c}, - {0x77,0xc1,0x71,0x06,0x9f,0x5e},{0x75,0xc2,0x78,0x0d,0x92,0x50}, - {0x6b,0xd3,0x0f,0x64,0xd9,0x0a},{0x69,0xd0,0x06,0x6f,0xd4,0x04}, - {0x6f,0xd5,0x1d,0x72,0xc3,0x16},{0x6d,0xd6,0x14,0x79,0xce,0x18}, - {0x63,0xdf,0x2b,0x48,0xed,0x32},{0x61,0xdc,0x22,0x43,0xe0,0x3c}, - {0x67,0xd9,0x39,0x5e,0xf7,0x2e},{0x65,0xda,0x30,0x55,0xfa,0x20}, - {0x9b,0x5b,0x9a,0x01,0xb7,0xec},{0x99,0x58,0x93,0x0a,0xba,0xe2}, - {0x9f,0x5d,0x88,0x17,0xad,0xf0},{0x9d,0x5e,0x81,0x1c,0xa0,0xfe}, - {0x93,0x57,0xbe,0x2d,0x83,0xd4},{0x91,0x54,0xb7,0x26,0x8e,0xda}, - {0x97,0x51,0xac,0x3b,0x99,0xc8},{0x95,0x52,0xa5,0x30,0x94,0xc6}, - {0x8b,0x43,0xd2,0x59,0xdf,0x9c},{0x89,0x40,0xdb,0x52,0xd2,0x92}, - {0x8f,0x45,0xc0,0x4f,0xc5,0x80},{0x8d,0x46,0xc9,0x44,0xc8,0x8e}, - {0x83,0x4f,0xf6,0x75,0xeb,0xa4},{0x81,0x4c,0xff,0x7e,0xe6,0xaa}, - {0x87,0x49,0xe4,0x63,0xf1,0xb8},{0x85,0x4a,0xed,0x68,0xfc,0xb6}, - {0xbb,0x6b,0x0a,0xb1,0x67,0x0c},{0xb9,0x68,0x03,0xba,0x6a,0x02}, - {0xbf,0x6d,0x18,0xa7,0x7d,0x10},{0xbd,0x6e,0x11,0xac,0x70,0x1e}, - {0xb3,0x67,0x2e,0x9d,0x53,0x34},{0xb1,0x64,0x27,0x96,0x5e,0x3a}, - {0xb7,0x61,0x3c,0x8b,0x49,0x28},{0xb5,0x62,0x35,0x80,0x44,0x26}, - {0xab,0x73,0x42,0xe9,0x0f,0x7c},{0xa9,0x70,0x4b,0xe2,0x02,0x72}, - {0xaf,0x75,0x50,0xff,0x15,0x60},{0xad,0x76,0x59,0xf4,0x18,0x6e}, - {0xa3,0x7f,0x66,0xc5,0x3b,0x44},{0xa1,0x7c,0x6f,0xce,0x36,0x4a}, - {0xa7,0x79,0x74,0xd3,0x21,0x58},{0xa5,0x7a,0x7d,0xd8,0x2c,0x56}, - {0xdb,0x3b,0xa1,0x7a,0x0c,0x37},{0xd9,0x38,0xa8,0x71,0x01,0x39}, - {0xdf,0x3d,0xb3,0x6c,0x16,0x2b},{0xdd,0x3e,0xba,0x67,0x1b,0x25}, - {0xd3,0x37,0x85,0x56,0x38,0x0f},{0xd1,0x34,0x8c,0x5d,0x35,0x01}, - {0xd7,0x31,0x97,0x40,0x22,0x13},{0xd5,0x32,0x9e,0x4b,0x2f,0x1d}, - {0xcb,0x23,0xe9,0x22,0x64,0x47},{0xc9,0x20,0xe0,0x29,0x69,0x49}, - {0xcf,0x25,0xfb,0x34,0x7e,0x5b},{0xcd,0x26,0xf2,0x3f,0x73,0x55}, - {0xc3,0x2f,0xcd,0x0e,0x50,0x7f},{0xc1,0x2c,0xc4,0x05,0x5d,0x71}, - {0xc7,0x29,0xdf,0x18,0x4a,0x63},{0xc5,0x2a,0xd6,0x13,0x47,0x6d}, - {0xfb,0x0b,0x31,0xca,0xdc,0xd7},{0xf9,0x08,0x38,0xc1,0xd1,0xd9}, - {0xff,0x0d,0x23,0xdc,0xc6,0xcb},{0xfd,0x0e,0x2a,0xd7,0xcb,0xc5}, - {0xf3,0x07,0x15,0xe6,0xe8,0xef},{0xf1,0x04,0x1c,0xed,0xe5,0xe1}, - {0xf7,0x01,0x07,0xf0,0xf2,0xf3},{0xf5,0x02,0x0e,0xfb,0xff,0xfd}, - {0xeb,0x13,0x79,0x92,0xb4,0xa7},{0xe9,0x10,0x70,0x99,0xb9,0xa9}, - {0xef,0x15,0x6b,0x84,0xae,0xbb},{0xed,0x16,0x62,0x8f,0xa3,0xb5}, - {0xe3,0x1f,0x5d,0xbe,0x80,0x9f},{0xe1,0x1c,0x54,0xb5,0x8d,0x91}, - {0xe7,0x19,0x4f,0xa8,0x9a,0x83},{0xe5,0x1a,0x46,0xa3,0x97,0x8d} -}; - + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x02, 0x03, 0x09, 0x0b, 0x0d, 0x0e}, {0x04, 0x06, 0x12, 0x16, 0x1a, 0x1c}, + {0x06, 0x05, 0x1b, 0x1d, 0x17, 0x12}, {0x08, 0x0c, 0x24, 0x2c, 0x34, 0x38}, {0x0a, 0x0f, 0x2d, 0x27, 0x39, 0x36}, + {0x0c, 0x0a, 0x36, 0x3a, 0x2e, 0x24}, {0x0e, 0x09, 0x3f, 0x31, 0x23, 0x2a}, {0x10, 0x18, 0x48, 0x58, 0x68, 0x70}, + {0x12, 0x1b, 0x41, 0x53, 0x65, 0x7e}, {0x14, 0x1e, 0x5a, 0x4e, 0x72, 0x6c}, {0x16, 0x1d, 0x53, 0x45, 0x7f, 0x62}, + {0x18, 0x14, 0x6c, 0x74, 0x5c, 0x48}, {0x1a, 0x17, 0x65, 0x7f, 0x51, 0x46}, {0x1c, 0x12, 0x7e, 0x62, 0x46, 0x54}, + {0x1e, 0x11, 0x77, 0x69, 0x4b, 0x5a}, {0x20, 0x30, 0x90, 0xb0, 0xd0, 0xe0}, {0x22, 0x33, 0x99, 0xbb, 0xdd, 0xee}, + {0x24, 0x36, 0x82, 0xa6, 0xca, 0xfc}, {0x26, 0x35, 0x8b, 0xad, 0xc7, 0xf2}, {0x28, 0x3c, 0xb4, 0x9c, 0xe4, 0xd8}, + {0x2a, 0x3f, 0xbd, 0x97, 0xe9, 0xd6}, {0x2c, 0x3a, 0xa6, 0x8a, 0xfe, 0xc4}, {0x2e, 0x39, 0xaf, 0x81, 0xf3, 0xca}, + {0x30, 0x28, 0xd8, 0xe8, 0xb8, 0x90}, {0x32, 0x2b, 0xd1, 0xe3, 0xb5, 0x9e}, {0x34, 0x2e, 0xca, 0xfe, 0xa2, 0x8c}, + {0x36, 0x2d, 0xc3, 0xf5, 0xaf, 0x82}, {0x38, 0x24, 0xfc, 0xc4, 0x8c, 0xa8}, {0x3a, 0x27, 0xf5, 0xcf, 0x81, 0xa6}, + {0x3c, 0x22, 0xee, 0xd2, 0x96, 0xb4}, {0x3e, 0x21, 0xe7, 0xd9, 0x9b, 0xba}, {0x40, 0x60, 0x3b, 0x7b, 0xbb, 0xdb}, + {0x42, 0x63, 0x32, 0x70, 0xb6, 0xd5}, {0x44, 0x66, 0x29, 0x6d, 0xa1, 0xc7}, {0x46, 0x65, 0x20, 0x66, 0xac, 0xc9}, + {0x48, 0x6c, 0x1f, 0x57, 0x8f, 0xe3}, {0x4a, 0x6f, 0x16, 0x5c, 0x82, 0xed}, {0x4c, 0x6a, 0x0d, 0x41, 0x95, 0xff}, + {0x4e, 0x69, 0x04, 0x4a, 0x98, 0xf1}, {0x50, 0x78, 0x73, 0x23, 0xd3, 0xab}, {0x52, 0x7b, 0x7a, 0x28, 0xde, 0xa5}, + {0x54, 0x7e, 0x61, 0x35, 0xc9, 0xb7}, {0x56, 0x7d, 0x68, 0x3e, 0xc4, 0xb9}, {0x58, 0x74, 0x57, 0x0f, 0xe7, 0x93}, + {0x5a, 0x77, 0x5e, 0x04, 0xea, 0x9d}, {0x5c, 0x72, 0x45, 0x19, 0xfd, 0x8f}, {0x5e, 0x71, 0x4c, 0x12, 0xf0, 0x81}, + {0x60, 0x50, 0xab, 0xcb, 0x6b, 0x3b}, {0x62, 0x53, 0xa2, 0xc0, 0x66, 0x35}, {0x64, 0x56, 0xb9, 0xdd, 0x71, 0x27}, + {0x66, 0x55, 0xb0, 0xd6, 0x7c, 0x29}, {0x68, 0x5c, 0x8f, 0xe7, 0x5f, 0x03}, {0x6a, 0x5f, 0x86, 0xec, 0x52, 0x0d}, + {0x6c, 0x5a, 0x9d, 0xf1, 0x45, 0x1f}, {0x6e, 0x59, 0x94, 0xfa, 0x48, 0x11}, {0x70, 0x48, 0xe3, 0x93, 0x03, 0x4b}, + {0x72, 0x4b, 0xea, 0x98, 0x0e, 0x45}, {0x74, 0x4e, 0xf1, 0x85, 0x19, 0x57}, {0x76, 0x4d, 0xf8, 0x8e, 0x14, 0x59}, + {0x78, 0x44, 0xc7, 0xbf, 0x37, 0x73}, {0x7a, 0x47, 0xce, 0xb4, 0x3a, 0x7d}, {0x7c, 0x42, 0xd5, 0xa9, 0x2d, 0x6f}, + {0x7e, 0x41, 0xdc, 0xa2, 0x20, 0x61}, {0x80, 0xc0, 0x76, 0xf6, 0x6d, 0xad}, {0x82, 0xc3, 0x7f, 0xfd, 0x60, 0xa3}, + {0x84, 0xc6, 0x64, 0xe0, 0x77, 0xb1}, {0x86, 0xc5, 0x6d, 0xeb, 0x7a, 0xbf}, {0x88, 0xcc, 0x52, 0xda, 0x59, 0x95}, + {0x8a, 0xcf, 0x5b, 0xd1, 0x54, 0x9b}, {0x8c, 0xca, 0x40, 0xcc, 0x43, 0x89}, {0x8e, 0xc9, 0x49, 0xc7, 0x4e, 0x87}, + {0x90, 0xd8, 0x3e, 0xae, 0x05, 0xdd}, {0x92, 0xdb, 0x37, 0xa5, 0x08, 0xd3}, {0x94, 0xde, 0x2c, 0xb8, 0x1f, 0xc1}, + {0x96, 0xdd, 0x25, 0xb3, 0x12, 0xcf}, {0x98, 0xd4, 0x1a, 0x82, 0x31, 0xe5}, {0x9a, 0xd7, 0x13, 0x89, 0x3c, 0xeb}, + {0x9c, 0xd2, 0x08, 0x94, 0x2b, 0xf9}, {0x9e, 0xd1, 0x01, 0x9f, 0x26, 0xf7}, {0xa0, 0xf0, 0xe6, 0x46, 0xbd, 0x4d}, + {0xa2, 0xf3, 0xef, 0x4d, 0xb0, 0x43}, {0xa4, 0xf6, 0xf4, 0x50, 0xa7, 0x51}, {0xa6, 0xf5, 0xfd, 0x5b, 0xaa, 0x5f}, + {0xa8, 0xfc, 0xc2, 0x6a, 0x89, 0x75}, {0xaa, 0xff, 0xcb, 0x61, 0x84, 0x7b}, {0xac, 0xfa, 0xd0, 0x7c, 0x93, 0x69}, + {0xae, 0xf9, 0xd9, 0x77, 0x9e, 0x67}, {0xb0, 0xe8, 0xae, 0x1e, 0xd5, 0x3d}, {0xb2, 0xeb, 0xa7, 0x15, 0xd8, 0x33}, + {0xb4, 0xee, 0xbc, 0x08, 0xcf, 0x21}, {0xb6, 0xed, 0xb5, 0x03, 0xc2, 0x2f}, {0xb8, 0xe4, 0x8a, 0x32, 0xe1, 0x05}, + {0xba, 0xe7, 0x83, 0x39, 0xec, 0x0b}, {0xbc, 0xe2, 0x98, 0x24, 0xfb, 0x19}, {0xbe, 0xe1, 0x91, 0x2f, 0xf6, 0x17}, + {0xc0, 0xa0, 0x4d, 0x8d, 0xd6, 0x76}, {0xc2, 0xa3, 0x44, 0x86, 0xdb, 0x78}, {0xc4, 0xa6, 0x5f, 0x9b, 0xcc, 0x6a}, + {0xc6, 0xa5, 0x56, 0x90, 0xc1, 0x64}, {0xc8, 0xac, 0x69, 0xa1, 0xe2, 0x4e}, {0xca, 0xaf, 0x60, 0xaa, 0xef, 0x40}, + {0xcc, 0xaa, 0x7b, 0xb7, 0xf8, 0x52}, {0xce, 0xa9, 0x72, 0xbc, 0xf5, 0x5c}, {0xd0, 0xb8, 0x05, 0xd5, 0xbe, 0x06}, + {0xd2, 0xbb, 0x0c, 0xde, 0xb3, 0x08}, {0xd4, 0xbe, 0x17, 0xc3, 0xa4, 0x1a}, {0xd6, 0xbd, 0x1e, 0xc8, 0xa9, 0x14}, + {0xd8, 0xb4, 0x21, 0xf9, 0x8a, 0x3e}, {0xda, 0xb7, 0x28, 0xf2, 0x87, 0x30}, {0xdc, 0xb2, 0x33, 0xef, 0x90, 0x22}, + {0xde, 0xb1, 0x3a, 0xe4, 0x9d, 0x2c}, {0xe0, 0x90, 0xdd, 0x3d, 0x06, 0x96}, {0xe2, 0x93, 0xd4, 0x36, 0x0b, 0x98}, + {0xe4, 0x96, 0xcf, 0x2b, 0x1c, 0x8a}, {0xe6, 0x95, 0xc6, 0x20, 0x11, 0x84}, {0xe8, 0x9c, 0xf9, 0x11, 0x32, 0xae}, + {0xea, 0x9f, 0xf0, 0x1a, 0x3f, 0xa0}, {0xec, 0x9a, 0xeb, 0x07, 0x28, 0xb2}, {0xee, 0x99, 0xe2, 0x0c, 0x25, 0xbc}, + {0xf0, 0x88, 0x95, 0x65, 0x6e, 0xe6}, {0xf2, 0x8b, 0x9c, 0x6e, 0x63, 0xe8}, {0xf4, 0x8e, 0x87, 0x73, 0x74, 0xfa}, + {0xf6, 0x8d, 0x8e, 0x78, 0x79, 0xf4}, {0xf8, 0x84, 0xb1, 0x49, 0x5a, 0xde}, {0xfa, 0x87, 0xb8, 0x42, 0x57, 0xd0}, + {0xfc, 0x82, 0xa3, 0x5f, 0x40, 0xc2}, {0xfe, 0x81, 0xaa, 0x54, 0x4d, 0xcc}, {0x1b, 0x9b, 0xec, 0xf7, 0xda, 0x41}, + {0x19, 0x98, 0xe5, 0xfc, 0xd7, 0x4f}, {0x1f, 0x9d, 0xfe, 0xe1, 0xc0, 0x5d}, {0x1d, 0x9e, 0xf7, 0xea, 0xcd, 0x53}, + {0x13, 0x97, 0xc8, 0xdb, 0xee, 0x79}, {0x11, 0x94, 0xc1, 0xd0, 0xe3, 0x77}, {0x17, 0x91, 0xda, 0xcd, 0xf4, 0x65}, + {0x15, 0x92, 0xd3, 0xc6, 0xf9, 0x6b}, {0x0b, 0x83, 0xa4, 0xaf, 0xb2, 0x31}, {0x09, 0x80, 0xad, 0xa4, 0xbf, 0x3f}, + {0x0f, 0x85, 0xb6, 0xb9, 0xa8, 0x2d}, {0x0d, 0x86, 0xbf, 0xb2, 0xa5, 0x23}, {0x03, 0x8f, 0x80, 0x83, 0x86, 0x09}, + {0x01, 0x8c, 0x89, 0x88, 0x8b, 0x07}, {0x07, 0x89, 0x92, 0x95, 0x9c, 0x15}, {0x05, 0x8a, 0x9b, 0x9e, 0x91, 0x1b}, + {0x3b, 0xab, 0x7c, 0x47, 0x0a, 0xa1}, {0x39, 0xa8, 0x75, 0x4c, 0x07, 0xaf}, {0x3f, 0xad, 0x6e, 0x51, 0x10, 0xbd}, + {0x3d, 0xae, 0x67, 0x5a, 0x1d, 0xb3}, {0x33, 0xa7, 0x58, 0x6b, 0x3e, 0x99}, {0x31, 0xa4, 0x51, 0x60, 0x33, 0x97}, + {0x37, 0xa1, 0x4a, 0x7d, 0x24, 0x85}, {0x35, 0xa2, 0x43, 0x76, 0x29, 0x8b}, {0x2b, 0xb3, 0x34, 0x1f, 0x62, 0xd1}, + {0x29, 0xb0, 0x3d, 0x14, 0x6f, 0xdf}, {0x2f, 0xb5, 0x26, 0x09, 0x78, 0xcd}, {0x2d, 0xb6, 0x2f, 0x02, 0x75, 0xc3}, + {0x23, 0xbf, 0x10, 0x33, 0x56, 0xe9}, {0x21, 0xbc, 0x19, 0x38, 0x5b, 0xe7}, {0x27, 0xb9, 0x02, 0x25, 0x4c, 0xf5}, + {0x25, 0xba, 0x0b, 0x2e, 0x41, 0xfb}, {0x5b, 0xfb, 0xd7, 0x8c, 0x61, 0x9a}, {0x59, 0xf8, 0xde, 0x87, 0x6c, 0x94}, + {0x5f, 0xfd, 0xc5, 0x9a, 0x7b, 0x86}, {0x5d, 0xfe, 0xcc, 0x91, 0x76, 0x88}, {0x53, 0xf7, 0xf3, 0xa0, 0x55, 0xa2}, + {0x51, 0xf4, 0xfa, 0xab, 0x58, 0xac}, {0x57, 0xf1, 0xe1, 0xb6, 0x4f, 0xbe}, {0x55, 0xf2, 0xe8, 0xbd, 0x42, 0xb0}, + {0x4b, 0xe3, 0x9f, 0xd4, 0x09, 0xea}, {0x49, 0xe0, 0x96, 0xdf, 0x04, 0xe4}, {0x4f, 0xe5, 0x8d, 0xc2, 0x13, 0xf6}, + {0x4d, 0xe6, 0x84, 0xc9, 0x1e, 0xf8}, {0x43, 0xef, 0xbb, 0xf8, 0x3d, 0xd2}, {0x41, 0xec, 0xb2, 0xf3, 0x30, 0xdc}, + {0x47, 0xe9, 0xa9, 0xee, 0x27, 0xce}, {0x45, 0xea, 0xa0, 0xe5, 0x2a, 0xc0}, {0x7b, 0xcb, 0x47, 0x3c, 0xb1, 0x7a}, + {0x79, 0xc8, 0x4e, 0x37, 0xbc, 0x74}, {0x7f, 0xcd, 0x55, 0x2a, 0xab, 0x66}, {0x7d, 0xce, 0x5c, 0x21, 0xa6, 0x68}, + {0x73, 0xc7, 0x63, 0x10, 0x85, 0x42}, {0x71, 0xc4, 0x6a, 0x1b, 0x88, 0x4c}, {0x77, 0xc1, 0x71, 0x06, 0x9f, 0x5e}, + {0x75, 0xc2, 0x78, 0x0d, 0x92, 0x50}, {0x6b, 0xd3, 0x0f, 0x64, 0xd9, 0x0a}, {0x69, 0xd0, 0x06, 0x6f, 0xd4, 0x04}, + {0x6f, 0xd5, 0x1d, 0x72, 0xc3, 0x16}, {0x6d, 0xd6, 0x14, 0x79, 0xce, 0x18}, {0x63, 0xdf, 0x2b, 0x48, 0xed, 0x32}, + {0x61, 0xdc, 0x22, 0x43, 0xe0, 0x3c}, {0x67, 0xd9, 0x39, 0x5e, 0xf7, 0x2e}, {0x65, 0xda, 0x30, 0x55, 0xfa, 0x20}, + {0x9b, 0x5b, 0x9a, 0x01, 0xb7, 0xec}, {0x99, 0x58, 0x93, 0x0a, 0xba, 0xe2}, {0x9f, 0x5d, 0x88, 0x17, 0xad, 0xf0}, + {0x9d, 0x5e, 0x81, 0x1c, 0xa0, 0xfe}, {0x93, 0x57, 0xbe, 0x2d, 0x83, 0xd4}, {0x91, 0x54, 0xb7, 0x26, 0x8e, 0xda}, + {0x97, 0x51, 0xac, 0x3b, 0x99, 0xc8}, {0x95, 0x52, 0xa5, 0x30, 0x94, 0xc6}, {0x8b, 0x43, 0xd2, 0x59, 0xdf, 0x9c}, + {0x89, 0x40, 0xdb, 0x52, 0xd2, 0x92}, {0x8f, 0x45, 0xc0, 0x4f, 0xc5, 0x80}, {0x8d, 0x46, 0xc9, 0x44, 0xc8, 0x8e}, + {0x83, 0x4f, 0xf6, 0x75, 0xeb, 0xa4}, {0x81, 0x4c, 0xff, 0x7e, 0xe6, 0xaa}, {0x87, 0x49, 0xe4, 0x63, 0xf1, 0xb8}, + {0x85, 0x4a, 0xed, 0x68, 0xfc, 0xb6}, {0xbb, 0x6b, 0x0a, 0xb1, 0x67, 0x0c}, {0xb9, 0x68, 0x03, 0xba, 0x6a, 0x02}, + {0xbf, 0x6d, 0x18, 0xa7, 0x7d, 0x10}, {0xbd, 0x6e, 0x11, 0xac, 0x70, 0x1e}, {0xb3, 0x67, 0x2e, 0x9d, 0x53, 0x34}, + {0xb1, 0x64, 0x27, 0x96, 0x5e, 0x3a}, {0xb7, 0x61, 0x3c, 0x8b, 0x49, 0x28}, {0xb5, 0x62, 0x35, 0x80, 0x44, 0x26}, + {0xab, 0x73, 0x42, 0xe9, 0x0f, 0x7c}, {0xa9, 0x70, 0x4b, 0xe2, 0x02, 0x72}, {0xaf, 0x75, 0x50, 0xff, 0x15, 0x60}, + {0xad, 0x76, 0x59, 0xf4, 0x18, 0x6e}, {0xa3, 0x7f, 0x66, 0xc5, 0x3b, 0x44}, {0xa1, 0x7c, 0x6f, 0xce, 0x36, 0x4a}, + {0xa7, 0x79, 0x74, 0xd3, 0x21, 0x58}, {0xa5, 0x7a, 0x7d, 0xd8, 0x2c, 0x56}, {0xdb, 0x3b, 0xa1, 0x7a, 0x0c, 0x37}, + {0xd9, 0x38, 0xa8, 0x71, 0x01, 0x39}, {0xdf, 0x3d, 0xb3, 0x6c, 0x16, 0x2b}, {0xdd, 0x3e, 0xba, 0x67, 0x1b, 0x25}, + {0xd3, 0x37, 0x85, 0x56, 0x38, 0x0f}, {0xd1, 0x34, 0x8c, 0x5d, 0x35, 0x01}, {0xd7, 0x31, 0x97, 0x40, 0x22, 0x13}, + {0xd5, 0x32, 0x9e, 0x4b, 0x2f, 0x1d}, {0xcb, 0x23, 0xe9, 0x22, 0x64, 0x47}, {0xc9, 0x20, 0xe0, 0x29, 0x69, 0x49}, + {0xcf, 0x25, 0xfb, 0x34, 0x7e, 0x5b}, {0xcd, 0x26, 0xf2, 0x3f, 0x73, 0x55}, {0xc3, 0x2f, 0xcd, 0x0e, 0x50, 0x7f}, + {0xc1, 0x2c, 0xc4, 0x05, 0x5d, 0x71}, {0xc7, 0x29, 0xdf, 0x18, 0x4a, 0x63}, {0xc5, 0x2a, 0xd6, 0x13, 0x47, 0x6d}, + {0xfb, 0x0b, 0x31, 0xca, 0xdc, 0xd7}, {0xf9, 0x08, 0x38, 0xc1, 0xd1, 0xd9}, {0xff, 0x0d, 0x23, 0xdc, 0xc6, 0xcb}, + {0xfd, 0x0e, 0x2a, 0xd7, 0xcb, 0xc5}, {0xf3, 0x07, 0x15, 0xe6, 0xe8, 0xef}, {0xf1, 0x04, 0x1c, 0xed, 0xe5, 0xe1}, + {0xf7, 0x01, 0x07, 0xf0, 0xf2, 0xf3}, {0xf5, 0x02, 0x0e, 0xfb, 0xff, 0xfd}, {0xeb, 0x13, 0x79, 0x92, 0xb4, 0xa7}, + {0xe9, 0x10, 0x70, 0x99, 0xb9, 0xa9}, {0xef, 0x15, 0x6b, 0x84, 0xae, 0xbb}, {0xed, 0x16, 0x62, 0x8f, 0xa3, 0xb5}, + {0xe3, 0x1f, 0x5d, 0xbe, 0x80, 0x9f}, {0xe1, 0x1c, 0x54, 0xb5, 0x8d, 0x91}, {0xe7, 0x19, 0x4f, 0xa8, 0x9a, 0x83}, + {0xe5, 0x1a, 0x46, 0xa3, 0x97, 0x8d}}; + /*********************** FUNCTION DEFINITIONS ***********************/ // XORs the in and out buffers, storing the result in out. Length is in bytes. -void xor_buf(const BYTE in[], BYTE out[], size_t len) -{ - size_t idx; - - for (idx = 0; idx < len; idx++) - out[idx] ^= in[idx]; +void +xor_buf(const BYTE in[], BYTE out[], size_t len) { + size_t idx; + + for (idx = 0; idx < len; idx++) + out[idx] ^= in[idx]; } - + /******************* * AES - CBC *******************/ -int aes_encrypt_cbc(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) -{ - BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; - int blocks, idx; - - if (in_len % AES_BLOCK_SIZE != 0) - return(FALSE); - - blocks = in_len / AES_BLOCK_SIZE; - - memcpy(iv_buf, iv, AES_BLOCK_SIZE); - - for (idx = 0; idx < blocks; idx++) { - memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); - xor_buf(iv_buf, buf_in, AES_BLOCK_SIZE); - aes_encrypt(buf_in, buf_out, key, keysize); - memcpy(&out[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); - memcpy(iv_buf, buf_out, AES_BLOCK_SIZE); - } - - return(TRUE); +int +aes_encrypt_cbc(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) { + BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; + int blocks, idx; + + if (in_len % AES_BLOCK_SIZE != 0) + return (FALSE); + + blocks = in_len / AES_BLOCK_SIZE; + + memcpy(iv_buf, iv, AES_BLOCK_SIZE); + + for (idx = 0; idx < blocks; idx++) { + memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); + xor_buf(iv_buf, buf_in, AES_BLOCK_SIZE); + aes_encrypt(buf_in, buf_out, key, keysize); + memcpy(&out[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); + memcpy(iv_buf, buf_out, AES_BLOCK_SIZE); + } + + return (TRUE); } - -int aes_encrypt_cbc_mac(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) -{ - BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; - int blocks, idx; - - if (in_len % AES_BLOCK_SIZE != 0) - return(FALSE); - - blocks = in_len / AES_BLOCK_SIZE; - - memcpy(iv_buf, iv, AES_BLOCK_SIZE); - - for (idx = 0; idx < blocks; idx++) { - memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); - xor_buf(iv_buf, buf_in, AES_BLOCK_SIZE); - aes_encrypt(buf_in, buf_out, key, keysize); - memcpy(iv_buf, buf_out, AES_BLOCK_SIZE); - // Do not output all encrypted blocks. - } - - memcpy(out, buf_out, AES_BLOCK_SIZE); // Only output the last block. - - return(TRUE); + +int +aes_encrypt_cbc_mac(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) { + BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; + int blocks, idx; + + if (in_len % AES_BLOCK_SIZE != 0) + return (FALSE); + + blocks = in_len / AES_BLOCK_SIZE; + + memcpy(iv_buf, iv, AES_BLOCK_SIZE); + + for (idx = 0; idx < blocks; idx++) { + memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); + xor_buf(iv_buf, buf_in, AES_BLOCK_SIZE); + aes_encrypt(buf_in, buf_out, key, keysize); + memcpy(iv_buf, buf_out, AES_BLOCK_SIZE); + // Do not output all encrypted blocks. + } + + memcpy(out, buf_out, AES_BLOCK_SIZE); // Only output the last block. + + return (TRUE); } - -int aes_decrypt_cbc(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) -{ - BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; - int blocks, idx; - - if (in_len % AES_BLOCK_SIZE != 0) - return(FALSE); - - blocks = in_len / AES_BLOCK_SIZE; - - memcpy(iv_buf, iv, AES_BLOCK_SIZE); - - for (idx = 0; idx < blocks; idx++) { - memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); - aes_decrypt(buf_in, buf_out, key, keysize); - xor_buf(iv_buf, buf_out, AES_BLOCK_SIZE); - memcpy(&out[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); - memcpy(iv_buf, buf_in, AES_BLOCK_SIZE); - } - - return(TRUE); + +int +aes_decrypt_cbc(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) { + BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; + int blocks, idx; + + if (in_len % AES_BLOCK_SIZE != 0) + return (FALSE); + + blocks = in_len / AES_BLOCK_SIZE; + + memcpy(iv_buf, iv, AES_BLOCK_SIZE); + + for (idx = 0; idx < blocks; idx++) { + memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); + aes_decrypt(buf_in, buf_out, key, keysize); + xor_buf(iv_buf, buf_out, AES_BLOCK_SIZE); + memcpy(&out[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); + memcpy(iv_buf, buf_in, AES_BLOCK_SIZE); + } + + return (TRUE); } - + /******************* * AES - CTR *******************/ -void increment_iv(BYTE iv[], int counter_size) -{ - int idx; - - // Use counter_size bytes at the end of the IV as the big-endian integer to increment. - for (idx = AES_BLOCK_SIZE - 1; idx >= AES_BLOCK_SIZE - counter_size; idx--) { - iv[idx]++; - if (iv[idx] != 0 || idx == AES_BLOCK_SIZE - counter_size) - break; - } +void +increment_iv(BYTE iv[], int counter_size) { + int idx; + + // Use counter_size bytes at the end of the IV as the big-endian integer to increment. + for (idx = AES_BLOCK_SIZE - 1; idx >= AES_BLOCK_SIZE - counter_size; idx--) { + iv[idx]++; + if (iv[idx] != 0 || idx == AES_BLOCK_SIZE - counter_size) + break; + } } - + // Performs the encryption in-place, the input and output buffers may be the same. // Input may be an arbitrary length (in bytes). -void aes_encrypt_ctr(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) -{ - size_t idx = 0, last_block_length; - BYTE iv_buf[AES_BLOCK_SIZE], out_buf[AES_BLOCK_SIZE]; - - if (in != out) - memcpy(out, in, in_len); - - memcpy(iv_buf, iv, AES_BLOCK_SIZE); - last_block_length = in_len - AES_BLOCK_SIZE; - - if (in_len > AES_BLOCK_SIZE) { - for (idx = 0; idx < last_block_length; idx += AES_BLOCK_SIZE) { - aes_encrypt(iv_buf, out_buf, key, keysize); - xor_buf(out_buf, &out[idx], AES_BLOCK_SIZE); - increment_iv(iv_buf, AES_BLOCK_SIZE); +void +aes_encrypt_ctr(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) { + size_t idx = 0, last_block_length; + BYTE iv_buf[AES_BLOCK_SIZE], out_buf[AES_BLOCK_SIZE]; + + if (in != out) + memcpy(out, in, in_len); + + memcpy(iv_buf, iv, AES_BLOCK_SIZE); + last_block_length = in_len - AES_BLOCK_SIZE; + + if (in_len > AES_BLOCK_SIZE) { + for (idx = 0; idx < last_block_length; idx += AES_BLOCK_SIZE) { + aes_encrypt(iv_buf, out_buf, key, keysize); + xor_buf(out_buf, &out[idx], AES_BLOCK_SIZE); + increment_iv(iv_buf, AES_BLOCK_SIZE); + } } - } - - aes_encrypt(iv_buf, out_buf, key, keysize); - xor_buf(out_buf, &out[idx], in_len - idx); // Use the Most Significant bytes. + + aes_encrypt(iv_buf, out_buf, key, keysize); + xor_buf(out_buf, &out[idx], in_len - idx); // Use the Most Significant bytes. } - -void aes_decrypt_ctr(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) -{ - // CTR encryption is its own inverse function. - aes_encrypt_ctr(in, in_len, out, key, keysize, iv); + +void +aes_decrypt_ctr(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) { + // CTR encryption is its own inverse function. + aes_encrypt_ctr(in, in_len, out, key, keysize, iv); } - + /******************* * AES - CCM *******************/ // out_len = payload_len + assoc_len -int aes_encrypt_ccm(const BYTE payload[], WORD payload_len, const BYTE assoc[], unsigned short assoc_len, - const BYTE nonce[], unsigned short nonce_len, BYTE out[], WORD *out_len, - WORD mac_len, const BYTE key_str[], int keysize) -{ - BYTE temp_iv[AES_BLOCK_SIZE], counter[AES_BLOCK_SIZE], mac[16], *buf; - int end_of_buf, payload_len_store_size; - WORD key[60]; - - if (mac_len != 4 && mac_len != 6 && mac_len != 8 && mac_len != 10 && - mac_len != 12 && mac_len != 14 && mac_len != 16) - return(FALSE); - - if (nonce_len < 7 || nonce_len > 13) - return(FALSE); - - if (assoc_len > 32768 /* = 2^15 */) - return(FALSE); - - buf = (BYTE*)malloc(payload_len + assoc_len + 48 /*Round both payload and associated data up a block size and add an extra block.*/); - if (! buf) - return(FALSE); - - // Prepare the key for usage. - aes_key_setup(key_str, key, keysize); - - // Format the first block of the formatted data. - payload_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; - ccm_prepare_first_format_blk(buf, assoc_len, payload_len, payload_len_store_size, mac_len, nonce, nonce_len); - end_of_buf = AES_BLOCK_SIZE; - - // Format the Associated Data, aka, assoc[]. - ccm_format_assoc_data(buf, &end_of_buf, assoc, assoc_len); - - // Format the Payload, aka payload[]. - ccm_format_payload_data(buf, &end_of_buf, payload, payload_len); - - // Create the first counter block. - ccm_prepare_first_ctr_blk(counter, nonce, nonce_len, payload_len_store_size); - - // Perform the CBC operation with an IV of zeros on the formatted buffer to calculate the MAC. - memset(temp_iv, 0, AES_BLOCK_SIZE); - aes_encrypt_cbc_mac(buf, end_of_buf, mac, key, keysize, temp_iv); - - // Copy the Payload and MAC to the output buffer. - memcpy(out, payload, payload_len); - memcpy(&out[payload_len], mac, mac_len); - - // Encrypt the Payload with CTR mode with a counter starting at 1. - memcpy(temp_iv, counter, AES_BLOCK_SIZE); - increment_iv(temp_iv, AES_BLOCK_SIZE - 1 - mac_len); // Last argument is the byte size of the counting portion of the counter block. /*BUG?*/ - aes_encrypt_ctr(out, payload_len, out, key, keysize, temp_iv); - - // Encrypt the MAC with CTR mode with a counter starting at 0. - aes_encrypt_ctr(&out[payload_len], mac_len, &out[payload_len], key, keysize, counter); - - free(buf); - *out_len = payload_len + mac_len; - - return(TRUE); -} - -// plaintext_len = ciphertext_len - mac_len -// Needs a flag for whether the MAC matches. -int aes_decrypt_ccm(const BYTE ciphertext[], WORD ciphertext_len, const BYTE assoc[], unsigned short assoc_len, - const BYTE nonce[], unsigned short nonce_len, BYTE plaintext[], WORD *plaintext_len, - WORD mac_len, int *mac_auth, const BYTE key_str[], int keysize) -{ - BYTE temp_iv[AES_BLOCK_SIZE], counter[AES_BLOCK_SIZE], mac[16], mac_buf[16], *buf; - int end_of_buf, plaintext_len_store_size; - WORD key[60]; - - if (ciphertext_len <= mac_len) - return(FALSE); - - buf = (BYTE*)malloc(assoc_len + ciphertext_len /*ciphertext_len = plaintext_len + mac_len*/ + 48); - if (! buf) - return(FALSE); - - // Prepare the key for usage. - aes_key_setup(key_str, key, keysize); - - // Copy the plaintext and MAC to the output buffers. - *plaintext_len = ciphertext_len - mac_len; - plaintext_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; - memcpy(plaintext, ciphertext, *plaintext_len); - memcpy(mac, &ciphertext[*plaintext_len], mac_len); - - // Prepare the first counter block for use in decryption. - ccm_prepare_first_ctr_blk(counter, nonce, nonce_len, plaintext_len_store_size); - - // Decrypt the Payload with CTR mode with a counter starting at 1. - memcpy(temp_iv, counter, AES_BLOCK_SIZE); - increment_iv(temp_iv, AES_BLOCK_SIZE - 1 - mac_len); // (AES_BLOCK_SIZE - 1 - mac_len) is the byte size of the counting portion of the counter block. - aes_decrypt_ctr(plaintext, *plaintext_len, plaintext, key, keysize, temp_iv); - - // Setting mac_auth to NULL disables the authentication check. - if (mac_auth != NULL) { - // Decrypt the MAC with CTR mode with a counter starting at 0. - aes_decrypt_ctr(mac, mac_len, mac, key, keysize, counter); - +int +aes_encrypt_ccm(const BYTE payload[], WORD payload_len, const BYTE assoc[], unsigned short assoc_len, + const BYTE nonce[], unsigned short nonce_len, BYTE out[], WORD *out_len, WORD mac_len, + const BYTE key_str[], int keysize) { + BYTE temp_iv[AES_BLOCK_SIZE], counter[AES_BLOCK_SIZE], mac[16], *buf; + int end_of_buf, payload_len_store_size; + WORD key[60]; + + if (mac_len != 4 && mac_len != 6 && mac_len != 8 && mac_len != 10 && mac_len != 12 && mac_len != 14 && + mac_len != 16) + return (FALSE); + + if (nonce_len < 7 || nonce_len > 13) + return (FALSE); + + if (assoc_len > 32768 /* = 2^15 */) + return (FALSE); + + buf = (BYTE *)malloc(payload_len + assoc_len + + 48 /*Round both payload and associated data up a block size and add an extra block.*/); + if (!buf) + return (FALSE); + + // Prepare the key for usage. + aes_key_setup(key_str, key, keysize); + // Format the first block of the formatted data. - plaintext_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; - ccm_prepare_first_format_blk(buf, assoc_len, *plaintext_len, plaintext_len_store_size, mac_len, nonce, nonce_len); + payload_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; + ccm_prepare_first_format_blk(buf, assoc_len, payload_len, payload_len_store_size, mac_len, nonce, nonce_len); end_of_buf = AES_BLOCK_SIZE; - - // Format the Associated Data into the authentication buffer. + + // Format the Associated Data, aka, assoc[]. ccm_format_assoc_data(buf, &end_of_buf, assoc, assoc_len); - - // Format the Payload into the authentication buffer. - ccm_format_payload_data(buf, &end_of_buf, plaintext, *plaintext_len); - + + // Format the Payload, aka payload[]. + ccm_format_payload_data(buf, &end_of_buf, payload, payload_len); + + // Create the first counter block. + ccm_prepare_first_ctr_blk(counter, nonce, nonce_len, payload_len_store_size); + // Perform the CBC operation with an IV of zeros on the formatted buffer to calculate the MAC. memset(temp_iv, 0, AES_BLOCK_SIZE); - aes_encrypt_cbc_mac(buf, end_of_buf, mac_buf, key, keysize, temp_iv); - - // Compare the calculated MAC against the MAC embedded in the ciphertext to see if they are the same. - if (! memcmp(mac, mac_buf, mac_len)) { - *mac_auth = TRUE; - } - else { - *mac_auth = FALSE; - memset(plaintext, 0, *plaintext_len); + aes_encrypt_cbc_mac(buf, end_of_buf, mac, key, keysize, temp_iv); + + // Copy the Payload and MAC to the output buffer. + memcpy(out, payload, payload_len); + memcpy(&out[payload_len], mac, mac_len); + + // Encrypt the Payload with CTR mode with a counter starting at 1. + memcpy(temp_iv, counter, AES_BLOCK_SIZE); + increment_iv( + temp_iv, + AES_BLOCK_SIZE - 1 - + mac_len); // Last argument is the byte size of the counting portion of the counter block. /*BUG?*/ + aes_encrypt_ctr(out, payload_len, out, key, keysize, temp_iv); + + // Encrypt the MAC with CTR mode with a counter starting at 0. + aes_encrypt_ctr(&out[payload_len], mac_len, &out[payload_len], key, keysize, counter); + + free(buf); + *out_len = payload_len + mac_len; + + return (TRUE); +} + +// plaintext_len = ciphertext_len - mac_len +// Needs a flag for whether the MAC matches. +int +aes_decrypt_ccm(const BYTE ciphertext[], WORD ciphertext_len, const BYTE assoc[], unsigned short assoc_len, + const BYTE nonce[], unsigned short nonce_len, BYTE plaintext[], WORD *plaintext_len, WORD mac_len, + int *mac_auth, const BYTE key_str[], int keysize) { + BYTE temp_iv[AES_BLOCK_SIZE], counter[AES_BLOCK_SIZE], mac[16], mac_buf[16], *buf; + int end_of_buf, plaintext_len_store_size; + WORD key[60]; + + if (ciphertext_len <= mac_len) + return (FALSE); + + buf = (BYTE *)malloc(assoc_len + ciphertext_len /*ciphertext_len = plaintext_len + mac_len*/ + 48); + if (!buf) + return (FALSE); + + // Prepare the key for usage. + aes_key_setup(key_str, key, keysize); + + // Copy the plaintext and MAC to the output buffers. + *plaintext_len = ciphertext_len - mac_len; + plaintext_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; + memcpy(plaintext, ciphertext, *plaintext_len); + memcpy(mac, &ciphertext[*plaintext_len], mac_len); + + // Prepare the first counter block for use in decryption. + ccm_prepare_first_ctr_blk(counter, nonce, nonce_len, plaintext_len_store_size); + + // Decrypt the Payload with CTR mode with a counter starting at 1. + memcpy(temp_iv, counter, AES_BLOCK_SIZE); + increment_iv(temp_iv, AES_BLOCK_SIZE - 1 - mac_len); // (AES_BLOCK_SIZE - 1 - mac_len) is the byte size of the + // counting portion of the counter block. + aes_decrypt_ctr(plaintext, *plaintext_len, plaintext, key, keysize, temp_iv); + + // Setting mac_auth to NULL disables the authentication check. + if (mac_auth != NULL) { + // Decrypt the MAC with CTR mode with a counter starting at 0. + aes_decrypt_ctr(mac, mac_len, mac, key, keysize, counter); + + // Format the first block of the formatted data. + plaintext_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; + ccm_prepare_first_format_blk(buf, assoc_len, *plaintext_len, plaintext_len_store_size, mac_len, nonce, + nonce_len); + end_of_buf = AES_BLOCK_SIZE; + + // Format the Associated Data into the authentication buffer. + ccm_format_assoc_data(buf, &end_of_buf, assoc, assoc_len); + + // Format the Payload into the authentication buffer. + ccm_format_payload_data(buf, &end_of_buf, plaintext, *plaintext_len); + + // Perform the CBC operation with an IV of zeros on the formatted buffer to calculate the MAC. + memset(temp_iv, 0, AES_BLOCK_SIZE); + aes_encrypt_cbc_mac(buf, end_of_buf, mac_buf, key, keysize, temp_iv); + + // Compare the calculated MAC against the MAC embedded in the ciphertext to see if they are the same. + if (!memcmp(mac, mac_buf, mac_len)) { + *mac_auth = TRUE; + } else { + *mac_auth = FALSE; + memset(plaintext, 0, *plaintext_len); + } } - } - - free(buf); - - return(TRUE); + + free(buf); + + return (TRUE); } - + // Creates the first counter block. First byte is flags, then the nonce, then the incremented part. -void ccm_prepare_first_ctr_blk(BYTE counter[], const BYTE nonce[], int nonce_len, int payload_len_store_size) -{ - memset(counter, 0, AES_BLOCK_SIZE); - counter[0] = (payload_len_store_size - 1) & 0x07; - memcpy(&counter[1], nonce, nonce_len); +void +ccm_prepare_first_ctr_blk(BYTE counter[], const BYTE nonce[], int nonce_len, int payload_len_store_size) { + memset(counter, 0, AES_BLOCK_SIZE); + counter[0] = (payload_len_store_size - 1) & 0x07; + memcpy(&counter[1], nonce, nonce_len); } - -void ccm_prepare_first_format_blk(BYTE buf[], int assoc_len, int payload_len, int payload_len_store_size, int mac_len, const BYTE nonce[], int nonce_len) -{ - // Set the flags for the first byte of the first block. - buf[0] = ((((mac_len - 2) / 2) & 0x07) << 3) | ((payload_len_store_size - 1) & 0x07); - if (assoc_len > 0) - buf[0] += 0x40; - // Format the rest of the first block, storing the nonce and the size of the payload. - memcpy(&buf[1], nonce, nonce_len); - memset(&buf[1 + nonce_len], 0, AES_BLOCK_SIZE - 1 - nonce_len); - buf[15] = payload_len & 0x000000FF; - buf[14] = (payload_len >> 8) & 0x000000FF; + +void +ccm_prepare_first_format_blk(BYTE buf[], int assoc_len, int payload_len, int payload_len_store_size, int mac_len, + const BYTE nonce[], int nonce_len) { + // Set the flags for the first byte of the first block. + buf[0] = ((((mac_len - 2) / 2) & 0x07) << 3) | ((payload_len_store_size - 1) & 0x07); + if (assoc_len > 0) + buf[0] += 0x40; + // Format the rest of the first block, storing the nonce and the size of the payload. + memcpy(&buf[1], nonce, nonce_len); + memset(&buf[1 + nonce_len], 0, AES_BLOCK_SIZE - 1 - nonce_len); + buf[15] = payload_len & 0x000000FF; + buf[14] = (payload_len >> 8) & 0x000000FF; } - -void ccm_format_assoc_data(BYTE buf[], int *end_of_buf, const BYTE assoc[], int assoc_len) -{ - int pad; - - buf[*end_of_buf + 1] = assoc_len & 0x00FF; - buf[*end_of_buf] = (assoc_len >> 8) & 0x00FF; - *end_of_buf += 2; - memcpy(&buf[*end_of_buf], assoc, assoc_len); - *end_of_buf += assoc_len; - pad = AES_BLOCK_SIZE - (*end_of_buf % AES_BLOCK_SIZE); /*BUG?*/ - memset(&buf[*end_of_buf], 0, pad); - *end_of_buf += pad; + +void +ccm_format_assoc_data(BYTE buf[], int *end_of_buf, const BYTE assoc[], int assoc_len) { + int pad; + + buf[*end_of_buf + 1] = assoc_len & 0x00FF; + buf[*end_of_buf] = (assoc_len >> 8) & 0x00FF; + *end_of_buf += 2; + memcpy(&buf[*end_of_buf], assoc, assoc_len); + *end_of_buf += assoc_len; + pad = AES_BLOCK_SIZE - (*end_of_buf % AES_BLOCK_SIZE); /*BUG?*/ + memset(&buf[*end_of_buf], 0, pad); + *end_of_buf += pad; } - -void ccm_format_payload_data(BYTE buf[], int *end_of_buf, const BYTE payload[], int payload_len) -{ - int pad; - - memcpy(&buf[*end_of_buf], payload, payload_len); - *end_of_buf += payload_len; - pad = *end_of_buf % AES_BLOCK_SIZE; - if (pad != 0) - pad = AES_BLOCK_SIZE - pad; - memset(&buf[*end_of_buf], 0, pad); - *end_of_buf += pad; + +void +ccm_format_payload_data(BYTE buf[], int *end_of_buf, const BYTE payload[], int payload_len) { + int pad; + + memcpy(&buf[*end_of_buf], payload, payload_len); + *end_of_buf += payload_len; + pad = *end_of_buf % AES_BLOCK_SIZE; + if (pad != 0) + pad = AES_BLOCK_SIZE - pad; + memset(&buf[*end_of_buf], 0, pad); + *end_of_buf += pad; } - + /******************* * AES *******************/ ///////////////// // KEY EXPANSION ///////////////// - + // Substitutes a word using the AES S-Box. -WORD SubWord(WORD word) -{ - unsigned int result; - - result = (int)aes_sbox[(word >> 4) & 0x0000000F][word & 0x0000000F]; - result += (int)aes_sbox[(word >> 12) & 0x0000000F][(word >> 8) & 0x0000000F] << 8; - result += (int)aes_sbox[(word >> 20) & 0x0000000F][(word >> 16) & 0x0000000F] << 16; - result += (int)aes_sbox[(word >> 28) & 0x0000000F][(word >> 24) & 0x0000000F] << 24; - return(result); +WORD +SubWord(WORD word) { + unsigned int result; + + result = (int)aes_sbox[(word >> 4) & 0x0000000F][word & 0x0000000F]; + result += (int)aes_sbox[(word >> 12) & 0x0000000F][(word >> 8) & 0x0000000F] << 8; + result += (int)aes_sbox[(word >> 20) & 0x0000000F][(word >> 16) & 0x0000000F] << 16; + result += (int)aes_sbox[(word >> 28) & 0x0000000F][(word >> 24) & 0x0000000F] << 24; + return (result); } - + // Performs the action of generating the keys that will be used in every round of // encryption. "key" is the user-supplied input key, "w" is the output key schedule, // "keysize" is the length in bits of "key", must be 128, 192, or 256. -void aes_key_setup(const BYTE key[], WORD w[], int keysize) -{ - int Nb=4,Nr,Nk,idx; - WORD temp,Rcon[]={0x01000000,0x02000000,0x04000000,0x08000000,0x10000000,0x20000000, - 0x40000000,0x80000000,0x1b000000,0x36000000,0x6c000000,0xd8000000, - 0xab000000,0x4d000000,0x9a000000}; - - switch (keysize) { - case 128: Nr = 10; Nk = 4; break; - case 192: Nr = 12; Nk = 6; break; - case 256: Nr = 14; Nk = 8; break; - default: return; - } - - for (idx=0; idx < Nk; ++idx) { - w[idx] = ((key[4 * idx]) << 24) | ((key[4 * idx + 1]) << 16) | - ((key[4 * idx + 2]) << 8) | ((key[4 * idx + 3])); - } - - for (idx = Nk; idx < Nb * (Nr+1); ++idx) { - temp = w[idx - 1]; - if ((idx % Nk) == 0) - temp = SubWord(KE_ROTWORD(temp)) ^ Rcon[(idx-1)/Nk]; - else if (Nk > 6 && (idx % Nk) == 4) - temp = SubWord(temp); - w[idx] = w[idx-Nk] ^ temp; - } +void +aes_key_setup(const BYTE key[], WORD w[], int keysize) { + int Nb = 4, Nr, Nk, idx; + WORD temp, + Rcon[] = {0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1b000000, 0x36000000, 0x6c000000, 0xd8000000, 0xab000000, 0x4d000000, 0x9a000000}; + + switch (keysize) { + case 128: + Nr = 10; + Nk = 4; + break; + case 192: + Nr = 12; + Nk = 6; + break; + case 256: + Nr = 14; + Nk = 8; + break; + default: + return; + } + + for (idx = 0; idx < Nk; ++idx) { + w[idx] = ((key[4 * idx]) << 24) | ((key[4 * idx + 1]) << 16) | ((key[4 * idx + 2]) << 8) | + ((key[4 * idx + 3])); + } + + for (idx = Nk; idx < Nb * (Nr + 1); ++idx) { + temp = w[idx - 1]; + if ((idx % Nk) == 0) + temp = SubWord(KE_ROTWORD(temp)) ^ Rcon[(idx - 1) / Nk]; + else if (Nk > 6 && (idx % Nk) == 4) + temp = SubWord(temp); + w[idx] = w[idx - Nk] ^ temp; + } } - + ///////////////// // ADD ROUND KEY ///////////////// - + // Performs the AddRoundKey step. Each round has its own pre-generated 16-byte key in the // form of 4 integers (the "w" array). Each integer is XOR'd by one column of the state. // Also performs the job of InvAddRoundKey(); since the function is a simple XOR process, // it is its own inverse. -void AddRoundKey(BYTE state[][4], const WORD w[]) -{ - BYTE subkey[4]; - - // memcpy(subkey,&w[idx],4); // Not accurate for big endian machines - // Subkey 1 - subkey[0] = w[0] >> 24; - subkey[1] = w[0] >> 16; - subkey[2] = w[0] >> 8; - subkey[3] = w[0]; - state[0][0] ^= subkey[0]; - state[1][0] ^= subkey[1]; - state[2][0] ^= subkey[2]; - state[3][0] ^= subkey[3]; - // Subkey 2 - subkey[0] = w[1] >> 24; - subkey[1] = w[1] >> 16; - subkey[2] = w[1] >> 8; - subkey[3] = w[1]; - state[0][1] ^= subkey[0]; - state[1][1] ^= subkey[1]; - state[2][1] ^= subkey[2]; - state[3][1] ^= subkey[3]; - // Subkey 3 - subkey[0] = w[2] >> 24; - subkey[1] = w[2] >> 16; - subkey[2] = w[2] >> 8; - subkey[3] = w[2]; - state[0][2] ^= subkey[0]; - state[1][2] ^= subkey[1]; - state[2][2] ^= subkey[2]; - state[3][2] ^= subkey[3]; - // Subkey 4 - subkey[0] = w[3] >> 24; - subkey[1] = w[3] >> 16; - subkey[2] = w[3] >> 8; - subkey[3] = w[3]; - state[0][3] ^= subkey[0]; - state[1][3] ^= subkey[1]; - state[2][3] ^= subkey[2]; - state[3][3] ^= subkey[3]; +void +AddRoundKey(BYTE state[][4], const WORD w[]) { + BYTE subkey[4]; + + // memcpy(subkey,&w[idx],4); // Not accurate for big endian machines + // Subkey 1 + subkey[0] = w[0] >> 24; + subkey[1] = w[0] >> 16; + subkey[2] = w[0] >> 8; + subkey[3] = w[0]; + state[0][0] ^= subkey[0]; + state[1][0] ^= subkey[1]; + state[2][0] ^= subkey[2]; + state[3][0] ^= subkey[3]; + // Subkey 2 + subkey[0] = w[1] >> 24; + subkey[1] = w[1] >> 16; + subkey[2] = w[1] >> 8; + subkey[3] = w[1]; + state[0][1] ^= subkey[0]; + state[1][1] ^= subkey[1]; + state[2][1] ^= subkey[2]; + state[3][1] ^= subkey[3]; + // Subkey 3 + subkey[0] = w[2] >> 24; + subkey[1] = w[2] >> 16; + subkey[2] = w[2] >> 8; + subkey[3] = w[2]; + state[0][2] ^= subkey[0]; + state[1][2] ^= subkey[1]; + state[2][2] ^= subkey[2]; + state[3][2] ^= subkey[3]; + // Subkey 4 + subkey[0] = w[3] >> 24; + subkey[1] = w[3] >> 16; + subkey[2] = w[3] >> 8; + subkey[3] = w[3]; + state[0][3] ^= subkey[0]; + state[1][3] ^= subkey[1]; + state[2][3] ^= subkey[2]; + state[3][3] ^= subkey[3]; } - + ///////////////// // (Inv)SubBytes ///////////////// - + // Performs the SubBytes step. All bytes in the state are substituted with a // pre-calculated value from a lookup table. -void SubBytes(BYTE state[][4]) -{ - state[0][0] = aes_sbox[state[0][0] >> 4][state[0][0] & 0x0F]; - state[0][1] = aes_sbox[state[0][1] >> 4][state[0][1] & 0x0F]; - state[0][2] = aes_sbox[state[0][2] >> 4][state[0][2] & 0x0F]; - state[0][3] = aes_sbox[state[0][3] >> 4][state[0][3] & 0x0F]; - state[1][0] = aes_sbox[state[1][0] >> 4][state[1][0] & 0x0F]; - state[1][1] = aes_sbox[state[1][1] >> 4][state[1][1] & 0x0F]; - state[1][2] = aes_sbox[state[1][2] >> 4][state[1][2] & 0x0F]; - state[1][3] = aes_sbox[state[1][3] >> 4][state[1][3] & 0x0F]; - state[2][0] = aes_sbox[state[2][0] >> 4][state[2][0] & 0x0F]; - state[2][1] = aes_sbox[state[2][1] >> 4][state[2][1] & 0x0F]; - state[2][2] = aes_sbox[state[2][2] >> 4][state[2][2] & 0x0F]; - state[2][3] = aes_sbox[state[2][3] >> 4][state[2][3] & 0x0F]; - state[3][0] = aes_sbox[state[3][0] >> 4][state[3][0] & 0x0F]; - state[3][1] = aes_sbox[state[3][1] >> 4][state[3][1] & 0x0F]; - state[3][2] = aes_sbox[state[3][2] >> 4][state[3][2] & 0x0F]; - state[3][3] = aes_sbox[state[3][3] >> 4][state[3][3] & 0x0F]; +void +SubBytes(BYTE state[][4]) { + state[0][0] = aes_sbox[state[0][0] >> 4][state[0][0] & 0x0F]; + state[0][1] = aes_sbox[state[0][1] >> 4][state[0][1] & 0x0F]; + state[0][2] = aes_sbox[state[0][2] >> 4][state[0][2] & 0x0F]; + state[0][3] = aes_sbox[state[0][3] >> 4][state[0][3] & 0x0F]; + state[1][0] = aes_sbox[state[1][0] >> 4][state[1][0] & 0x0F]; + state[1][1] = aes_sbox[state[1][1] >> 4][state[1][1] & 0x0F]; + state[1][2] = aes_sbox[state[1][2] >> 4][state[1][2] & 0x0F]; + state[1][3] = aes_sbox[state[1][3] >> 4][state[1][3] & 0x0F]; + state[2][0] = aes_sbox[state[2][0] >> 4][state[2][0] & 0x0F]; + state[2][1] = aes_sbox[state[2][1] >> 4][state[2][1] & 0x0F]; + state[2][2] = aes_sbox[state[2][2] >> 4][state[2][2] & 0x0F]; + state[2][3] = aes_sbox[state[2][3] >> 4][state[2][3] & 0x0F]; + state[3][0] = aes_sbox[state[3][0] >> 4][state[3][0] & 0x0F]; + state[3][1] = aes_sbox[state[3][1] >> 4][state[3][1] & 0x0F]; + state[3][2] = aes_sbox[state[3][2] >> 4][state[3][2] & 0x0F]; + state[3][3] = aes_sbox[state[3][3] >> 4][state[3][3] & 0x0F]; } - -void InvSubBytes(BYTE state[][4]) -{ - state[0][0] = aes_invsbox[state[0][0] >> 4][state[0][0] & 0x0F]; - state[0][1] = aes_invsbox[state[0][1] >> 4][state[0][1] & 0x0F]; - state[0][2] = aes_invsbox[state[0][2] >> 4][state[0][2] & 0x0F]; - state[0][3] = aes_invsbox[state[0][3] >> 4][state[0][3] & 0x0F]; - state[1][0] = aes_invsbox[state[1][0] >> 4][state[1][0] & 0x0F]; - state[1][1] = aes_invsbox[state[1][1] >> 4][state[1][1] & 0x0F]; - state[1][2] = aes_invsbox[state[1][2] >> 4][state[1][2] & 0x0F]; - state[1][3] = aes_invsbox[state[1][3] >> 4][state[1][3] & 0x0F]; - state[2][0] = aes_invsbox[state[2][0] >> 4][state[2][0] & 0x0F]; - state[2][1] = aes_invsbox[state[2][1] >> 4][state[2][1] & 0x0F]; - state[2][2] = aes_invsbox[state[2][2] >> 4][state[2][2] & 0x0F]; - state[2][3] = aes_invsbox[state[2][3] >> 4][state[2][3] & 0x0F]; - state[3][0] = aes_invsbox[state[3][0] >> 4][state[3][0] & 0x0F]; - state[3][1] = aes_invsbox[state[3][1] >> 4][state[3][1] & 0x0F]; - state[3][2] = aes_invsbox[state[3][2] >> 4][state[3][2] & 0x0F]; - state[3][3] = aes_invsbox[state[3][3] >> 4][state[3][3] & 0x0F]; + +void +InvSubBytes(BYTE state[][4]) { + state[0][0] = aes_invsbox[state[0][0] >> 4][state[0][0] & 0x0F]; + state[0][1] = aes_invsbox[state[0][1] >> 4][state[0][1] & 0x0F]; + state[0][2] = aes_invsbox[state[0][2] >> 4][state[0][2] & 0x0F]; + state[0][3] = aes_invsbox[state[0][3] >> 4][state[0][3] & 0x0F]; + state[1][0] = aes_invsbox[state[1][0] >> 4][state[1][0] & 0x0F]; + state[1][1] = aes_invsbox[state[1][1] >> 4][state[1][1] & 0x0F]; + state[1][2] = aes_invsbox[state[1][2] >> 4][state[1][2] & 0x0F]; + state[1][3] = aes_invsbox[state[1][3] >> 4][state[1][3] & 0x0F]; + state[2][0] = aes_invsbox[state[2][0] >> 4][state[2][0] & 0x0F]; + state[2][1] = aes_invsbox[state[2][1] >> 4][state[2][1] & 0x0F]; + state[2][2] = aes_invsbox[state[2][2] >> 4][state[2][2] & 0x0F]; + state[2][3] = aes_invsbox[state[2][3] >> 4][state[2][3] & 0x0F]; + state[3][0] = aes_invsbox[state[3][0] >> 4][state[3][0] & 0x0F]; + state[3][1] = aes_invsbox[state[3][1] >> 4][state[3][1] & 0x0F]; + state[3][2] = aes_invsbox[state[3][2] >> 4][state[3][2] & 0x0F]; + state[3][3] = aes_invsbox[state[3][3] >> 4][state[3][3] & 0x0F]; } - + ///////////////// // (Inv)ShiftRows ///////////////// - + // Performs the ShiftRows step. All rows are shifted cylindrically to the left. -void ShiftRows(BYTE state[][4]) -{ - int t; - - // Shift left by 1 - t = state[1][0]; - state[1][0] = state[1][1]; - state[1][1] = state[1][2]; - state[1][2] = state[1][3]; - state[1][3] = t; - // Shift left by 2 - t = state[2][0]; - state[2][0] = state[2][2]; - state[2][2] = t; - t = state[2][1]; - state[2][1] = state[2][3]; - state[2][3] = t; - // Shift left by 3 - t = state[3][0]; - state[3][0] = state[3][3]; - state[3][3] = state[3][2]; - state[3][2] = state[3][1]; - state[3][1] = t; +void +ShiftRows(BYTE state[][4]) { + int t; + + // Shift left by 1 + t = state[1][0]; + state[1][0] = state[1][1]; + state[1][1] = state[1][2]; + state[1][2] = state[1][3]; + state[1][3] = t; + // Shift left by 2 + t = state[2][0]; + state[2][0] = state[2][2]; + state[2][2] = t; + t = state[2][1]; + state[2][1] = state[2][3]; + state[2][3] = t; + // Shift left by 3 + t = state[3][0]; + state[3][0] = state[3][3]; + state[3][3] = state[3][2]; + state[3][2] = state[3][1]; + state[3][1] = t; } - + // All rows are shifted cylindrically to the right. -void InvShiftRows(BYTE state[][4]) -{ - int t; - - // Shift right by 1 - t = state[1][3]; - state[1][3] = state[1][2]; - state[1][2] = state[1][1]; - state[1][1] = state[1][0]; - state[1][0] = t; - // Shift right by 2 - t = state[2][3]; - state[2][3] = state[2][1]; - state[2][1] = t; - t = state[2][2]; - state[2][2] = state[2][0]; - state[2][0] = t; - // Shift right by 3 - t = state[3][3]; - state[3][3] = state[3][0]; - state[3][0] = state[3][1]; - state[3][1] = state[3][2]; - state[3][2] = t; +void +InvShiftRows(BYTE state[][4]) { + int t; + + // Shift right by 1 + t = state[1][3]; + state[1][3] = state[1][2]; + state[1][2] = state[1][1]; + state[1][1] = state[1][0]; + state[1][0] = t; + // Shift right by 2 + t = state[2][3]; + state[2][3] = state[2][1]; + state[2][1] = t; + t = state[2][2]; + state[2][2] = state[2][0]; + state[2][0] = t; + // Shift right by 3 + t = state[3][3]; + state[3][3] = state[3][0]; + state[3][0] = state[3][1]; + state[3][1] = state[3][2]; + state[3][2] = t; } - + ///////////////// // (Inv)MixColumns ///////////////// - + // Performs the MixColums step. The state is multiplied by itself using matrix // multiplication in a Galios Field 2^8. All multiplication is pre-computed in a table. // Addition is equivilent to XOR. (Must always make a copy of the column as the original // values will be destoyed.) -void MixColumns(BYTE state[][4]) -{ - BYTE col[4]; - - // Column 1 - col[0] = state[0][0]; - col[1] = state[1][0]; - col[2] = state[2][0]; - col[3] = state[3][0]; - state[0][0] = gf_mul[col[0]][0]; - state[0][0] ^= gf_mul[col[1]][1]; - state[0][0] ^= col[2]; - state[0][0] ^= col[3]; - state[1][0] = col[0]; - state[1][0] ^= gf_mul[col[1]][0]; - state[1][0] ^= gf_mul[col[2]][1]; - state[1][0] ^= col[3]; - state[2][0] = col[0]; - state[2][0] ^= col[1]; - state[2][0] ^= gf_mul[col[2]][0]; - state[2][0] ^= gf_mul[col[3]][1]; - state[3][0] = gf_mul[col[0]][1]; - state[3][0] ^= col[1]; - state[3][0] ^= col[2]; - state[3][0] ^= gf_mul[col[3]][0]; - // Column 2 - col[0] = state[0][1]; - col[1] = state[1][1]; - col[2] = state[2][1]; - col[3] = state[3][1]; - state[0][1] = gf_mul[col[0]][0]; - state[0][1] ^= gf_mul[col[1]][1]; - state[0][1] ^= col[2]; - state[0][1] ^= col[3]; - state[1][1] = col[0]; - state[1][1] ^= gf_mul[col[1]][0]; - state[1][1] ^= gf_mul[col[2]][1]; - state[1][1] ^= col[3]; - state[2][1] = col[0]; - state[2][1] ^= col[1]; - state[2][1] ^= gf_mul[col[2]][0]; - state[2][1] ^= gf_mul[col[3]][1]; - state[3][1] = gf_mul[col[0]][1]; - state[3][1] ^= col[1]; - state[3][1] ^= col[2]; - state[3][1] ^= gf_mul[col[3]][0]; - // Column 3 - col[0] = state[0][2]; - col[1] = state[1][2]; - col[2] = state[2][2]; - col[3] = state[3][2]; - state[0][2] = gf_mul[col[0]][0]; - state[0][2] ^= gf_mul[col[1]][1]; - state[0][2] ^= col[2]; - state[0][2] ^= col[3]; - state[1][2] = col[0]; - state[1][2] ^= gf_mul[col[1]][0]; - state[1][2] ^= gf_mul[col[2]][1]; - state[1][2] ^= col[3]; - state[2][2] = col[0]; - state[2][2] ^= col[1]; - state[2][2] ^= gf_mul[col[2]][0]; - state[2][2] ^= gf_mul[col[3]][1]; - state[3][2] = gf_mul[col[0]][1]; - state[3][2] ^= col[1]; - state[3][2] ^= col[2]; - state[3][2] ^= gf_mul[col[3]][0]; - // Column 4 - col[0] = state[0][3]; - col[1] = state[1][3]; - col[2] = state[2][3]; - col[3] = state[3][3]; - state[0][3] = gf_mul[col[0]][0]; - state[0][3] ^= gf_mul[col[1]][1]; - state[0][3] ^= col[2]; - state[0][3] ^= col[3]; - state[1][3] = col[0]; - state[1][3] ^= gf_mul[col[1]][0]; - state[1][3] ^= gf_mul[col[2]][1]; - state[1][3] ^= col[3]; - state[2][3] = col[0]; - state[2][3] ^= col[1]; - state[2][3] ^= gf_mul[col[2]][0]; - state[2][3] ^= gf_mul[col[3]][1]; - state[3][3] = gf_mul[col[0]][1]; - state[3][3] ^= col[1]; - state[3][3] ^= col[2]; - state[3][3] ^= gf_mul[col[3]][0]; +void +MixColumns(BYTE state[][4]) { + BYTE col[4]; + + // Column 1 + col[0] = state[0][0]; + col[1] = state[1][0]; + col[2] = state[2][0]; + col[3] = state[3][0]; + state[0][0] = gf_mul[col[0]][0]; + state[0][0] ^= gf_mul[col[1]][1]; + state[0][0] ^= col[2]; + state[0][0] ^= col[3]; + state[1][0] = col[0]; + state[1][0] ^= gf_mul[col[1]][0]; + state[1][0] ^= gf_mul[col[2]][1]; + state[1][0] ^= col[3]; + state[2][0] = col[0]; + state[2][0] ^= col[1]; + state[2][0] ^= gf_mul[col[2]][0]; + state[2][0] ^= gf_mul[col[3]][1]; + state[3][0] = gf_mul[col[0]][1]; + state[3][0] ^= col[1]; + state[3][0] ^= col[2]; + state[3][0] ^= gf_mul[col[3]][0]; + // Column 2 + col[0] = state[0][1]; + col[1] = state[1][1]; + col[2] = state[2][1]; + col[3] = state[3][1]; + state[0][1] = gf_mul[col[0]][0]; + state[0][1] ^= gf_mul[col[1]][1]; + state[0][1] ^= col[2]; + state[0][1] ^= col[3]; + state[1][1] = col[0]; + state[1][1] ^= gf_mul[col[1]][0]; + state[1][1] ^= gf_mul[col[2]][1]; + state[1][1] ^= col[3]; + state[2][1] = col[0]; + state[2][1] ^= col[1]; + state[2][1] ^= gf_mul[col[2]][0]; + state[2][1] ^= gf_mul[col[3]][1]; + state[3][1] = gf_mul[col[0]][1]; + state[3][1] ^= col[1]; + state[3][1] ^= col[2]; + state[3][1] ^= gf_mul[col[3]][0]; + // Column 3 + col[0] = state[0][2]; + col[1] = state[1][2]; + col[2] = state[2][2]; + col[3] = state[3][2]; + state[0][2] = gf_mul[col[0]][0]; + state[0][2] ^= gf_mul[col[1]][1]; + state[0][2] ^= col[2]; + state[0][2] ^= col[3]; + state[1][2] = col[0]; + state[1][2] ^= gf_mul[col[1]][0]; + state[1][2] ^= gf_mul[col[2]][1]; + state[1][2] ^= col[3]; + state[2][2] = col[0]; + state[2][2] ^= col[1]; + state[2][2] ^= gf_mul[col[2]][0]; + state[2][2] ^= gf_mul[col[3]][1]; + state[3][2] = gf_mul[col[0]][1]; + state[3][2] ^= col[1]; + state[3][2] ^= col[2]; + state[3][2] ^= gf_mul[col[3]][0]; + // Column 4 + col[0] = state[0][3]; + col[1] = state[1][3]; + col[2] = state[2][3]; + col[3] = state[3][3]; + state[0][3] = gf_mul[col[0]][0]; + state[0][3] ^= gf_mul[col[1]][1]; + state[0][3] ^= col[2]; + state[0][3] ^= col[3]; + state[1][3] = col[0]; + state[1][3] ^= gf_mul[col[1]][0]; + state[1][3] ^= gf_mul[col[2]][1]; + state[1][3] ^= col[3]; + state[2][3] = col[0]; + state[2][3] ^= col[1]; + state[2][3] ^= gf_mul[col[2]][0]; + state[2][3] ^= gf_mul[col[3]][1]; + state[3][3] = gf_mul[col[0]][1]; + state[3][3] ^= col[1]; + state[3][3] ^= col[2]; + state[3][3] ^= gf_mul[col[3]][0]; } - -void InvMixColumns(BYTE state[][4]) -{ - BYTE col[4]; - - // Column 1 - col[0] = state[0][0]; - col[1] = state[1][0]; - col[2] = state[2][0]; - col[3] = state[3][0]; - state[0][0] = gf_mul[col[0]][5]; - state[0][0] ^= gf_mul[col[1]][3]; - state[0][0] ^= gf_mul[col[2]][4]; - state[0][0] ^= gf_mul[col[3]][2]; - state[1][0] = gf_mul[col[0]][2]; - state[1][0] ^= gf_mul[col[1]][5]; - state[1][0] ^= gf_mul[col[2]][3]; - state[1][0] ^= gf_mul[col[3]][4]; - state[2][0] = gf_mul[col[0]][4]; - state[2][0] ^= gf_mul[col[1]][2]; - state[2][0] ^= gf_mul[col[2]][5]; - state[2][0] ^= gf_mul[col[3]][3]; - state[3][0] = gf_mul[col[0]][3]; - state[3][0] ^= gf_mul[col[1]][4]; - state[3][0] ^= gf_mul[col[2]][2]; - state[3][0] ^= gf_mul[col[3]][5]; - // Column 2 - col[0] = state[0][1]; - col[1] = state[1][1]; - col[2] = state[2][1]; - col[3] = state[3][1]; - state[0][1] = gf_mul[col[0]][5]; - state[0][1] ^= gf_mul[col[1]][3]; - state[0][1] ^= gf_mul[col[2]][4]; - state[0][1] ^= gf_mul[col[3]][2]; - state[1][1] = gf_mul[col[0]][2]; - state[1][1] ^= gf_mul[col[1]][5]; - state[1][1] ^= gf_mul[col[2]][3]; - state[1][1] ^= gf_mul[col[3]][4]; - state[2][1] = gf_mul[col[0]][4]; - state[2][1] ^= gf_mul[col[1]][2]; - state[2][1] ^= gf_mul[col[2]][5]; - state[2][1] ^= gf_mul[col[3]][3]; - state[3][1] = gf_mul[col[0]][3]; - state[3][1] ^= gf_mul[col[1]][4]; - state[3][1] ^= gf_mul[col[2]][2]; - state[3][1] ^= gf_mul[col[3]][5]; - // Column 3 - col[0] = state[0][2]; - col[1] = state[1][2]; - col[2] = state[2][2]; - col[3] = state[3][2]; - state[0][2] = gf_mul[col[0]][5]; - state[0][2] ^= gf_mul[col[1]][3]; - state[0][2] ^= gf_mul[col[2]][4]; - state[0][2] ^= gf_mul[col[3]][2]; - state[1][2] = gf_mul[col[0]][2]; - state[1][2] ^= gf_mul[col[1]][5]; - state[1][2] ^= gf_mul[col[2]][3]; - state[1][2] ^= gf_mul[col[3]][4]; - state[2][2] = gf_mul[col[0]][4]; - state[2][2] ^= gf_mul[col[1]][2]; - state[2][2] ^= gf_mul[col[2]][5]; - state[2][2] ^= gf_mul[col[3]][3]; - state[3][2] = gf_mul[col[0]][3]; - state[3][2] ^= gf_mul[col[1]][4]; - state[3][2] ^= gf_mul[col[2]][2]; - state[3][2] ^= gf_mul[col[3]][5]; - // Column 4 - col[0] = state[0][3]; - col[1] = state[1][3]; - col[2] = state[2][3]; - col[3] = state[3][3]; - state[0][3] = gf_mul[col[0]][5]; - state[0][3] ^= gf_mul[col[1]][3]; - state[0][3] ^= gf_mul[col[2]][4]; - state[0][3] ^= gf_mul[col[3]][2]; - state[1][3] = gf_mul[col[0]][2]; - state[1][3] ^= gf_mul[col[1]][5]; - state[1][3] ^= gf_mul[col[2]][3]; - state[1][3] ^= gf_mul[col[3]][4]; - state[2][3] = gf_mul[col[0]][4]; - state[2][3] ^= gf_mul[col[1]][2]; - state[2][3] ^= gf_mul[col[2]][5]; - state[2][3] ^= gf_mul[col[3]][3]; - state[3][3] = gf_mul[col[0]][3]; - state[3][3] ^= gf_mul[col[1]][4]; - state[3][3] ^= gf_mul[col[2]][2]; - state[3][3] ^= gf_mul[col[3]][5]; + +void +InvMixColumns(BYTE state[][4]) { + BYTE col[4]; + + // Column 1 + col[0] = state[0][0]; + col[1] = state[1][0]; + col[2] = state[2][0]; + col[3] = state[3][0]; + state[0][0] = gf_mul[col[0]][5]; + state[0][0] ^= gf_mul[col[1]][3]; + state[0][0] ^= gf_mul[col[2]][4]; + state[0][0] ^= gf_mul[col[3]][2]; + state[1][0] = gf_mul[col[0]][2]; + state[1][0] ^= gf_mul[col[1]][5]; + state[1][0] ^= gf_mul[col[2]][3]; + state[1][0] ^= gf_mul[col[3]][4]; + state[2][0] = gf_mul[col[0]][4]; + state[2][0] ^= gf_mul[col[1]][2]; + state[2][0] ^= gf_mul[col[2]][5]; + state[2][0] ^= gf_mul[col[3]][3]; + state[3][0] = gf_mul[col[0]][3]; + state[3][0] ^= gf_mul[col[1]][4]; + state[3][0] ^= gf_mul[col[2]][2]; + state[3][0] ^= gf_mul[col[3]][5]; + // Column 2 + col[0] = state[0][1]; + col[1] = state[1][1]; + col[2] = state[2][1]; + col[3] = state[3][1]; + state[0][1] = gf_mul[col[0]][5]; + state[0][1] ^= gf_mul[col[1]][3]; + state[0][1] ^= gf_mul[col[2]][4]; + state[0][1] ^= gf_mul[col[3]][2]; + state[1][1] = gf_mul[col[0]][2]; + state[1][1] ^= gf_mul[col[1]][5]; + state[1][1] ^= gf_mul[col[2]][3]; + state[1][1] ^= gf_mul[col[3]][4]; + state[2][1] = gf_mul[col[0]][4]; + state[2][1] ^= gf_mul[col[1]][2]; + state[2][1] ^= gf_mul[col[2]][5]; + state[2][1] ^= gf_mul[col[3]][3]; + state[3][1] = gf_mul[col[0]][3]; + state[3][1] ^= gf_mul[col[1]][4]; + state[3][1] ^= gf_mul[col[2]][2]; + state[3][1] ^= gf_mul[col[3]][5]; + // Column 3 + col[0] = state[0][2]; + col[1] = state[1][2]; + col[2] = state[2][2]; + col[3] = state[3][2]; + state[0][2] = gf_mul[col[0]][5]; + state[0][2] ^= gf_mul[col[1]][3]; + state[0][2] ^= gf_mul[col[2]][4]; + state[0][2] ^= gf_mul[col[3]][2]; + state[1][2] = gf_mul[col[0]][2]; + state[1][2] ^= gf_mul[col[1]][5]; + state[1][2] ^= gf_mul[col[2]][3]; + state[1][2] ^= gf_mul[col[3]][4]; + state[2][2] = gf_mul[col[0]][4]; + state[2][2] ^= gf_mul[col[1]][2]; + state[2][2] ^= gf_mul[col[2]][5]; + state[2][2] ^= gf_mul[col[3]][3]; + state[3][2] = gf_mul[col[0]][3]; + state[3][2] ^= gf_mul[col[1]][4]; + state[3][2] ^= gf_mul[col[2]][2]; + state[3][2] ^= gf_mul[col[3]][5]; + // Column 4 + col[0] = state[0][3]; + col[1] = state[1][3]; + col[2] = state[2][3]; + col[3] = state[3][3]; + state[0][3] = gf_mul[col[0]][5]; + state[0][3] ^= gf_mul[col[1]][3]; + state[0][3] ^= gf_mul[col[2]][4]; + state[0][3] ^= gf_mul[col[3]][2]; + state[1][3] = gf_mul[col[0]][2]; + state[1][3] ^= gf_mul[col[1]][5]; + state[1][3] ^= gf_mul[col[2]][3]; + state[1][3] ^= gf_mul[col[3]][4]; + state[2][3] = gf_mul[col[0]][4]; + state[2][3] ^= gf_mul[col[1]][2]; + state[2][3] ^= gf_mul[col[2]][5]; + state[2][3] ^= gf_mul[col[3]][3]; + state[3][3] = gf_mul[col[0]][3]; + state[3][3] ^= gf_mul[col[1]][4]; + state[3][3] ^= gf_mul[col[2]][2]; + state[3][3] ^= gf_mul[col[3]][5]; } - + ///////////////// // (En/De)Crypt ///////////////// - -void aes_encrypt(const BYTE in[], BYTE out[], const WORD key[], int keysize) -{ - BYTE state[4][4]; - - // Copy input array (should be 16 bytes long) to a matrix (sequential bytes are ordered - // by row, not col) called "state" for processing. - // *** Implementation note: The official AES documentation references the state by - // column, then row. Accessing an element in C requires row then column. Thus, all state - // references in AES must have the column and row indexes reversed for C implementation. - state[0][0] = in[0]; - state[1][0] = in[1]; - state[2][0] = in[2]; - state[3][0] = in[3]; - state[0][1] = in[4]; - state[1][1] = in[5]; - state[2][1] = in[6]; - state[3][1] = in[7]; - state[0][2] = in[8]; - state[1][2] = in[9]; - state[2][2] = in[10]; - state[3][2] = in[11]; - state[0][3] = in[12]; - state[1][3] = in[13]; - state[2][3] = in[14]; - state[3][3] = in[15]; - - // Perform the necessary number of rounds. The round key is added first. - // The last round does not perform the MixColumns step. - AddRoundKey(state,&key[0]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[4]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[8]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[12]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[16]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[20]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[24]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[28]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[32]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[36]); - if (keysize != 128) { - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[40]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[44]); - if (keysize != 192) { - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[48]); - SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[52]); - SubBytes(state); ShiftRows(state); AddRoundKey(state,&key[56]); - } - else { - SubBytes(state); ShiftRows(state); AddRoundKey(state,&key[48]); + +void +aes_encrypt(const BYTE in[], BYTE out[], const WORD key[], int keysize) { + BYTE state[4][4]; + + // Copy input array (should be 16 bytes long) to a matrix (sequential bytes are ordered + // by row, not col) called "state" for processing. + // *** Implementation note: The official AES documentation references the state by + // column, then row. Accessing an element in C requires row then column. Thus, all state + // references in AES must have the column and row indexes reversed for C implementation. + state[0][0] = in[0]; + state[1][0] = in[1]; + state[2][0] = in[2]; + state[3][0] = in[3]; + state[0][1] = in[4]; + state[1][1] = in[5]; + state[2][1] = in[6]; + state[3][1] = in[7]; + state[0][2] = in[8]; + state[1][2] = in[9]; + state[2][2] = in[10]; + state[3][2] = in[11]; + state[0][3] = in[12]; + state[1][3] = in[13]; + state[2][3] = in[14]; + state[3][3] = in[15]; + + // Perform the necessary number of rounds. The round key is added first. + // The last round does not perform the MixColumns step. + AddRoundKey(state, &key[0]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[4]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[8]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[12]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[16]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[20]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[24]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[28]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[32]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[36]); + if (keysize != 128) { + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[40]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[44]); + if (keysize != 192) { + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[48]); + SubBytes(state); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, &key[52]); + SubBytes(state); + ShiftRows(state); + AddRoundKey(state, &key[56]); + } else { + SubBytes(state); + ShiftRows(state); + AddRoundKey(state, &key[48]); + } + } else { + SubBytes(state); + ShiftRows(state); + AddRoundKey(state, &key[40]); } - } - else { - SubBytes(state); ShiftRows(state); AddRoundKey(state,&key[40]); - } - - // Copy the state to the output array. - out[0] = state[0][0]; - out[1] = state[1][0]; - out[2] = state[2][0]; - out[3] = state[3][0]; - out[4] = state[0][1]; - out[5] = state[1][1]; - out[6] = state[2][1]; - out[7] = state[3][1]; - out[8] = state[0][2]; - out[9] = state[1][2]; - out[10] = state[2][2]; - out[11] = state[3][2]; - out[12] = state[0][3]; - out[13] = state[1][3]; - out[14] = state[2][3]; - out[15] = state[3][3]; + + // Copy the state to the output array. + out[0] = state[0][0]; + out[1] = state[1][0]; + out[2] = state[2][0]; + out[3] = state[3][0]; + out[4] = state[0][1]; + out[5] = state[1][1]; + out[6] = state[2][1]; + out[7] = state[3][1]; + out[8] = state[0][2]; + out[9] = state[1][2]; + out[10] = state[2][2]; + out[11] = state[3][2]; + out[12] = state[0][3]; + out[13] = state[1][3]; + out[14] = state[2][3]; + out[15] = state[3][3]; } - -void aes_decrypt(const BYTE in[], BYTE out[], const WORD key[], int keysize) -{ - BYTE state[4][4]; - - // Copy the input to the state. - state[0][0] = in[0]; - state[1][0] = in[1]; - state[2][0] = in[2]; - state[3][0] = in[3]; - state[0][1] = in[4]; - state[1][1] = in[5]; - state[2][1] = in[6]; - state[3][1] = in[7]; - state[0][2] = in[8]; - state[1][2] = in[9]; - state[2][2] = in[10]; - state[3][2] = in[11]; - state[0][3] = in[12]; - state[1][3] = in[13]; - state[2][3] = in[14]; - state[3][3] = in[15]; - - // Perform the necessary number of rounds. The round key is added first. - // The last round does not perform the MixColumns step. - if (keysize > 128) { - if (keysize > 192) { - AddRoundKey(state,&key[56]); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[52]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[48]);InvMixColumns(state); - } - else { - AddRoundKey(state,&key[48]); + +void +aes_decrypt(const BYTE in[], BYTE out[], const WORD key[], int keysize) { + BYTE state[4][4]; + + // Copy the input to the state. + state[0][0] = in[0]; + state[1][0] = in[1]; + state[2][0] = in[2]; + state[3][0] = in[3]; + state[0][1] = in[4]; + state[1][1] = in[5]; + state[2][1] = in[6]; + state[3][1] = in[7]; + state[0][2] = in[8]; + state[1][2] = in[9]; + state[2][2] = in[10]; + state[3][2] = in[11]; + state[0][3] = in[12]; + state[1][3] = in[13]; + state[2][3] = in[14]; + state[3][3] = in[15]; + + // Perform the necessary number of rounds. The round key is added first. + // The last round does not perform the MixColumns step. + if (keysize > 128) { + if (keysize > 192) { + AddRoundKey(state, &key[56]); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[52]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[48]); + InvMixColumns(state); + } else { + AddRoundKey(state, &key[48]); + } + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[44]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[40]); + InvMixColumns(state); + } else { + AddRoundKey(state, &key[40]); } - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[44]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[40]);InvMixColumns(state); - } - else { - AddRoundKey(state,&key[40]); - } - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[36]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[32]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[28]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[24]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[20]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[16]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[12]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[8]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[4]);InvMixColumns(state); - InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[0]); - - // Copy the state to the output array. - out[0] = state[0][0]; - out[1] = state[1][0]; - out[2] = state[2][0]; - out[3] = state[3][0]; - out[4] = state[0][1]; - out[5] = state[1][1]; - out[6] = state[2][1]; - out[7] = state[3][1]; - out[8] = state[0][2]; - out[9] = state[1][2]; - out[10] = state[2][2]; - out[11] = state[3][2]; - out[12] = state[0][3]; - out[13] = state[1][3]; - out[14] = state[2][3]; - out[15] = state[3][3]; + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[36]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[32]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[28]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[24]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[20]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[16]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[12]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[8]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[4]); + InvMixColumns(state); + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(state, &key[0]); + + // Copy the state to the output array. + out[0] = state[0][0]; + out[1] = state[1][0]; + out[2] = state[2][0]; + out[3] = state[3][0]; + out[4] = state[0][1]; + out[5] = state[1][1]; + out[6] = state[2][1]; + out[7] = state[3][1]; + out[8] = state[0][2]; + out[9] = state[1][2]; + out[10] = state[2][2]; + out[11] = state[3][2]; + out[12] = state[0][3]; + out[13] = state[1][3]; + out[14] = state[2][3]; + out[15] = state[3][3]; } - + /******************* ** AES DEBUGGING FUNCTIONS *******************/ @@ -1125,18 +1192,18 @@ void aes_decrypt(const BYTE in[], BYTE out[], const WORD key[], int keysize) void print_state(BYTE state[][4]) { int idx,idx2; - + for (idx=0; idx < 4; idx++) for (idx2=0; idx2 < 4; idx2++) printf("%02x",state[idx2][idx]); printf("\n"); } - + // This prints the key (4 consecutive ints) used for a given round as a linear hex string. void print_rnd_key(WORD key[]) { int idx; - + for (idx=0; idx < 4; idx++) printf("%08x",key[idx]); printf("\n"); diff --git a/examples/aes_encrypt/aes.h b/examples/aes_encrypt/aes.h index 9a697a293..030436b15 100644 --- a/examples/aes_encrypt/aes.h +++ b/examples/aes_encrypt/aes.h @@ -45,127 +45,141 @@ * Details: Defines the API for the corresponding AES implementation. * Source: https://github.com/B-Con/crypto-algorithms *********************************************************************/ - + #ifndef AES_H #define AES_H - + /*************************** HEADER FILES ***************************/ #include - + /****************************** MACROS ******************************/ -#define AES_BLOCK_SIZE 16 // AES operates on 16 bytes at a time - +#define AES_BLOCK_SIZE 16 // AES operates on 16 bytes at a time + /**************************** DATA TYPES ****************************/ -typedef unsigned char BYTE; // 8-bit byte -typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines - +typedef unsigned char BYTE; // 8-bit byte +typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines + /*********************** FUNCTION DECLARATIONS **********************/ /////////////////// // AES /////////////////// // Key setup must be done before any AES en/de-cryption functions can be used. -void aes_key_setup(const BYTE key[], // The key, must be 128, 192, or 256 bits - WORD w[], // Output key schedule to be used later - int keysize); // Bit length of the key, 128, 192, or 256 - -void aes_encrypt(const BYTE in[], // 16 bytes of plaintext - BYTE out[], // 16 bytes of ciphertext - const WORD key[], // From the key setup - int keysize); // Bit length of the key, 128, 192, or 256 - -void aes_decrypt(const BYTE in[], // 16 bytes of ciphertext - BYTE out[], // 16 bytes of plaintext - const WORD key[], // From the key setup - int keysize); // Bit length of the key, 128, 192, or 256 - +void +aes_key_setup(const BYTE key[], // The key, must be 128, 192, or 256 bits + WORD w[], // Output key schedule to be used later + int keysize); // Bit length of the key, 128, 192, or 256 + +void +aes_encrypt(const BYTE in[], // 16 bytes of plaintext + BYTE out[], // 16 bytes of ciphertext + const WORD key[], // From the key setup + int keysize); // Bit length of the key, 128, 192, or 256 + +void +aes_decrypt(const BYTE in[], // 16 bytes of ciphertext + BYTE out[], // 16 bytes of plaintext + const WORD key[], // From the key setup + int keysize); // Bit length of the key, 128, 192, or 256 + /////////////////// // AES - CBC /////////////////// -int aes_encrypt_cbc(const BYTE in[], // Plaintext - size_t in_len, // Must be a multiple of AES_BLOCK_SIZE - BYTE out[], // Ciphertext, same length as plaintext - const WORD key[], // From the key setup - int keysize, // Bit length of the key, 128, 192, or 256 - const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long - +int +aes_encrypt_cbc(const BYTE in[], // Plaintext + size_t in_len, // Must be a multiple of AES_BLOCK_SIZE + BYTE out[], // Ciphertext, same length as plaintext + const WORD key[], // From the key setup + int keysize, // Bit length of the key, 128, 192, or 256 + const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long + // Only output the CBC-MAC of the input. -int aes_encrypt_cbc_mac(const BYTE in[], // plaintext - size_t in_len, // Must be a multiple of AES_BLOCK_SIZE - BYTE out[], // Output MAC - const WORD key[], // From the key setup - int keysize, // Bit length of the key, 128, 192, or 256 - const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long +int +aes_encrypt_cbc_mac(const BYTE in[], // plaintext + size_t in_len, // Must be a multiple of AES_BLOCK_SIZE + BYTE out[], // Output MAC + const WORD key[], // From the key setup + int keysize, // Bit length of the key, 128, 192, or 256 + const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long // Only output the CBC-MAC of the input. -int aes_decrypt_cbc(const BYTE in[], // plaintext - size_t in_len, // Must be a multiple of AES_BLOCK_SIZE - BYTE out[], // Output MAC - const WORD key[], // From the key setup - int keysize, // Bit length of the key, 128, 192, or 256 - const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long - +int +aes_decrypt_cbc(const BYTE in[], // plaintext + size_t in_len, // Must be a multiple of AES_BLOCK_SIZE + BYTE out[], // Output MAC + const WORD key[], // From the key setup + int keysize, // Bit length of the key, 128, 192, or 256 + const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long + /////////////////// // AES - CTR /////////////////// -void increment_iv(BYTE iv[], // Must be a multiple of AES_BLOCK_SIZE - int counter_size); // Bytes of the IV used for counting (low end) - -void aes_encrypt_ctr(const BYTE in[], // Plaintext - size_t in_len, // Any byte length - BYTE out[], // Ciphertext, same length as plaintext - const WORD key[], // From the key setup - int keysize, // Bit length of the key, 128, 192, or 256 - const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long - -void aes_decrypt_ctr(const BYTE in[], // Ciphertext - size_t in_len, // Any byte length - BYTE out[], // Plaintext, same length as ciphertext - const WORD key[], // From the key setup - int keysize, // Bit length of the key, 128, 192, or 256 - const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long - +void +increment_iv(BYTE iv[], // Must be a multiple of AES_BLOCK_SIZE + int counter_size); // Bytes of the IV used for counting (low end) + +void +aes_encrypt_ctr(const BYTE in[], // Plaintext + size_t in_len, // Any byte length + BYTE out[], // Ciphertext, same length as plaintext + const WORD key[], // From the key setup + int keysize, // Bit length of the key, 128, 192, or 256 + const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long + +void +aes_decrypt_ctr(const BYTE in[], // Ciphertext + size_t in_len, // Any byte length + BYTE out[], // Plaintext, same length as ciphertext + const WORD key[], // From the key setup + int keysize, // Bit length of the key, 128, 192, or 256 + const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long + /////////////////// // AES - CCM /////////////////// // Returns True if the input parameters do not violate any constraint. -int aes_encrypt_ccm(const BYTE plaintext[], // IN - Plaintext. - WORD plaintext_len, // IN - Plaintext length. - const BYTE associated_data[], // IN - Associated Data included in authentication, but not encryption. - unsigned short associated_data_len, // IN - Associated Data length in bytes. - const BYTE nonce[], // IN - The Nonce to be used for encryption. - unsigned short nonce_len, // IN - Nonce length in bytes. - BYTE ciphertext[], // OUT - Ciphertext, a concatination of the plaintext and the MAC. - WORD *ciphertext_len, // OUT - The length of the ciphertext, always plaintext_len + mac_len. - WORD mac_len, // IN - The desired length of the MAC, must be 4, 6, 8, 10, 12, 14, or 16. - const BYTE key[], // IN - The AES key for encryption. - int keysize); // IN - The length of the key in bits. Valid values are 128, 192, 256. - +int +aes_encrypt_ccm(const BYTE plaintext[], // IN - Plaintext. + WORD plaintext_len, // IN - Plaintext length. + const BYTE associated_data[], // IN - Associated Data included in authentication, but not encryption. + unsigned short associated_data_len, // IN - Associated Data length in bytes. + const BYTE nonce[], // IN - The Nonce to be used for encryption. + unsigned short nonce_len, // IN - Nonce length in bytes. + BYTE ciphertext[], // OUT - Ciphertext, a concatination of the plaintext and the MAC. + WORD *ciphertext_len, // OUT - The length of the ciphertext, always plaintext_len + mac_len. + WORD mac_len, // IN - The desired length of the MAC, must be 4, 6, 8, 10, 12, 14, or 16. + const BYTE key[], // IN - The AES key for encryption. + int keysize); // IN - The length of the key in bits. Valid values are 128, 192, 256. + // Returns True if the input parameters do not violate any constraint. // Use mac_auth to ensure decryption/validation was preformed correctly. // If authentication does not succeed, the plaintext is zeroed out. To overwride // this, call with mac_auth = NULL. The proper proceedure is to decrypt with // authentication enabled (mac_auth != NULL) and make a second call to that // ignores authentication explicitly if the first call failes. -int aes_decrypt_ccm(const BYTE ciphertext[], // IN - Ciphertext, the concatination of encrypted plaintext and MAC. - WORD ciphertext_len, // IN - Ciphertext length in bytes. - const BYTE assoc[], // IN - The Associated Data, required for authentication. - unsigned short assoc_len, // IN - Associated Data length in bytes. - const BYTE nonce[], // IN - The Nonce to use for decryption, same one as for encryption. - unsigned short nonce_len, // IN - Nonce length in bytes. - BYTE plaintext[], // OUT - The plaintext that was decrypted. Will need to be large enough to hold ciphertext_len - mac_len. - WORD *plaintext_len, // OUT - Length in bytes of the output plaintext, always ciphertext_len - mac_len . - WORD mac_len, // IN - The length of the MAC that was calculated. - int *mac_auth, // OUT - TRUE if authentication succeeded, FALSE if it did not. NULL pointer will ignore the authentication. - const BYTE key[], // IN - The AES key for decryption. - int keysize); // IN - The length of the key in BITS. Valid values are 128, 192, 256. - +int +aes_decrypt_ccm( + const BYTE ciphertext[], // IN - Ciphertext, the concatination of encrypted plaintext and MAC. + WORD ciphertext_len, // IN - Ciphertext length in bytes. + const BYTE assoc[], // IN - The Associated Data, required for authentication. + unsigned short assoc_len, // IN - Associated Data length in bytes. + const BYTE nonce[], // IN - The Nonce to use for decryption, same one as for encryption. + unsigned short nonce_len, // IN - Nonce length in bytes. + BYTE plaintext[], // OUT - The plaintext that was decrypted. Will need to be large enough to hold ciphertext_len - + // mac_len. + WORD *plaintext_len, // OUT - Length in bytes of the output plaintext, always ciphertext_len - mac_len . + WORD mac_len, // IN - The length of the MAC that was calculated. + int *mac_auth, // OUT - TRUE if authentication succeeded, FALSE if it did not. NULL pointer will ignore the + // authentication. + const BYTE key[], // IN - The AES key for decryption. + int keysize); // IN - The length of the key in BITS. Valid values are 128, 192, 256. + /////////////////// // Test functions /////////////////// -//int aes_test(); -//int aes_ecb_test(); -//int aes_cbc_test(); -//int aes_ctr_test(); -//int aes_ccm_test(); - -#endif // AES_H +// int aes_test(); +// int aes_ecb_test(); +// int aes_cbc_test(); +// int aes_ctr_test(); +// int aes_ccm_test(); + +#endif // AES_H diff --git a/examples/aes_encrypt/aesencrypt.c b/examples/aes_encrypt/aesencrypt.c index b84d27835..5763b00af 100644 --- a/examples/aes_encrypt/aesencrypt.c +++ b/examples/aes_encrypt/aesencrypt.c @@ -39,26 +39,26 @@ * aesencrypt.c - Encrypt UDP packets using AES ********************************************************************/ -#include -#include -#include +#include +#include #include #include -#include -#include +#include +#include #include -#include #include +#include +#include #include -#include +#include #include +#include #include -#include +#include "aes.h" #include "onvm_nflib.h" #include "onvm_pkt_helper.h" -#include "aes.h" #define NF_TAG "aes_encrypt" @@ -68,17 +68,13 @@ struct onvm_nf_info *nf_info; /* number of package between each print */ static uint32_t print_delay = 1000000; - static uint32_t destination; /* AES encryption parameters */ -BYTE key[1][32] = { - {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4} -}; -BYTE iv[1][16] = { - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f} -}; -WORD key_schedule[60]; //word Schedule +BYTE key[1][32] = {{0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4}}; +BYTE iv[1][16] = {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}}; +WORD key_schedule[60]; // word Schedule /* * Print a usage message @@ -102,27 +98,27 @@ parse_app_args(int argc, char *argv[], const char *progname) { while ((c = getopt(argc, argv, "d:p:")) != -1) { switch (c) { - case 'd': - destination = strtoul(optarg, NULL, 10); - dst_flag = 1; - break; - case 'p': - print_delay = strtoul(optarg, NULL, 10); - break; - case '?': - usage(progname); - if (optopt == 'd') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (optopt == 'p') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (isprint(optopt)) - RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); - else - RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); - return -1; - default: - usage(progname); - return -1; + case 'd': + destination = strtoul(optarg, NULL, 10); + dst_flag = 1; + break; + case 'p': + print_delay = strtoul(optarg, NULL, 10); + break; + case '?': + usage(progname); + if (optopt == 'd') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (optopt == 'p') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (isprint(optopt)) + RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); + else + RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); + return -1; + default: + usage(progname); + return -1; } } @@ -141,11 +137,11 @@ parse_app_args(int argc, char *argv[], const char *progname) { * than one lcore enabled. */ static void -do_stats_display(struct rte_mbuf* pkt) { - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; +do_stats_display(struct rte_mbuf *pkt) { + const char clr[] = {27, '[', '2', 'J', '\0'}; + const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'}; static uint64_t pkt_process = 0; - struct ipv4_hdr* ip; + struct ipv4_hdr *ip; pkt_process += print_delay; @@ -156,21 +152,21 @@ do_stats_display(struct rte_mbuf* pkt) { printf("-----\n"); printf("Port : %d\n", pkt->port); printf("Size : %d\n", pkt->pkt_len); - printf("N° : %"PRIu64"\n", pkt_process); + printf("N° : %" PRIu64 "\n", pkt_process); printf("\n\n"); ip = onvm_pkt_ipv4_hdr(pkt); if (ip != NULL) { - struct udp_hdr *udp; + struct udp_hdr *udp; onvm_pkt_print(pkt); - /* Check if we have a valid UDP packet */ - udp = onvm_pkt_udp_hdr(pkt); - if (udp != NULL) { - uint8_t * pkt_data; - pkt_data = ((uint8_t *) udp) + sizeof(struct udp_hdr); - printf("Payload : %.32s\n", pkt_data); - } + /* Check if we have a valid UDP packet */ + udp = onvm_pkt_udp_hdr(pkt); + if (udp != NULL) { + uint8_t *pkt_data; + pkt_data = ((uint8_t *)udp) + sizeof(struct udp_hdr); + printf("Payload : %.32s\n", pkt_data); + } } else { printf("No IP4 header found\n"); } @@ -178,7 +174,7 @@ do_stats_display(struct rte_mbuf* pkt) { static int packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__((unused)) struct onvm_nf_info *nf_info) { - struct udp_hdr *udp; + struct udp_hdr *udp; static uint32_t counter = 0; if (++counter == print_delay) { @@ -186,38 +182,38 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( counter = 0; } - /* Check if we have a valid UDP packet */ - udp = onvm_pkt_udp_hdr(pkt); - if (udp != NULL) { - uint8_t * pkt_data; - uint8_t * eth; - uint16_t plen; - uint16_t hlen; - - /* Get at the payload */ - pkt_data = ((uint8_t *) udp) + sizeof(struct udp_hdr); - /* Calculate length */ - eth = rte_pktmbuf_mtod(pkt, uint8_t *); - hlen = pkt_data - eth; - plen = pkt->pkt_len - hlen; - - /* Encrypt. */ - /* IV should change with every packet, but we don't have any - * way to send it to the other side. */ - aes_encrypt_ctr(pkt_data, plen, pkt_data, key_schedule, 256, iv[0]); - if (counter == 0) { - printf("Encrypted %d bytes at offset %d (%ld)\n", - plen, hlen, sizeof(struct ether_hdr) + sizeof(struct ipv4_hdr) + sizeof(struct udp_hdr)); - } - } + /* Check if we have a valid UDP packet */ + udp = onvm_pkt_udp_hdr(pkt); + if (udp != NULL) { + uint8_t *pkt_data; + uint8_t *eth; + uint16_t plen; + uint16_t hlen; + + /* Get at the payload */ + pkt_data = ((uint8_t *)udp) + sizeof(struct udp_hdr); + /* Calculate length */ + eth = rte_pktmbuf_mtod(pkt, uint8_t *); + hlen = pkt_data - eth; + plen = pkt->pkt_len - hlen; + + /* Encrypt. */ + /* IV should change with every packet, but we don't have any + * way to send it to the other side. */ + aes_encrypt_ctr(pkt_data, plen, pkt_data, key_schedule, 256, iv[0]); + if (counter == 0) { + printf("Encrypted %d bytes at offset %d (%ld)\n", plen, hlen, + sizeof(struct ether_hdr) + sizeof(struct ipv4_hdr) + sizeof(struct udp_hdr)); + } + } meta->action = ONVM_NF_ACTION_TONF; meta->destination = destination; return 0; } - -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; @@ -232,10 +228,10 @@ int main(int argc, char *argv[]) { rte_exit(EXIT_FAILURE, "Invalid command-line arguments\n"); } - /* Initialise encryption engine. Key should be configurable. */ - aes_key_setup(key[0], key_schedule, 256); + /* Initialise encryption engine. Key should be configurable. */ + aes_key_setup(key[0], key_schedule, 256); - onvm_nflib_run(nf_info, &packet_handler); + onvm_nflib_run(nf_info, &packet_handler); printf("If we reach here, program is ending\n"); return 0; } diff --git a/examples/arp_response/arp_response.c b/examples/arp_response/arp_response.c index 68a030001..1fc5508a2 100644 --- a/examples/arp_response/arp_response.c +++ b/examples/arp_response/arp_response.c @@ -38,24 +38,24 @@ * arp_response.c - an example using onvm. If it receives an ARP packet, send a response. ********************************************************************/ -#include -#include -#include +#include +#include #include #include -#include -#include +#include +#include #include -#include #include +#include +#include +#include #include -#include -#include #include -#include -#include +#include #include +#include +#include #include "onvm_nflib.h" #include "onvm_pkt_helper.h" @@ -85,8 +85,13 @@ usage(const char *progname) { printf("%s [EAL args] -- [NF Lib args] -- -d -s [-p enable printing]\n", progname); printf("%s -F [EAL args] -- [NF_LIB args] -- [NF args]>\n\n", progname); printf("Flags:\n"); - printf(" - `-d `: the NF will send non-ARP packets to the NF at this service ID, e.g. `-d 2` sends packets to service ID 2\n"); - printf(" - `-s `: the NF will map each comma separated IP (no spaces) to the corresponding port. Example: `-s 10.0.0.31,11.0.0.31` maps port 0 to 10.0.0.31, and port 1 to 11.0.0.31. If 0.0.0.0 is inputted, the IP will be 0. If too few IPs are inputted, the remaining ports will be ignored.\n"); + printf( + " - `-d `: the NF will send non-ARP packets to the NF at this service ID, e.g. `-d 2` " + "sends packets to service ID 2\n"); + printf( + " - `-s `: the NF will map each comma separated IP (no spaces) to the corresponding port. " + "Example: `-s 10.0.0.31,11.0.0.31` maps port 0 to 10.0.0.31, and port 1 to 11.0.0.31. If 0.0.0.0 is " + "inputted, the IP will be 0. If too few IPs are inputted, the remaining ports will be ignored.\n"); printf(" - `-p`: Enables printing of log information\n"); } @@ -141,53 +146,53 @@ parse_app_args(int argc, char *argv[], const char *progname) { } while ((c = getopt(argc, argv, "d:s:p")) != -1) { - switch(c) { - case 'd': - state_info->nf_destination = strtoul(optarg, NULL, 10); - dst_flag = 1; - RTE_LOG(INFO, APP, "Sending packets to service ID %d\n", state_info->nf_destination); - break; - case 's': - num_ips = get_ip_count(optarg, delim); - if (num_ips > ports->num_ports) { - RTE_LOG(INFO, APP, "Too many IPs were entered!\n"); - return -1; - } - - if (num_ips < 0) { - RTE_LOG(INFO, APP, "Invalid IP pointer\n"); - return -1; - } + switch (c) { + case 'd': + state_info->nf_destination = strtoul(optarg, NULL, 10); + dst_flag = 1; + RTE_LOG(INFO, APP, "Sending packets to service ID %d\n", state_info->nf_destination); + break; + case 's': + num_ips = get_ip_count(optarg, delim); + if (num_ips > ports->num_ports) { + RTE_LOG(INFO, APP, "Too many IPs were entered!\n"); + return -1; + } - token = strtok_r(optarg, delim, &buffer); - while (token != NULL) { - result = onvm_pkt_parse_ip(token, &state_info->source_ips[current_ip]); - if (result < 0) { - RTE_LOG(INFO, APP, "Invalid IP entered"); + if (num_ips < 0) { + RTE_LOG(INFO, APP, "Invalid IP pointer\n"); return -1; } - ++current_ip; - token = strtok_r(NULL, delim, &buffer); - } - - ip_flag = 1; - break; - case 'p': - state_info->print_flag = 1; - break; - case '?': - usage(progname); - if (optopt == 'd') - RTE_LOG(INFO, APP, "Option -%c requires an argument\n", optopt); - else if (optopt == 'd') - RTE_LOG(INFO, APP, "Option -%c requires an argument\n", optopt); - else - RTE_LOG(INFO, APP, "Unknown option character\n"); - - return -1; - default: - usage(progname); - return -1; + + token = strtok_r(optarg, delim, &buffer); + while (token != NULL) { + result = onvm_pkt_parse_ip(token, &state_info->source_ips[current_ip]); + if (result < 0) { + RTE_LOG(INFO, APP, "Invalid IP entered"); + return -1; + } + ++current_ip; + token = strtok_r(NULL, delim, &buffer); + } + + ip_flag = 1; + break; + case 'p': + state_info->print_flag = 1; + break; + case '?': + usage(progname); + if (optopt == 'd') + RTE_LOG(INFO, APP, "Option -%c requires an argument\n", optopt); + else if (optopt == 'd') + RTE_LOG(INFO, APP, "Option -%c requires an argument\n", optopt); + else + RTE_LOG(INFO, APP, "Unknown option character\n"); + + return -1; + default: + usage(progname); + return -1; } } @@ -230,13 +235,13 @@ send_arp_reply(int port, struct ether_addr *tha, uint32_t tip) { out_pkt->data_len = pkt_size; out_pkt->pkt_len = pkt_size; - //SET ETHER HEADER INFO + // SET ETHER HEADER INFO eth_hdr = onvm_pkt_ether_hdr(out_pkt); ether_addr_copy(&ports->mac[port], ð_hdr->s_addr); eth_hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_ARP); ether_addr_copy(tha, ð_hdr->d_addr); - //SET ARP HDR INFO + // SET ARP HDR INFO out_arp_hdr = rte_pktmbuf_mtod_offset(out_pkt, struct arp_hdr *, sizeof(struct ether_hdr)); out_arp_hdr->arp_hrd = rte_cpu_to_be_16(ARP_HRD_ETHER); @@ -251,7 +256,7 @@ send_arp_reply(int port, struct ether_addr *tha, uint32_t tip) { out_arp_hdr->arp_data.arp_tip = tip; ether_addr_copy(tha, &out_arp_hdr->arp_data.arp_tha); - //SEND PACKET OUT/SET METAINFO + // SEND PACKET OUT/SET METAINFO pmeta = onvm_get_pkt_meta(out_pkt); pmeta->destination = port; pmeta->action = ONVM_NF_ACTION_OUT; @@ -277,9 +282,11 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( switch (rte_cpu_to_be_16(in_arp_hdr->arp_op)) { case ARP_OP_REQUEST: if (in_arp_hdr->arp_data.arp_tip == state_info->source_ips[ports->id[pkt->port]]) { - result = send_arp_reply(pkt->port, ð_hdr->s_addr, in_arp_hdr->arp_data.arp_sip); + result = + send_arp_reply(pkt->port, ð_hdr->s_addr, in_arp_hdr->arp_data.arp_sip); if (state_info->print_flag) { - printf("ARP Reply From Port %d (ID %d): %d\n", pkt->port, ports->id[pkt->port], result); + printf("ARP Reply From Port %d (ID %d): %d\n", pkt->port, + ports->id[pkt->port], result); } meta->action = ONVM_NF_ACTION_DROP; return 0; @@ -290,7 +297,8 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( break; default: if (state_info->print_flag) { - printf("ARP with opcode %d, port %d (ID %d) DROPPED\n", rte_cpu_to_be_16(in_arp_hdr->arp_op),pkt->port, ports->id[pkt->port]); + printf("ARP with opcode %d, port %d (ID %d) DROPPED\n", + rte_cpu_to_be_16(in_arp_hdr->arp_op), pkt->port, ports->id[pkt->port]); } } } @@ -300,7 +308,8 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( return 0; } -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; diff --git a/examples/basic_monitor/monitor.c b/examples/basic_monitor/monitor.c index 4fa51af03..7e4ba4456 100644 --- a/examples/basic_monitor/monitor.c +++ b/examples/basic_monitor/monitor.c @@ -38,21 +38,21 @@ * monitor.c - an example using onvm. Print a message each p package received ********************************************************************/ -#include -#include -#include +#include +#include #include #include -#include -#include +#include +#include #include -#include #include +#include +#include #include -#include -#include #include +#include +#include #include "onvm_nflib.h" #include "onvm_pkt_helper.h" @@ -79,7 +79,7 @@ static void usage(const char *progname) { printf("Usage:\n"); printf("%s [EAL args] -- [NF_LIB args] -- -p \n", progname); - printf("%s -F [EAL args] -- [NF_LIB args] -- [NF args]\n\n", progname); + printf("%s -F [EAL args] -- [NF_LIB args] -- [NF args]\n\n", progname); printf("Flags:\n"); printf(" - `-p `: number of packets between each print, e.g. `-p 1` prints every packets.\n"); } @@ -91,24 +91,24 @@ static int parse_app_args(int argc, char *argv[], const char *progname) { int c; - while ((c = getopt (argc, argv, "p:")) != -1) { + while ((c = getopt(argc, argv, "p:")) != -1) { switch (c) { - case 'p': - print_delay = strtoul(optarg, NULL, 10); - RTE_LOG(INFO, APP, "print_delay = %d\n", print_delay); - break; - case '?': - usage(progname); - if (optopt == 'p') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (isprint(optopt)) - RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); - else - RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); - return -1; - default: - usage(progname); - return -1; + case 'p': + print_delay = strtoul(optarg, NULL, 10); + RTE_LOG(INFO, APP, "print_delay = %d\n", print_delay); + break; + case '?': + usage(progname); + if (optopt == 'p') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (isprint(optopt)) + RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); + else + RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); + return -1; + default: + usage(progname); + return -1; } } return optind; @@ -121,11 +121,11 @@ parse_app_args(int argc, char *argv[], const char *progname) { * than one lcore enabled. */ static void -do_stats_display(struct rte_mbuf* pkt) { - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; +do_stats_display(struct rte_mbuf *pkt) { + const char clr[] = {27, '[', '2', 'J', '\0'}; + const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'}; static uint64_t pkt_process = 0; - struct ipv4_hdr* ip; + struct ipv4_hdr *ip; pkt_process += print_delay; @@ -137,7 +137,7 @@ do_stats_display(struct rte_mbuf* pkt) { printf("Port : %d\n", pkt->port); printf("Size : %d\n", pkt->pkt_len); printf("Hash : %u\n", pkt->hash.rss); - printf("N° : %"PRIu64"\n", pkt_process); + printf("N° : %" PRIu64 "\n", pkt_process); printf("\n\n"); ip = onvm_pkt_ipv4_hdr(pkt); @@ -178,8 +178,8 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( return 0; } - -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; diff --git a/examples/bridge/bridge.c b/examples/bridge/bridge.c index 8f76bd948..23c3934d9 100644 --- a/examples/bridge/bridge.c +++ b/examples/bridge/bridge.c @@ -38,20 +38,20 @@ * bridge.c - send all packets from one port out the other. ********************************************************************/ -#include -#include -#include +#include +#include #include #include -#include -#include +#include +#include #include -#include #include +#include +#include #include -#include #include +#include #include "onvm_nflib.h" #include "onvm_pkt_helper.h" @@ -72,7 +72,7 @@ usage(const char *progname) { printf("Usage:\n"); printf("%s [EAL args] -- [NF_LIB args] -- -p \n", progname); printf("%s -F [EAL args] -- [NF_LIB args] -- [NF args]\n\n", progname); - printf("Flags:\n"); + printf("Flags:\n"); printf(" - `-p `: number of packets between each print, e.g. `-p 1` prints every packets.\n"); } @@ -83,23 +83,23 @@ static int parse_app_args(int argc, char *argv[], const char *progname) { int c; - while ((c = getopt (argc, argv, "p:")) != -1) { + while ((c = getopt(argc, argv, "p:")) != -1) { switch (c) { - case 'p': - print_delay = strtoul(optarg, NULL, 10); - break; - case '?': - usage(progname); - if (optopt == 'p') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (isprint(optopt)) - RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); - else - RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); - return -1; - default: - usage(progname); - return -1; + case 'p': + print_delay = strtoul(optarg, NULL, 10); + break; + case '?': + usage(progname); + if (optopt == 'p') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (isprint(optopt)) + RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); + else + RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); + return -1; + default: + usage(progname); + return -1; } } return optind; @@ -112,12 +112,12 @@ parse_app_args(int argc, char *argv[], const char *progname) { * than one lcore enabled. */ static void -do_stats_display(struct rte_mbuf* pkt) { - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; +do_stats_display(struct rte_mbuf *pkt) { + const char clr[] = {27, '[', '2', 'J', '\0'}; + const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'}; static uint64_t pkt_process = 0; - struct ipv4_hdr* ip; + struct ipv4_hdr *ip; pkt_process += print_delay; @@ -129,13 +129,12 @@ do_stats_display(struct rte_mbuf* pkt) { printf("Port : %d\n", pkt->port); printf("Size : %d\n", pkt->pkt_len); printf("Type : %d\n", pkt->packet_type); - printf("Number of packet processed : %"PRIu64"\n", pkt_process); + printf("Number of packet processed : %" PRIu64 "\n", pkt_process); ip = onvm_pkt_ipv4_hdr(pkt); - if(ip != NULL) { + if (ip != NULL) { onvm_pkt_print(pkt); - } - else { + } else { printf("Not IP4\n"); } @@ -152,16 +151,15 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( if (pkt->port == 0) { meta->destination = 1; - } - else { + } else { meta->destination = 0; } meta->action = ONVM_NF_ACTION_OUT; return 0; } - -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; diff --git a/examples/flow_table/flow_table.c b/examples/flow_table/flow_table.c index 32d5d30f9..1a4901d97 100644 --- a/examples/flow_table/flow_table.c +++ b/examples/flow_table/flow_table.c @@ -38,43 +38,43 @@ * flow_table.c - a simple flow table NF ********************************************************************/ -#include -#include -#include +#include +#include #include #include -#include -#include +#include +#include #include -#include #include +#include +#include #include -#include -#include -#include #include #include +#include #include -#include -#include +#include #include +#include +#include +#include -#include "onvm_nflib.h" -#include "onvm_pkt_helper.h" #include "flow_table.h" -#include "sdn.h" -#include "onvm_flow_table.h" #include "onvm_flow_dir.h" +#include "onvm_flow_table.h" +#include "onvm_nflib.h" +#include "onvm_pkt_helper.h" #include "onvm_sc_common.h" +#include "sdn.h" #define NF_TAG "flow_table" /* Struct that contains information about this NF */ struct onvm_nf_info *nf_info; -struct rte_ring* ring_to_sdn; -struct rte_ring* ring_from_sdn; +struct rte_ring *ring_to_sdn; +struct rte_ring *ring_from_sdn; #define SDN_RING_SIZE 65536 /* number of package between each print */ @@ -90,17 +90,15 @@ setup_rings(void) { ring_to_sdn = rte_ring_lookup("ring_to_sdn"); ring_from_sdn = rte_ring_lookup("ring_from_sdn"); if (ring_to_sdn) { - rte_ring_free(ring_to_sdn); + rte_ring_free(ring_to_sdn); } if (ring_from_sdn) { - rte_ring_free(ring_from_sdn); + rte_ring_free(ring_from_sdn); } - ring_to_sdn = rte_ring_create("ring_to_sdn", SDN_RING_SIZE, - rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ); - ring_from_sdn = rte_ring_create("ring_from_sdn", SDN_RING_SIZE, - rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ); - if(ring_to_sdn == NULL || ring_from_sdn == NULL) { + ring_to_sdn = rte_ring_create("ring_to_sdn", SDN_RING_SIZE, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ); + ring_from_sdn = rte_ring_create("ring_from_sdn", SDN_RING_SIZE, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ); + if (ring_to_sdn == NULL || ring_from_sdn == NULL) { onvm_nflib_stop(nf_info); rte_exit(EXIT_FAILURE, "Unable to create SDN rings\n"); } @@ -123,35 +121,34 @@ parse_app_args(int argc, char *argv[]) { opterr = 0; - while ((c = getopt (argc, argv, "p:")) != -1) + while ((c = getopt(argc, argv, "p:")) != -1) switch (c) { - case 'p': - print_delay = strtoul(optarg, NULL, 10); - break; - case '?': - usage(progname); - if (optopt == 'p') - fprintf(stderr, "Option -%c requires an argument.\n", optopt); - else if (isprint(optopt)) - fprintf(stderr, "Unknown option `-%c'.\n", optopt); - else - fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); - return -1; - default: - return -1; + case 'p': + print_delay = strtoul(optarg, NULL, 10); + break; + case '?': + usage(progname); + if (optopt == 'p') + fprintf(stderr, "Option -%c requires an argument.\n", optopt); + else if (isprint(optopt)) + fprintf(stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); + return -1; + default: + return -1; } return optind; } static void -do_stats_display(struct rte_mbuf* pkt, int32_t tbl_index) { - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; +do_stats_display(struct rte_mbuf *pkt, int32_t tbl_index) { + const char clr[] = {27, '[', '2', 'J', '\0'}; + const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'}; static uint64_t total_pkts = 0; /* Fix unused variable warnings: */ (void)pkt; - struct onvm_flow_entry *flow_entry = (struct onvm_flow_entry *)onvm_ft_get_data(sdn_ft, tbl_index); total_pkts += print_delay; @@ -160,42 +157,42 @@ do_stats_display(struct rte_mbuf* pkt, int32_t tbl_index) { printf("FLOW TABLE NF\n"); printf("-----\n"); - printf("Total pkts : %"PRIu64"\n", total_pkts); + printf("Total pkts : %" PRIu64 "\n", total_pkts); printf("Total flows : %d\n", total_flows); printf("Flow ID : %d\n", tbl_index); - printf("Flow pkts : %"PRIu64"\n", flow_entry->packet_count); - // printf("Flow Action : %d\n", flow_entry->action); - // printf("Flow Dest : %d\n", flow_entry->destination); + printf("Flow pkts : %" PRIu64 "\n", flow_entry->packet_count); + // printf("Flow Action : %d\n", flow_entry->action); + // printf("Flow Dest : %d\n", flow_entry->destination); printf("\n\n"); - #ifdef DEBUG_PRINT - struct ipv4_hdr* ip; - ip = onvm_pkt_ipv4_hdr(pkt); - if (ip != NULL) { - onvm_pkt_print(pkt); - } else { - printf("Not an IP4 packet\n"); - } - #endif +#ifdef DEBUG_PRINT + struct ipv4_hdr *ip; + ip = onvm_pkt_ipv4_hdr(pkt); + if (ip != NULL) { + onvm_pkt_print(pkt); + } else { + printf("Not an IP4 packet\n"); + } +#endif } static int -flow_table_hit(struct rte_mbuf* pkt, struct onvm_pkt_meta* meta) { +flow_table_hit(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta) { (void)pkt; - meta->chain_index = 0; - meta->action = ONVM_NF_ACTION_NEXT; - meta->destination = 0; + meta->chain_index = 0; + meta->action = ONVM_NF_ACTION_NEXT; + meta->destination = 0; return 0; } static int -flow_table_miss(struct rte_mbuf* pkt, struct onvm_pkt_meta* meta) { +flow_table_miss(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta) { int ret; /* Buffer new flows until we get response from SDN controller. */ ret = rte_ring_enqueue(ring_to_sdn, pkt); - if(ret != 0) { + if (ret != 0) { printf("ERROR enqueing to SDN ring\n"); meta->action = ONVM_NF_ACTION_DROP; meta->destination = 0; @@ -211,9 +208,9 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( int32_t tbl_index; int action; - struct onvm_flow_entry *flow_entry; + struct onvm_flow_entry *flow_entry; - if(!onvm_pkt_is_ipv4(pkt)) { + if (!onvm_pkt_is_ipv4(pkt)) { printf("Non-ipv4 packet\n"); meta->action = ONVM_NF_ACTION_TONF; meta->destination = def_destination; @@ -221,41 +218,39 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( } tbl_index = onvm_flow_dir_get_pkt(pkt, &flow_entry); - if(tbl_index >= 0) { - #ifdef DEBUG_PRINT - printf("Found existing flow %d\n", tbl_index); - #endif + if (tbl_index >= 0) { +#ifdef DEBUG_PRINT + printf("Found existing flow %d\n", tbl_index); +#endif /* Existing flow */ action = flow_table_hit(pkt, meta); - } - else if (tbl_index == -ENOENT) { - #ifdef DEBUG_PRINT - printf("Unkown flow\n"); - #endif + } else if (tbl_index == -ENOENT) { +#ifdef DEBUG_PRINT + printf("Unkown flow\n"); +#endif /* New flow */ action = flow_table_miss(pkt, meta); - } - else { - #ifdef DEBUG_PRINT + } else { +#ifdef DEBUG_PRINT printf("Error in flow lookup: %d (ENOENT=%d, EINVAL=%d)\n", tbl_index, ENOENT, EINVAL); onvm_pkt_print(pkt); - #endif +#endif onvm_nflib_stop(nf_info); rte_exit(EXIT_FAILURE, "Error in flow lookup\n"); } if (++counter == print_delay && print_delay != 0) { - if (tbl_index >= 0) { - do_stats_display(pkt, tbl_index); - counter = 0; - } + if (tbl_index >= 0) { + do_stats_display(pkt, tbl_index); + counter = 0; + } } return action; } - -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int retval; unsigned sdn_core = 0; @@ -269,7 +264,7 @@ int main(int argc, char *argv[]) { } printf("Flow table running on %d\n", rte_lcore_id()); - def_destination = nf_info->service_id + 1; + def_destination = nf_info->service_id + 1; printf("Setting up hash table with default destination: %d\n", def_destination); total_flows = 0; @@ -280,8 +275,8 @@ int main(int argc, char *argv[]) { sdn_core = rte_get_next_lcore(sdn_core, 1, 1); rte_eal_remote_launch(setup_securechannel, NULL, sdn_core); - /* Map sdn_ft table */ - onvm_flow_dir_nf_init(); + /* Map sdn_ft table */ + onvm_flow_dir_nf_init(); printf("Starting packet handler.\n"); onvm_nflib_run(nf_info, &packet_handler); printf("NF exiting...\n"); diff --git a/examples/flow_table/flow_table.h b/examples/flow_table/flow_table.h index 3cc4ab6c7..72509ba0b 100644 --- a/examples/flow_table/flow_table.h +++ b/examples/flow_table/flow_table.h @@ -55,8 +55,8 @@ usage(const char *progname) { } struct flow_table_entry { - uint32_t count; /* Number of packets in flow */ - uint8_t action; /* Action to be performed */ + uint32_t count; /* Number of packets in flow */ + uint8_t action; /* Action to be performed */ uint16_t destination; /* where to go next */ }; diff --git a/examples/flow_table/msgbuf.c b/examples/flow_table/msgbuf.c index 5b02a5c00..5139631c0 100644 --- a/examples/flow_table/msgbuf.c +++ b/examples/flow_table/msgbuf.c @@ -49,125 +49,117 @@ #include "msgbuf.h" #ifndef MIN -#define MIN(x,y) (((x) < (y))? (x) : (y)) +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) #endif -struct msgbuf * msgbuf_new(int bufsize) -{ - struct msgbuf * mbuf; - mbuf = malloc(sizeof(*mbuf)); - assert(mbuf); - mbuf->len = bufsize; - mbuf->buf = malloc(mbuf->len); - assert(mbuf->len); - mbuf->start = mbuf->end = 0; +struct msgbuf * +msgbuf_new(int bufsize) { + struct msgbuf *mbuf; + mbuf = malloc(sizeof(*mbuf)); + assert(mbuf); + mbuf->len = bufsize; + mbuf->buf = malloc(mbuf->len); + assert(mbuf->len); + mbuf->start = mbuf->end = 0; - return mbuf; + return mbuf; } -int msgbuf_read(struct msgbuf * mbuf, int sock) -{ - int count = read(sock, &mbuf->buf[mbuf->end], mbuf->len - mbuf->end); - if(count>0) - mbuf->end+=count; - if( mbuf->end >= mbuf->len) // resize buffer if need be - msgbuf_grow(mbuf); - return count; +int +msgbuf_read(struct msgbuf *mbuf, int sock) { + int count = read(sock, &mbuf->buf[mbuf->end], mbuf->len - mbuf->end); + if (count > 0) + mbuf->end += count; + if (mbuf->end >= mbuf->len) // resize buffer if need be + msgbuf_grow(mbuf); + return count; } -int msgbuf_read_all(struct msgbuf * mbuf, int sock, int len) -{ - - int count = 0; - int tmp; - while(count < len) - { - tmp =msgbuf_read(mbuf,sock); - if((tmp == 0) || - ((tmp<0) && (errno != EWOULDBLOCK ) && (errno != EINTR) && (errno != EAGAIN))) - return tmp; - if(tmp > 0) - count+=tmp; - } - return count; +int +msgbuf_read_all(struct msgbuf *mbuf, int sock, int len) { + int count = 0; + int tmp; + while (count < len) { + tmp = msgbuf_read(mbuf, sock); + if ((tmp == 0) || ((tmp < 0) && (errno != EWOULDBLOCK) && (errno != EINTR) && (errno != EAGAIN))) + return tmp; + if (tmp > 0) + count += tmp; + } + return count; } -int msgbuf_write(struct msgbuf * mbuf, int sock, int len) -{ - int send_len = mbuf->end - mbuf->start; - if (len > 0) - { - if (send_len < len) - return -1; - if (send_len > len) - send_len = len; - } - int count = write(sock, &mbuf->buf[mbuf->start], send_len); - if(count>0) - mbuf->start+=count; - if(mbuf->start >= mbuf->end) - mbuf->start = mbuf->end = 0; - return count; +int +msgbuf_write(struct msgbuf *mbuf, int sock, int len) { + int send_len = mbuf->end - mbuf->start; + if (len > 0) { + if (send_len < len) + return -1; + if (send_len > len) + send_len = len; + } + int count = write(sock, &mbuf->buf[mbuf->start], send_len); + if (count > 0) + mbuf->start += count; + if (mbuf->start >= mbuf->end) + mbuf->start = mbuf->end = 0; + return count; } -int msgbuf_write_all(struct msgbuf * mbuf, int sock, int len) -{ - int tmp=0,count=0; - while(mbuf->start < mbuf->end) - { - tmp=msgbuf_write(mbuf, sock, len); - if((tmp < 0) && - (errno != EAGAIN) && - (errno != EWOULDBLOCK) && - (errno != EINTR)) - - return tmp; - if(count > 0) - count+=tmp; - } - return count; +int +msgbuf_write_all(struct msgbuf *mbuf, int sock, int len) { + int tmp = 0, count = 0; + while (mbuf->start < mbuf->end) { + tmp = msgbuf_write(mbuf, sock, len); + if ((tmp < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINTR)) + + return tmp; + if (count > 0) + count += tmp; + } + return count; } -void msgbuf_clear(struct msgbuf * mbuf) -{ - mbuf->start = mbuf->end = 0; +void +msgbuf_clear(struct msgbuf *mbuf) { + mbuf->start = mbuf->end = 0; } -void msgbuf_grow(struct msgbuf * mbuf) -{ - mbuf->len *=2 ; - mbuf->buf = realloc(mbuf->buf, mbuf->len); - if(mbuf->buf == NULL) { - perror("msgbuf_grow failed"); - printf("buffer len: %d\n", mbuf->len); - } - assert(mbuf->buf); +void +msgbuf_grow(struct msgbuf *mbuf) { + mbuf->len *= 2; + mbuf->buf = realloc(mbuf->buf, mbuf->len); + if (mbuf->buf == NULL) { + perror("msgbuf_grow failed"); + printf("buffer len: %d\n", mbuf->len); + } + assert(mbuf->buf); } -void * msgbuf_peek(struct msgbuf *mbuf) -{ - if(mbuf->start >= mbuf->end) - return NULL; - return (void *) &mbuf->buf[mbuf->start]; +void * +msgbuf_peek(struct msgbuf *mbuf) { + if (mbuf->start >= mbuf->end) + return NULL; + return (void *)&mbuf->buf[mbuf->start]; } -int msgbuf_pull(struct msgbuf *mbuf, char * buf, int count) -{ - int min = MIN(count, mbuf->end - mbuf->start); - if( min <= 0) - return -1; - if(buf) // don't write if NULL - memcpy(buf, &mbuf->buf[mbuf->start], min); - mbuf->start+=min; - if(mbuf->start>= mbuf->end) - mbuf->start = mbuf->end = 0; - return min; +int +msgbuf_pull(struct msgbuf *mbuf, char *buf, int count) { + int min = MIN(count, mbuf->end - mbuf->start); + if (min <= 0) + return -1; + if (buf) // don't write if NULL + memcpy(buf, &mbuf->buf[mbuf->start], min); + mbuf->start += min; + if (mbuf->start >= mbuf->end) + mbuf->start = mbuf->end = 0; + return min; } -void msgbuf_push(struct msgbuf *mbuf, char *buf, int count) -{ - while((mbuf->end + count) > mbuf->len) - msgbuf_grow(mbuf); - memcpy(&mbuf->buf[mbuf->end], buf, count); - mbuf->end += count; +void +msgbuf_push(struct msgbuf *mbuf, char *buf, int count) { + while ((mbuf->end + count) > mbuf->len) + msgbuf_grow(mbuf); + memcpy(&mbuf->buf[mbuf->end], buf, count); + mbuf->end += count; } diff --git a/examples/flow_table/msgbuf.h b/examples/flow_table/msgbuf.h index 7a2a3936c..26f7a4348 100644 --- a/examples/flow_table/msgbuf.h +++ b/examples/flow_table/msgbuf.h @@ -41,22 +41,31 @@ #ifndef MSGBUF_H #define MSGBUF_H -struct msgbuf -{ - char* buf; - int len, start, end; +struct msgbuf { + char *buf; + int len, start, end; }; -struct msgbuf* msgbuf_new(int bufsize); -int msgbuf_read(struct msgbuf *mbuf, int sock); -int msgbuf_read_all(struct msgbuf *mbuf, int sock, int len); -int msgbuf_write(struct msgbuf *mbuf, int sock, int len); -int msgbuf_write_all(struct msgbuf *mbuf, int sock, int len); -void msgbuf_grow(struct msgbuf *mbuf); -void msgbuf_clear(struct msgbuf *mbuf); -void* msgbuf_peek(struct msgbuf *mbuf); -int msgbuf_pull(struct msgbuf *mbuf, char *buf, int count); -void msgbuf_push(struct msgbuf *mbuf, char *buf, int count); +struct msgbuf * +msgbuf_new(int bufsize); +int +msgbuf_read(struct msgbuf *mbuf, int sock); +int +msgbuf_read_all(struct msgbuf *mbuf, int sock, int len); +int +msgbuf_write(struct msgbuf *mbuf, int sock, int len); +int +msgbuf_write_all(struct msgbuf *mbuf, int sock, int len); +void +msgbuf_grow(struct msgbuf *mbuf); +void +msgbuf_clear(struct msgbuf *mbuf); +void * +msgbuf_peek(struct msgbuf *mbuf); +int +msgbuf_pull(struct msgbuf *mbuf, char *buf, int count); +void +msgbuf_push(struct msgbuf *mbuf, char *buf, int count); #define msgbuf_count_buffered(mbuf) ((mbuf->end - mbuf->start)) #endif diff --git a/examples/flow_table/openflow.h b/examples/flow_table/openflow.h index c0b5090d1..9fdb8b4ce 100644 --- a/examples/flow_table/openflow.h +++ b/examples/flow_table/openflow.h @@ -43,12 +43,11 @@ #endif #ifdef SWIG -#define OFP_ASSERT(EXPR) /* SWIG can't handle OFP_ASSERT. */ +#define OFP_ASSERT(EXPR) /* SWIG can't handle OFP_ASSERT. */ #elif !defined(__cplusplus) /* Build-time assertion for use in a declaration context. */ -#define OFP_ASSERT(EXPR) \ - extern int (*build_assert(void))[ sizeof(struct { \ - unsigned int build_assert_failed : (EXPR) ? 1 : -1; })] +#define OFP_ASSERT(EXPR) \ + extern int(*build_assert(void))[sizeof(struct { unsigned int build_assert_failed : (EXPR) ? 1 : -1; })] #else /* __cplusplus */ #define OFP_ASSERT(_EXPR) typedef int build_assert_failed[(_EXPR) ? 1 : -1] #endif /* __cplusplus */ @@ -56,7 +55,7 @@ #ifndef SWIG #define OFP_PACKED __attribute__((packed)) #else -#define OFP_PACKED /* SWIG doesn't understand __attribute. */ +#define OFP_PACKED /* SWIG doesn't understand __attribute. */ #endif /* Version number: @@ -66,123 +65,123 @@ /* The most significant bit being set in the version field indicates an * experimental OpenFlow version. */ -#define OFP_VERSION 0x01 +#define OFP_VERSION 0x01 #define OFP_MAX_TABLE_NAME_LEN 32 -#define OFP_MAX_PORT_NAME_LEN 16 +#define OFP_MAX_PORT_NAME_LEN 16 -#define OFP_TCP_PORT 6633 -#define OFP_SSL_PORT 6633 +#define OFP_TCP_PORT 6633 +#define OFP_SSL_PORT 6633 -#define OFP_ETH_ALEN 6 /* Bytes in an Ethernet address. */ +#define OFP_ETH_ALEN 6 /* Bytes in an Ethernet address. */ /* Port numbering. Physical ports are numbered starting from 1. */ enum ofp_port { - /* Maximum number of physical switch ports. */ - OFPP_MAX = 0xff00, - - /* Fake output "ports". */ - OFPP_IN_PORT = 0xfff8, /* Send the packet out the input port. This - virtual port must be explicitly used - in order to send back out of the input - port. */ - OFPP_TABLE = 0xfff9, /* Perform actions in flow table. - NB: This can only be the destination - port for packet-out messages. */ - OFPP_NORMAL = 0xfffa, /* Process with normal L2/L3 switching. */ - OFPP_FLOOD = 0xfffb, /* All physical ports except input port and - those disabled by STP. */ - OFPP_ALL = 0xfffc, /* All physical ports except input port. */ - OFPP_CONTROLLER = 0xfffd, /* Send to controller. */ - OFPP_LOCAL = 0xfffe, /* Local openflow "port". */ - OFPP_NONE = 0xffff /* Not associated with a physical port. */ + /* Maximum number of physical switch ports. */ + OFPP_MAX = 0xff00, + + /* Fake output "ports". */ + OFPP_IN_PORT = 0xfff8, /* Send the packet out the input port. This + virtual port must be explicitly used + in order to send back out of the input + port. */ + OFPP_TABLE = 0xfff9, /* Perform actions in flow table. + NB: This can only be the destination + port for packet-out messages. */ + OFPP_NORMAL = 0xfffa, /* Process with normal L2/L3 switching. */ + OFPP_FLOOD = 0xfffb, /* All physical ports except input port and + those disabled by STP. */ + OFPP_ALL = 0xfffc, /* All physical ports except input port. */ + OFPP_CONTROLLER = 0xfffd, /* Send to controller. */ + OFPP_LOCAL = 0xfffe, /* Local openflow "port". */ + OFPP_NONE = 0xffff /* Not associated with a physical port. */ }; enum ofp_type { - /* Immutable messages. */ - OFPT_HELLO, /* Symmetric message */ - OFPT_ERROR, /* Symmetric message */ - OFPT_ECHO_REQUEST, /* Symmetric message */ - OFPT_ECHO_REPLY, /* Symmetric message */ - OFPT_VENDOR, /* Symmetric message */ + /* Immutable messages. */ + OFPT_HELLO, /* Symmetric message */ + OFPT_ERROR, /* Symmetric message */ + OFPT_ECHO_REQUEST, /* Symmetric message */ + OFPT_ECHO_REPLY, /* Symmetric message */ + OFPT_VENDOR, /* Symmetric message */ - /* Switch configuration messages. */ - OFPT_FEATURES_REQUEST, /* Controller/switch message */ - OFPT_FEATURES_REPLY, /* Controller/switch message */ - OFPT_GET_CONFIG_REQUEST, /* Controller/switch message */ - OFPT_GET_CONFIG_REPLY, /* Controller/switch message */ - OFPT_SET_CONFIG, /* Controller/switch message */ + /* Switch configuration messages. */ + OFPT_FEATURES_REQUEST, /* Controller/switch message */ + OFPT_FEATURES_REPLY, /* Controller/switch message */ + OFPT_GET_CONFIG_REQUEST, /* Controller/switch message */ + OFPT_GET_CONFIG_REPLY, /* Controller/switch message */ + OFPT_SET_CONFIG, /* Controller/switch message */ - /* Asynchronous messages. */ - OFPT_PACKET_IN, /* Async message */ - OFPT_FLOW_REMOVED, /* Async message */ - OFPT_PORT_STATUS, /* Async message */ + /* Asynchronous messages. */ + OFPT_PACKET_IN, /* Async message */ + OFPT_FLOW_REMOVED, /* Async message */ + OFPT_PORT_STATUS, /* Async message */ - /* Controller command messages. */ - OFPT_PACKET_OUT, /* Controller/switch message */ - OFPT_FLOW_MOD, /* Controller/switch message */ - OFPT_PORT_MOD, /* Controller/switch message */ + /* Controller command messages. */ + OFPT_PACKET_OUT, /* Controller/switch message */ + OFPT_FLOW_MOD, /* Controller/switch message */ + OFPT_PORT_MOD, /* Controller/switch message */ - /* Statistics messages. */ - OFPT_STATS_REQUEST, /* Controller/switch message */ - OFPT_STATS_REPLY, /* Controller/switch message */ + /* Statistics messages. */ + OFPT_STATS_REQUEST, /* Controller/switch message */ + OFPT_STATS_REPLY, /* Controller/switch message */ - /* Barrier messages. */ - OFPT_BARRIER_REQUEST, /* Controller/switch message */ - OFPT_BARRIER_REPLY, /* Controller/switch message */ + /* Barrier messages. */ + OFPT_BARRIER_REQUEST, /* Controller/switch message */ + OFPT_BARRIER_REPLY, /* Controller/switch message */ - /* Queue Configuration messages. */ - OFPT_QUEUE_GET_CONFIG_REQUEST, /* Controller/switch message */ - OFPT_QUEUE_GET_CONFIG_REPLY /* Controller/switch message */ + /* Queue Configuration messages. */ + OFPT_QUEUE_GET_CONFIG_REQUEST, /* Controller/switch message */ + OFPT_QUEUE_GET_CONFIG_REPLY /* Controller/switch message */ }; /* Header on all OpenFlow packets. */ struct ofp_header { - uint8_t version; /* OFP_VERSION. */ - uint8_t type; /* One of the OFPT_ constants. */ - uint16_t length; /* Length including this ofp_header. */ - uint32_t xid; /* Transaction id associated with this packet. - Replies use the same id as was in the request - to facilitate pairing. */ + uint8_t version; /* OFP_VERSION. */ + uint8_t type; /* One of the OFPT_ constants. */ + uint16_t length; /* Length including this ofp_header. */ + uint32_t xid; /* Transaction id associated with this packet. + Replies use the same id as was in the request + to facilitate pairing. */ }; OFP_ASSERT(sizeof(struct ofp_header) == 8); /* OFPT_HELLO. This message has an empty body, but implementations must * ignore any data included in the body, to allow for future extensions. */ struct ofp_hello { - struct ofp_header header; + struct ofp_header header; }; -#define OFP_DEFAULT_MISS_SEND_LEN 128 +#define OFP_DEFAULT_MISS_SEND_LEN 128 enum ofp_config_flags { - /* Handling of IP fragments. */ - OFPC_FRAG_NORMAL = 0, /* No special handling for fragments. */ - OFPC_FRAG_DROP = 1, /* Drop fragments. */ - OFPC_FRAG_REASM = 2, /* Reassemble (only if OFPC_IP_REASM set). */ - OFPC_FRAG_MASK = 3 + /* Handling of IP fragments. */ + OFPC_FRAG_NORMAL = 0, /* No special handling for fragments. */ + OFPC_FRAG_DROP = 1, /* Drop fragments. */ + OFPC_FRAG_REASM = 2, /* Reassemble (only if OFPC_IP_REASM set). */ + OFPC_FRAG_MASK = 3 }; /* Switch configuration. */ struct ofp_switch_config { - struct ofp_header header; - uint16_t flags; /* OFPC_* flags. */ - uint16_t miss_send_len; /* Max bytes of new flow that datapath should + struct ofp_header header; + uint16_t flags; /* OFPC_* flags. */ + uint16_t miss_send_len; /* Max bytes of new flow that datapath should send to the controller. */ }; OFP_ASSERT(sizeof(struct ofp_switch_config) == 12); /* Capabilities supported by the datapath. */ enum ofp_capabilities { - OFPC_FLOW_STATS = 1 << 0, /* Flow statistics. */ - OFPC_TABLE_STATS = 1 << 1, /* Table statistics. */ - OFPC_PORT_STATS = 1 << 2, /* Port statistics. */ - OFPC_STP = 1 << 3, /* 802.1d spanning tree. */ - OFPC_RESERVED = 1 << 4, /* Reserved, must be zero. */ - OFPC_IP_REASM = 1 << 5, /* Can reassemble IP fragments. */ - OFPC_QUEUE_STATS = 1 << 6, /* Queue statistics. */ - OFPC_ARP_MATCH_IP = 1 << 7 /* Match IP addresses in ARP pkts. */ + OFPC_FLOW_STATS = 1 << 0, /* Flow statistics. */ + OFPC_TABLE_STATS = 1 << 1, /* Table statistics. */ + OFPC_PORT_STATS = 1 << 2, /* Port statistics. */ + OFPC_STP = 1 << 3, /* 802.1d spanning tree. */ + OFPC_RESERVED = 1 << 4, /* Reserved, must be zero. */ + OFPC_IP_REASM = 1 << 5, /* Can reassemble IP fragments. */ + OFPC_QUEUE_STATS = 1 << 6, /* Queue statistics. */ + OFPC_ARP_MATCH_IP = 1 << 7 /* Match IP addresses in ARP pkts. */ }; /* Flags to indicate behavior of the physical port. These flags are @@ -190,163 +189,163 @@ enum ofp_capabilities { * used in the ofp_port_mod message to configure the port's behavior. */ enum ofp_port_config { - OFPPC_PORT_DOWN = 1 << 0, /* Port is administratively down. */ + OFPPC_PORT_DOWN = 1 << 0, /* Port is administratively down. */ - OFPPC_NO_STP = 1 << 1, /* Disable 802.1D spanning tree on port. */ - OFPPC_NO_RECV = 1 << 2, /* Drop all packets except 802.1D spanning - tree packets. */ - OFPPC_NO_RECV_STP = 1 << 3, /* Drop received 802.1D STP packets. */ - OFPPC_NO_FLOOD = 1 << 4, /* Do not include this port when flooding. */ - OFPPC_NO_FWD = 1 << 5, /* Drop packets forwarded to port. */ - OFPPC_NO_PACKET_IN = 1 << 6 /* Do not send packet-in msgs for port. */ + OFPPC_NO_STP = 1 << 1, /* Disable 802.1D spanning tree on port. */ + OFPPC_NO_RECV = 1 << 2, /* Drop all packets except 802.1D spanning + tree packets. */ + OFPPC_NO_RECV_STP = 1 << 3, /* Drop received 802.1D STP packets. */ + OFPPC_NO_FLOOD = 1 << 4, /* Do not include this port when flooding. */ + OFPPC_NO_FWD = 1 << 5, /* Drop packets forwarded to port. */ + OFPPC_NO_PACKET_IN = 1 << 6 /* Do not send packet-in msgs for port. */ }; /* Current state of the physical port. These are not configurable from * the controller. */ enum ofp_port_state { - OFPPS_LINK_DOWN = 1 << 0, /* No physical link present. */ + OFPPS_LINK_DOWN = 1 << 0, /* No physical link present. */ - /* The OFPPS_STP_* bits have no effect on switch operation. The - * controller must adjust OFPPC_NO_RECV, OFPPC_NO_FWD, and - * OFPPC_NO_PACKET_IN appropriately to fully implement an 802.1D spanning - * tree. */ - OFPPS_STP_LISTEN = 0 << 8, /* Not learning or relaying frames. */ - OFPPS_STP_LEARN = 1 << 8, /* Learning but not relaying frames. */ - OFPPS_STP_FORWARD = 2 << 8, /* Learning and relaying frames. */ - OFPPS_STP_BLOCK = 3 << 8, /* Not part of spanning tree. */ - OFPPS_STP_MASK = 3 << 8 /* Bit mask for OFPPS_STP_* values. */ + /* The OFPPS_STP_* bits have no effect on switch operation. The + * controller must adjust OFPPC_NO_RECV, OFPPC_NO_FWD, and + * OFPPC_NO_PACKET_IN appropriately to fully implement an 802.1D spanning + * tree. */ + OFPPS_STP_LISTEN = 0 << 8, /* Not learning or relaying frames. */ + OFPPS_STP_LEARN = 1 << 8, /* Learning but not relaying frames. */ + OFPPS_STP_FORWARD = 2 << 8, /* Learning and relaying frames. */ + OFPPS_STP_BLOCK = 3 << 8, /* Not part of spanning tree. */ + OFPPS_STP_MASK = 3 << 8 /* Bit mask for OFPPS_STP_* values. */ }; /* Features of physical ports available in a datapath. */ enum ofp_port_features { - OFPPF_10MB_HD = 1 << 0, /* 10 Mb half-duplex rate support. */ - OFPPF_10MB_FD = 1 << 1, /* 10 Mb full-duplex rate support. */ - OFPPF_100MB_HD = 1 << 2, /* 100 Mb half-duplex rate support. */ - OFPPF_100MB_FD = 1 << 3, /* 100 Mb full-duplex rate support. */ - OFPPF_1GB_HD = 1 << 4, /* 1 Gb half-duplex rate support. */ - OFPPF_1GB_FD = 1 << 5, /* 1 Gb full-duplex rate support. */ - OFPPF_10GB_FD = 1 << 6, /* 10 Gb full-duplex rate support. */ - OFPPF_COPPER = 1 << 7, /* Copper medium. */ - OFPPF_FIBER = 1 << 8, /* Fiber medium. */ - OFPPF_AUTONEG = 1 << 9, /* Auto-negotiation. */ - OFPPF_PAUSE = 1 << 10, /* Pause. */ - OFPPF_PAUSE_ASYM = 1 << 11 /* Asymmetric pause. */ + OFPPF_10MB_HD = 1 << 0, /* 10 Mb half-duplex rate support. */ + OFPPF_10MB_FD = 1 << 1, /* 10 Mb full-duplex rate support. */ + OFPPF_100MB_HD = 1 << 2, /* 100 Mb half-duplex rate support. */ + OFPPF_100MB_FD = 1 << 3, /* 100 Mb full-duplex rate support. */ + OFPPF_1GB_HD = 1 << 4, /* 1 Gb half-duplex rate support. */ + OFPPF_1GB_FD = 1 << 5, /* 1 Gb full-duplex rate support. */ + OFPPF_10GB_FD = 1 << 6, /* 10 Gb full-duplex rate support. */ + OFPPF_COPPER = 1 << 7, /* Copper medium. */ + OFPPF_FIBER = 1 << 8, /* Fiber medium. */ + OFPPF_AUTONEG = 1 << 9, /* Auto-negotiation. */ + OFPPF_PAUSE = 1 << 10, /* Pause. */ + OFPPF_PAUSE_ASYM = 1 << 11 /* Asymmetric pause. */ }; /* Description of a physical port */ struct ofp_phy_port { - uint16_t port_no; - uint8_t hw_addr[OFP_ETH_ALEN]; - char name[OFP_MAX_PORT_NAME_LEN]; /* Null-terminated */ + uint16_t port_no; + uint8_t hw_addr[OFP_ETH_ALEN]; + char name[OFP_MAX_PORT_NAME_LEN]; /* Null-terminated */ - uint32_t config; /* Bitmap of OFPPC_* flags. */ - uint32_t state; /* Bitmap of OFPPS_* flags. */ + uint32_t config; /* Bitmap of OFPPC_* flags. */ + uint32_t state; /* Bitmap of OFPPS_* flags. */ - /* Bitmaps of OFPPF_* that describe features. All bits zeroed if - * unsupported or unavailable. */ - uint32_t curr; /* Current features. */ - uint32_t advertised; /* Features being advertised by the port. */ - uint32_t supported; /* Features supported by the port. */ - uint32_t peer; /* Features advertised by peer. */ + /* Bitmaps of OFPPF_* that describe features. All bits zeroed if + * unsupported or unavailable. */ + uint32_t curr; /* Current features. */ + uint32_t advertised; /* Features being advertised by the port. */ + uint32_t supported; /* Features supported by the port. */ + uint32_t peer; /* Features advertised by peer. */ }; OFP_ASSERT(sizeof(struct ofp_phy_port) == 48); /* Switch features. */ struct ofp_switch_features { - struct ofp_header header; - uint64_t datapath_id; /* Datapath unique ID. The lower 48-bits are for - a MAC address, while the upper 16-bits are - implementer-defined. */ + struct ofp_header header; + uint64_t datapath_id; /* Datapath unique ID. The lower 48-bits are for + a MAC address, while the upper 16-bits are + implementer-defined. */ - uint32_t n_buffers; /* Max packets buffered at once. */ + uint32_t n_buffers; /* Max packets buffered at once. */ - uint8_t n_tables; /* Number of tables supported by datapath. */ - uint8_t pad[3]; /* Align to 64-bits. */ + uint8_t n_tables; /* Number of tables supported by datapath. */ + uint8_t pad[3]; /* Align to 64-bits. */ - /* Features. */ - uint32_t capabilities; /* Bitmap of support "ofp_capabilities". */ - uint32_t actions; /* Bitmap of supported "ofp_action_type"s. */ + /* Features. */ + uint32_t capabilities; /* Bitmap of support "ofp_capabilities". */ + uint32_t actions; /* Bitmap of supported "ofp_action_type"s. */ - /* Port info.*/ - struct ofp_phy_port ports[0]; /* Port definitions. The number of ports - is inferred from the length field in - the header. */ + /* Port info.*/ + struct ofp_phy_port ports[0]; /* Port definitions. The number of ports + is inferred from the length field in + the header. */ }; OFP_ASSERT(sizeof(struct ofp_switch_features) == 32); /* What changed about the physical port */ enum ofp_port_reason { - OFPPR_ADD, /* The port was added. */ - OFPPR_DELETE, /* The port was removed. */ - OFPPR_MODIFY /* Some attribute of the port has changed. */ + OFPPR_ADD, /* The port was added. */ + OFPPR_DELETE, /* The port was removed. */ + OFPPR_MODIFY /* Some attribute of the port has changed. */ }; /* A physical port has changed in the datapath */ struct ofp_port_status { - struct ofp_header header; - uint8_t reason; /* One of OFPPR_*. */ - uint8_t pad[7]; /* Align to 64-bits. */ - struct ofp_phy_port desc; + struct ofp_header header; + uint8_t reason; /* One of OFPPR_*. */ + uint8_t pad[7]; /* Align to 64-bits. */ + struct ofp_phy_port desc; }; OFP_ASSERT(sizeof(struct ofp_port_status) == 64); /* Modify behavior of the physical port */ struct ofp_port_mod { - struct ofp_header header; - uint16_t port_no; - uint8_t hw_addr[OFP_ETH_ALEN]; /* The hardware address is not - configurable. This is used to - sanity-check the request, so it must - be the same as returned in an - ofp_phy_port struct. */ - - uint32_t config; /* Bitmap of OFPPC_* flags. */ - uint32_t mask; /* Bitmap of OFPPC_* flags to be changed. */ - - uint32_t advertise; /* Bitmap of "ofp_port_features"s. Zero all + struct ofp_header header; + uint16_t port_no; + uint8_t hw_addr[OFP_ETH_ALEN]; /* The hardware address is not + configurable. This is used to + sanity-check the request, so it must + be the same as returned in an + ofp_phy_port struct. */ + + uint32_t config; /* Bitmap of OFPPC_* flags. */ + uint32_t mask; /* Bitmap of OFPPC_* flags to be changed. */ + + uint32_t advertise; /* Bitmap of "ofp_port_features"s. Zero all bits to prevent any action taking place. */ - uint8_t pad[4]; /* Pad to 64-bits. */ + uint8_t pad[4]; /* Pad to 64-bits. */ }; OFP_ASSERT(sizeof(struct ofp_port_mod) == 32); /* Why is this packet being sent to the controller? */ enum ofp_packet_in_reason { - OFPR_NO_MATCH, /* No matching flow. */ - OFPR_ACTION /* Action explicitly output to controller. */ + OFPR_NO_MATCH, /* No matching flow. */ + OFPR_ACTION /* Action explicitly output to controller. */ }; /* Packet received on port (datapath -> controller). */ struct ofp_packet_in { - struct ofp_header header; - uint32_t buffer_id; /* ID assigned by datapath. */ - uint16_t total_len; /* Full length of frame. */ - uint16_t in_port; /* Port on which frame was received. */ - uint8_t reason; /* Reason packet is being sent (one of OFPR_*) */ - uint8_t pad; - uint8_t data[0]; /* Ethernet frame, halfway through 32-bit word, - so the IP header is 32-bit aligned. The - amount of data is inferred from the length - field in the header. Because of padding, - offsetof(struct ofp_packet_in, data) == - sizeof(struct ofp_packet_in) - 2. */ + struct ofp_header header; + uint32_t buffer_id; /* ID assigned by datapath. */ + uint16_t total_len; /* Full length of frame. */ + uint16_t in_port; /* Port on which frame was received. */ + uint8_t reason; /* Reason packet is being sent (one of OFPR_*) */ + uint8_t pad; + uint8_t data[0]; /* Ethernet frame, halfway through 32-bit word, + so the IP header is 32-bit aligned. The + amount of data is inferred from the length + field in the header. Because of padding, + offsetof(struct ofp_packet_in, data) == + sizeof(struct ofp_packet_in) - 2. */ }; OFP_ASSERT(sizeof(struct ofp_packet_in) == 20); enum ofp_action_type { - OFPAT_OUTPUT, /* Output to switch port. */ - OFPAT_SET_VLAN_VID, /* Set the 802.1q VLAN id. */ - OFPAT_SET_VLAN_PCP, /* Set the 802.1q priority. */ - OFPAT_STRIP_VLAN, /* Strip the 802.1q header. */ - OFPAT_SET_DL_SRC, /* Ethernet source address. */ - OFPAT_SET_DL_DST, /* Ethernet destination address. */ - OFPAT_SET_NW_SRC, /* IP source address. */ - OFPAT_SET_NW_DST, /* IP destination address. */ - OFPAT_SET_NW_TOS, /* IP ToS (DSCP field, 6 bits). */ - OFPAT_SET_TP_SRC, /* TCP/UDP source port. */ - OFPAT_SET_TP_DST, /* TCP/UDP destination port. */ - OFPAT_ENQUEUE, /* Output to queue. */ - OFPAT_VENDOR = 0xffff + OFPAT_OUTPUT, /* Output to switch port. */ + OFPAT_SET_VLAN_VID, /* Set the 802.1q VLAN id. */ + OFPAT_SET_VLAN_PCP, /* Set the 802.1q priority. */ + OFPAT_STRIP_VLAN, /* Strip the 802.1q header. */ + OFPAT_SET_DL_SRC, /* Ethernet source address. */ + OFPAT_SET_DL_DST, /* Ethernet destination address. */ + OFPAT_SET_NW_SRC, /* IP source address. */ + OFPAT_SET_NW_DST, /* IP destination address. */ + OFPAT_SET_NW_TOS, /* IP ToS (DSCP field, 6 bits). */ + OFPAT_SET_TP_SRC, /* TCP/UDP source port. */ + OFPAT_SET_TP_DST, /* TCP/UDP destination port. */ + OFPAT_ENQUEUE, /* Output to queue. */ + OFPAT_VENDOR = 0xffff }; /* Action structure for OFPAT_OUTPUT, which sends packets out 'port'. @@ -354,77 +353,77 @@ enum ofp_action_type { * number of bytes to send. A 'max_len' of zero means no bytes of the * packet should be sent.*/ struct ofp_action_output { - uint16_t type; /* OFPAT_OUTPUT. */ - uint16_t len; /* Length is 8. */ - uint16_t port; /* Output port. */ - uint16_t max_len; /* Max length to send to controller. */ + uint16_t type; /* OFPAT_OUTPUT. */ + uint16_t len; /* Length is 8. */ + uint16_t port; /* Output port. */ + uint16_t max_len; /* Max length to send to controller. */ }; OFP_ASSERT(sizeof(struct ofp_action_output) == 8); /* The VLAN id is 12 bits, so we can use the entire 16 bits to indicate * special conditions. All ones is used to match that no VLAN id was * set. */ -#define OFP_VLAN_NONE 0xffff +#define OFP_VLAN_NONE 0xffff /* Action structure for OFPAT_SET_VLAN_VID. */ struct ofp_action_vlan_vid { - uint16_t type; /* OFPAT_SET_VLAN_VID. */ - uint16_t len; /* Length is 8. */ - uint16_t vlan_vid; /* VLAN id. */ - uint8_t pad[2]; + uint16_t type; /* OFPAT_SET_VLAN_VID. */ + uint16_t len; /* Length is 8. */ + uint16_t vlan_vid; /* VLAN id. */ + uint8_t pad[2]; }; OFP_ASSERT(sizeof(struct ofp_action_vlan_vid) == 8); /* Action structure for OFPAT_SET_VLAN_PCP. */ struct ofp_action_vlan_pcp { - uint16_t type; /* OFPAT_SET_VLAN_PCP. */ - uint16_t len; /* Length is 8. */ - uint8_t vlan_pcp; /* VLAN priority. */ - uint8_t pad[3]; + uint16_t type; /* OFPAT_SET_VLAN_PCP. */ + uint16_t len; /* Length is 8. */ + uint8_t vlan_pcp; /* VLAN priority. */ + uint8_t pad[3]; }; OFP_ASSERT(sizeof(struct ofp_action_vlan_pcp) == 8); /* Action structure for OFPAT_SET_DL_SRC/DST. */ struct ofp_action_dl_addr { - uint16_t type; /* OFPAT_SET_DL_SRC/DST. */ - uint16_t len; /* Length is 16. */ - uint8_t dl_addr[OFP_ETH_ALEN]; /* Ethernet address. */ - uint8_t pad[6]; + uint16_t type; /* OFPAT_SET_DL_SRC/DST. */ + uint16_t len; /* Length is 16. */ + uint8_t dl_addr[OFP_ETH_ALEN]; /* Ethernet address. */ + uint8_t pad[6]; }; OFP_ASSERT(sizeof(struct ofp_action_dl_addr) == 16); /* Action structure for OFPAT_SET_NW_SRC/DST. */ struct ofp_action_nw_addr { - uint16_t type; /* OFPAT_SET_TW_SRC/DST. */ - uint16_t len; /* Length is 8. */ - uint32_t nw_addr; /* IP address. */ + uint16_t type; /* OFPAT_SET_TW_SRC/DST. */ + uint16_t len; /* Length is 8. */ + uint32_t nw_addr; /* IP address. */ }; OFP_ASSERT(sizeof(struct ofp_action_nw_addr) == 8); /* Action structure for OFPAT_SET_TP_SRC/DST. */ struct ofp_action_tp_port { - uint16_t type; /* OFPAT_SET_TP_SRC/DST. */ - uint16_t len; /* Length is 8. */ - uint16_t tp_port; /* TCP/UDP port. */ - uint8_t pad[2]; + uint16_t type; /* OFPAT_SET_TP_SRC/DST. */ + uint16_t len; /* Length is 8. */ + uint16_t tp_port; /* TCP/UDP port. */ + uint8_t pad[2]; }; OFP_ASSERT(sizeof(struct ofp_action_tp_port) == 8); /* Action structure for OFPAT_SET_NW_TOS. */ struct ofp_action_nw_tos { - uint16_t type; /* OFPAT_SET_TW_SRC/DST. */ - uint16_t len; /* Length is 8. */ - uint8_t nw_tos; /* IP ToS (DSCP field, 6 bits). */ - uint8_t pad[3]; + uint16_t type; /* OFPAT_SET_TW_SRC/DST. */ + uint16_t len; /* Length is 8. */ + uint8_t nw_tos; /* IP ToS (DSCP field, 6 bits). */ + uint8_t pad[3]; }; OFP_ASSERT(sizeof(struct ofp_action_nw_tos) == 8); /* Action header for OFPAT_VENDOR. The rest of the body is vendor-defined. */ struct ofp_action_vendor_header { - uint16_t type; /* OFPAT_VENDOR. */ - uint16_t len; /* Length is a multiple of 8. */ - uint32_t vendor; /* Vendor ID, which takes the same form - as in "struct ofp_vendor_header". */ + uint16_t type; /* OFPAT_VENDOR. */ + uint16_t len; /* Length is a multiple of 8. */ + uint32_t vendor; /* Vendor ID, which takes the same form + as in "struct ofp_vendor_header". */ }; OFP_ASSERT(sizeof(struct ofp_action_vendor_header) == 8); @@ -432,67 +431,67 @@ OFP_ASSERT(sizeof(struct ofp_action_vendor_header) == 8); * header and any padding used to make the action 64-bit aligned. * NB: The length of an action *must* always be a multiple of eight. */ struct ofp_action_header { - uint16_t type; /* One of OFPAT_*. */ - uint16_t len; /* Length of action, including this - header. This is the length of action, - including any padding to make it - 64-bit aligned. */ - uint8_t pad[4]; + uint16_t type; /* One of OFPAT_*. */ + uint16_t len; /* Length of action, including this + header. This is the length of action, + including any padding to make it + 64-bit aligned. */ + uint8_t pad[4]; }; OFP_ASSERT(sizeof(struct ofp_action_header) == 8); /* Send packet (controller -> datapath). */ struct ofp_packet_out { - struct ofp_header header; - uint32_t buffer_id; /* ID assigned by datapath (-1 if none). */ - uint16_t in_port; /* Packet's input port (OFPP_NONE if none). */ - uint16_t actions_len; /* Size of action array in bytes. */ - struct ofp_action_header actions[0]; /* Actions. */ - /* uint8_t data[0]; */ /* Packet data. The length is inferred - from the length field in the header. - (Only meaningful if buffer_id == -1.) */ + struct ofp_header header; + uint32_t buffer_id; /* ID assigned by datapath (-1 if none). */ + uint16_t in_port; /* Packet's input port (OFPP_NONE if none). */ + uint16_t actions_len; /* Size of action array in bytes. */ + struct ofp_action_header actions[0]; /* Actions. */ + /* uint8_t data[0]; */ /* Packet data. The length is inferred + from the length field in the header. + (Only meaningful if buffer_id == -1.) */ }; OFP_ASSERT(sizeof(struct ofp_packet_out) == 16); enum ofp_flow_mod_command { - OFPFC_ADD, /* New flow. */ - OFPFC_MODIFY, /* Modify all matching flows. */ - OFPFC_MODIFY_STRICT, /* Modify entry strictly matching wildcards */ - OFPFC_DELETE, /* Delete all matching flows. */ - OFPFC_DELETE_STRICT /* Strictly match wildcards and priority. */ + OFPFC_ADD, /* New flow. */ + OFPFC_MODIFY, /* Modify all matching flows. */ + OFPFC_MODIFY_STRICT, /* Modify entry strictly matching wildcards */ + OFPFC_DELETE, /* Delete all matching flows. */ + OFPFC_DELETE_STRICT /* Strictly match wildcards and priority. */ }; /* Flow wildcards. */ enum ofp_flow_wildcards { - OFPFW_IN_PORT = 1 << 0, /* Switch input port. */ - OFPFW_DL_VLAN = 1 << 1, /* VLAN id. */ - OFPFW_DL_SRC = 1 << 2, /* Ethernet source address. */ - OFPFW_DL_DST = 1 << 3, /* Ethernet destination address. */ - OFPFW_DL_TYPE = 1 << 4, /* Ethernet frame type. */ - OFPFW_NW_PROTO = 1 << 5, /* IP protocol. */ - OFPFW_TP_SRC = 1 << 6, /* TCP/UDP source port. */ - OFPFW_TP_DST = 1 << 7, /* TCP/UDP destination port. */ - - /* IP source address wildcard bit count. 0 is exact match, 1 ignores the - * LSB, 2 ignores the 2 least-significant bits, ..., 32 and higher wildcard - * the entire field. This is the *opposite* of the usual convention where - * e.g. /24 indicates that 8 bits (not 24 bits) are wildcarded. */ - OFPFW_NW_SRC_SHIFT = 8, - OFPFW_NW_SRC_BITS = 6, - OFPFW_NW_SRC_MASK = ((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT, - OFPFW_NW_SRC_ALL = 32 << OFPFW_NW_SRC_SHIFT, - - /* IP destination address wildcard bit count. Same format as source. */ - OFPFW_NW_DST_SHIFT = 14, - OFPFW_NW_DST_BITS = 6, - OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT, - OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT, - - OFPFW_DL_VLAN_PCP = 1 << 20, /* VLAN priority. */ - OFPFW_NW_TOS = 1 << 21, /* IP ToS (DSCP field, 6 bits). */ - - /* Wildcard all fields. */ - OFPFW_ALL = ((1 << 22) - 1) + OFPFW_IN_PORT = 1 << 0, /* Switch input port. */ + OFPFW_DL_VLAN = 1 << 1, /* VLAN id. */ + OFPFW_DL_SRC = 1 << 2, /* Ethernet source address. */ + OFPFW_DL_DST = 1 << 3, /* Ethernet destination address. */ + OFPFW_DL_TYPE = 1 << 4, /* Ethernet frame type. */ + OFPFW_NW_PROTO = 1 << 5, /* IP protocol. */ + OFPFW_TP_SRC = 1 << 6, /* TCP/UDP source port. */ + OFPFW_TP_DST = 1 << 7, /* TCP/UDP destination port. */ + + /* IP source address wildcard bit count. 0 is exact match, 1 ignores the + * LSB, 2 ignores the 2 least-significant bits, ..., 32 and higher wildcard + * the entire field. This is the *opposite* of the usual convention where + * e.g. /24 indicates that 8 bits (not 24 bits) are wildcarded. */ + OFPFW_NW_SRC_SHIFT = 8, + OFPFW_NW_SRC_BITS = 6, + OFPFW_NW_SRC_MASK = ((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT, + OFPFW_NW_SRC_ALL = 32 << OFPFW_NW_SRC_SHIFT, + + /* IP destination address wildcard bit count. Same format as source. */ + OFPFW_NW_DST_SHIFT = 14, + OFPFW_NW_DST_BITS = 6, + OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT, + OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT, + + OFPFW_DL_VLAN_PCP = 1 << 20, /* VLAN priority. */ + OFPFW_NW_TOS = 1 << 21, /* IP ToS (DSCP field, 6 bits). */ + + /* Wildcard all fields. */ + OFPFW_ALL = ((1 << 22) - 1) }; /* The wildcards for ICMP type and code fields use the transport source @@ -504,36 +503,36 @@ enum ofp_flow_wildcards { * following MAC addresses are used as a frame length. Otherwise, the * two bytes are used as the Ethernet type. */ -#define OFP_DL_TYPE_ETH2_CUTOFF 0x0600 +#define OFP_DL_TYPE_ETH2_CUTOFF 0x0600 /* Value of dl_type to indicate that the frame does not include an * Ethernet type. */ -#define OFP_DL_TYPE_NOT_ETH_TYPE 0x05ff +#define OFP_DL_TYPE_NOT_ETH_TYPE 0x05ff /* The VLAN id is 12-bits, so we can use the entire 16 bits to indicate * special conditions. All ones indicates that no VLAN id was set. */ -#define OFP_VLAN_NONE 0xffff +#define OFP_VLAN_NONE 0xffff /* Fields to match against flows */ struct ofp_match { - uint32_t wildcards; /* Wildcard fields. */ - uint16_t in_port; /* Input switch port. */ - uint8_t dl_src[OFP_ETH_ALEN]; /* Ethernet source address. */ - uint8_t dl_dst[OFP_ETH_ALEN]; /* Ethernet destination address. */ - uint16_t dl_vlan; /* Input VLAN id. */ - uint8_t dl_vlan_pcp; /* Input VLAN priority. */ - uint8_t pad1[1]; /* Align to 64-bits */ - uint16_t dl_type; /* Ethernet frame type. */ - uint8_t nw_tos; /* IP ToS (actually DSCP field, 6 bits). */ - uint8_t nw_proto; /* IP protocol or lower 8 bits of - * ARP opcode. */ - uint8_t pad2[2]; /* Align to 64-bits */ - uint32_t nw_src; /* IP source address. */ - uint32_t nw_dst; /* IP destination address. */ - uint16_t tp_src; /* TCP/UDP source port. */ - uint16_t tp_dst; /* TCP/UDP destination port. */ + uint32_t wildcards; /* Wildcard fields. */ + uint16_t in_port; /* Input switch port. */ + uint8_t dl_src[OFP_ETH_ALEN]; /* Ethernet source address. */ + uint8_t dl_dst[OFP_ETH_ALEN]; /* Ethernet destination address. */ + uint16_t dl_vlan; /* Input VLAN id. */ + uint8_t dl_vlan_pcp; /* Input VLAN priority. */ + uint8_t pad1[1]; /* Align to 64-bits */ + uint16_t dl_type; /* Ethernet frame type. */ + uint8_t nw_tos; /* IP ToS (actually DSCP field, 6 bits). */ + uint8_t nw_proto; /* IP protocol or lower 8 bits of + * ARP opcode. */ + uint8_t pad2[2]; /* Align to 64-bits */ + uint32_t nw_src; /* IP source address. */ + uint32_t nw_dst; /* IP destination address. */ + uint16_t tp_src; /* TCP/UDP source port. */ + uint16_t tp_dst; /* TCP/UDP destination port. */ }; OFP_ASSERT(sizeof(struct ofp_match) == 40); @@ -550,60 +549,60 @@ OFP_ASSERT(sizeof(struct ofp_match) == 40); #define OFP_DEFAULT_PRIORITY 0x8000 enum ofp_flow_mod_flags { - OFPFF_SEND_FLOW_REM = 1 << 0, /* Send flow removed message when flow - * expires or is deleted. */ - OFPFF_CHECK_OVERLAP = 1 << 1, /* Check for overlapping entries first. */ - OFPFF_EMERG = 1 << 2 /* Remark this is for emergency. */ + OFPFF_SEND_FLOW_REM = 1 << 0, /* Send flow removed message when flow + * expires or is deleted. */ + OFPFF_CHECK_OVERLAP = 1 << 1, /* Check for overlapping entries first. */ + OFPFF_EMERG = 1 << 2 /* Remark this is for emergency. */ }; /* Flow setup and teardown (controller -> datapath). */ struct ofp_flow_mod { - struct ofp_header header; - struct ofp_match match; /* Fields to match */ - uint64_t cookie; /* Opaque controller-issued identifier. */ - - /* Flow actions. */ - uint16_t command; /* One of OFPFC_*. */ - uint16_t idle_timeout; /* Idle time before discarding (seconds). */ - uint16_t hard_timeout; /* Max time before discarding (seconds). */ - uint16_t priority; /* Priority level of flow entry. */ - uint32_t buffer_id; /* Buffered packet to apply to (or -1). - Not meaningful for OFPFC_DELETE*. */ - uint16_t out_port; /* For OFPFC_DELETE* commands, require - matching entries to include this as an - output port. A value of OFPP_NONE - indicates no restriction. */ - uint16_t flags; /* One of OFPFF_*. */ - struct ofp_action_header actions[0]; /* The action length is inferred - from the length field in the - header. */ + struct ofp_header header; + struct ofp_match match; /* Fields to match */ + uint64_t cookie; /* Opaque controller-issued identifier. */ + + /* Flow actions. */ + uint16_t command; /* One of OFPFC_*. */ + uint16_t idle_timeout; /* Idle time before discarding (seconds). */ + uint16_t hard_timeout; /* Max time before discarding (seconds). */ + uint16_t priority; /* Priority level of flow entry. */ + uint32_t buffer_id; /* Buffered packet to apply to (or -1). + Not meaningful for OFPFC_DELETE*. */ + uint16_t out_port; /* For OFPFC_DELETE* commands, require + matching entries to include this as an + output port. A value of OFPP_NONE + indicates no restriction. */ + uint16_t flags; /* One of OFPFF_*. */ + struct ofp_action_header actions[0]; /* The action length is inferred + from the length field in the + header. */ }; OFP_ASSERT(sizeof(struct ofp_flow_mod) == 72); /* Why was this flow removed? */ enum ofp_flow_removed_reason { - OFPRR_IDLE_TIMEOUT, /* Flow idle time exceeded idle_timeout. */ - OFPRR_HARD_TIMEOUT, /* Time exceeded hard_timeout. */ - OFPRR_DELETE /* Evicted by a DELETE flow mod. */ + OFPRR_IDLE_TIMEOUT, /* Flow idle time exceeded idle_timeout. */ + OFPRR_HARD_TIMEOUT, /* Time exceeded hard_timeout. */ + OFPRR_DELETE /* Evicted by a DELETE flow mod. */ }; /* Flow removed (datapath -> controller). */ struct ofp_flow_removed { - struct ofp_header header; - struct ofp_match match; /* Description of fields. */ - uint64_t cookie; /* Opaque controller-issued identifier. */ - - uint16_t priority; /* Priority level of flow entry. */ - uint8_t reason; /* One of OFPRR_*. */ - uint8_t pad[1]; /* Align to 32-bits. */ - - uint32_t duration_sec; /* Time flow was alive in seconds. */ - uint32_t duration_nsec; /* Time flow was alive in nanoseconds beyond - duration_sec. */ - uint16_t idle_timeout; /* Idle timeout from original flow mod. */ - uint8_t pad2[2]; /* Align to 64-bits. */ - uint64_t packet_count; - uint64_t byte_count; + struct ofp_header header; + struct ofp_match match; /* Description of fields. */ + uint64_t cookie; /* Opaque controller-issued identifier. */ + + uint16_t priority; /* Priority level of flow entry. */ + uint8_t reason; /* One of OFPRR_*. */ + uint8_t pad[1]; /* Align to 32-bits. */ + + uint32_t duration_sec; /* Time flow was alive in seconds. */ + uint32_t duration_nsec; /* Time flow was alive in nanoseconds beyond + duration_sec. */ + uint16_t idle_timeout; /* Idle timeout from original flow mod. */ + uint8_t pad2[2]; /* Align to 64-bits. */ + uint64_t packet_count; + uint64_t byte_count; }; OFP_ASSERT(sizeof(struct ofp_flow_removed) == 88); @@ -611,359 +610,359 @@ OFP_ASSERT(sizeof(struct ofp_flow_removed) == 88); * will not change in future versions of the protocol (although new values may * be added). */ enum ofp_error_type { - OFPET_HELLO_FAILED, /* Hello protocol failed. */ - OFPET_BAD_REQUEST, /* Request was not understood. */ - OFPET_BAD_ACTION, /* Error in action description. */ - OFPET_FLOW_MOD_FAILED, /* Problem modifying flow entry. */ - OFPET_PORT_MOD_FAILED, /* Port mod request failed. */ - OFPET_QUEUE_OP_FAILED /* Queue operation failed. */ + OFPET_HELLO_FAILED, /* Hello protocol failed. */ + OFPET_BAD_REQUEST, /* Request was not understood. */ + OFPET_BAD_ACTION, /* Error in action description. */ + OFPET_FLOW_MOD_FAILED, /* Problem modifying flow entry. */ + OFPET_PORT_MOD_FAILED, /* Port mod request failed. */ + OFPET_QUEUE_OP_FAILED /* Queue operation failed. */ }; /* ofp_error_msg 'code' values for OFPET_HELLO_FAILED. 'data' contains an * ASCII text string that may give failure details. */ enum ofp_hello_failed_code { - OFPHFC_INCOMPATIBLE, /* No compatible version. */ - OFPHFC_EPERM /* Permissions error. */ + OFPHFC_INCOMPATIBLE, /* No compatible version. */ + OFPHFC_EPERM /* Permissions error. */ }; /* ofp_error_msg 'code' values for OFPET_BAD_REQUEST. 'data' contains at least * the first 64 bytes of the failed request. */ enum ofp_bad_request_code { - OFPBRC_BAD_VERSION, /* ofp_header.version not supported. */ - OFPBRC_BAD_TYPE, /* ofp_header.type not supported. */ - OFPBRC_BAD_STAT, /* ofp_stats_request.type not supported. */ - OFPBRC_BAD_VENDOR, /* Vendor not supported (in ofp_vendor_header - * or ofp_stats_request or ofp_stats_reply). */ - OFPBRC_BAD_SUBTYPE, /* Vendor subtype not supported. */ - OFPBRC_EPERM, /* Permissions error. */ - OFPBRC_BAD_LEN, /* Wrong request length for type. */ - OFPBRC_BUFFER_EMPTY, /* Specified buffer has already been used. */ - OFPBRC_BUFFER_UNKNOWN /* Specified buffer does not exist. */ + OFPBRC_BAD_VERSION, /* ofp_header.version not supported. */ + OFPBRC_BAD_TYPE, /* ofp_header.type not supported. */ + OFPBRC_BAD_STAT, /* ofp_stats_request.type not supported. */ + OFPBRC_BAD_VENDOR, /* Vendor not supported (in ofp_vendor_header + * or ofp_stats_request or ofp_stats_reply). */ + OFPBRC_BAD_SUBTYPE, /* Vendor subtype not supported. */ + OFPBRC_EPERM, /* Permissions error. */ + OFPBRC_BAD_LEN, /* Wrong request length for type. */ + OFPBRC_BUFFER_EMPTY, /* Specified buffer has already been used. */ + OFPBRC_BUFFER_UNKNOWN /* Specified buffer does not exist. */ }; /* ofp_error_msg 'code' values for OFPET_BAD_ACTION. 'data' contains at least * the first 64 bytes of the failed request. */ enum ofp_bad_action_code { - OFPBAC_BAD_TYPE, /* Unknown action type. */ - OFPBAC_BAD_LEN, /* Length problem in actions. */ - OFPBAC_BAD_VENDOR, /* Unknown vendor id specified. */ - OFPBAC_BAD_VENDOR_TYPE, /* Unknown action type for vendor id. */ - OFPBAC_BAD_OUT_PORT, /* Problem validating output action. */ - OFPBAC_BAD_ARGUMENT, /* Bad action argument. */ - OFPBAC_EPERM, /* Permissions error. */ - OFPBAC_TOO_MANY, /* Can't handle this many actions. */ - OFPBAC_BAD_QUEUE /* Problem validating output queue. */ + OFPBAC_BAD_TYPE, /* Unknown action type. */ + OFPBAC_BAD_LEN, /* Length problem in actions. */ + OFPBAC_BAD_VENDOR, /* Unknown vendor id specified. */ + OFPBAC_BAD_VENDOR_TYPE, /* Unknown action type for vendor id. */ + OFPBAC_BAD_OUT_PORT, /* Problem validating output action. */ + OFPBAC_BAD_ARGUMENT, /* Bad action argument. */ + OFPBAC_EPERM, /* Permissions error. */ + OFPBAC_TOO_MANY, /* Can't handle this many actions. */ + OFPBAC_BAD_QUEUE /* Problem validating output queue. */ }; /* ofp_error_msg 'code' values for OFPET_FLOW_MOD_FAILED. 'data' contains * at least the first 64 bytes of the failed request. */ enum ofp_flow_mod_failed_code { - OFPFMFC_ALL_TABLES_FULL, /* Flow not added because of full tables. */ - OFPFMFC_OVERLAP, /* Attempted to add overlapping flow with - * CHECK_OVERLAP flag set. */ - OFPFMFC_EPERM, /* Permissions error. */ - OFPFMFC_BAD_EMERG_TIMEOUT, /* Flow not added because of non-zero idle/hard - * timeout. */ - OFPFMFC_BAD_COMMAND, /* Unknown command. */ - OFPFMFC_UNSUPPORTED /* Unsupported action list - cannot process in - * the order specified. */ + OFPFMFC_ALL_TABLES_FULL, /* Flow not added because of full tables. */ + OFPFMFC_OVERLAP, /* Attempted to add overlapping flow with + * CHECK_OVERLAP flag set. */ + OFPFMFC_EPERM, /* Permissions error. */ + OFPFMFC_BAD_EMERG_TIMEOUT, /* Flow not added because of non-zero idle/hard + * timeout. */ + OFPFMFC_BAD_COMMAND, /* Unknown command. */ + OFPFMFC_UNSUPPORTED /* Unsupported action list - cannot process in + * the order specified. */ }; /* ofp_error_msg 'code' values for OFPET_PORT_MOD_FAILED. 'data' contains * at least the first 64 bytes of the failed request. */ enum ofp_port_mod_failed_code { - OFPPMFC_BAD_PORT, /* Specified port does not exist. */ - OFPPMFC_BAD_HW_ADDR, /* Specified hardware address is wrong. */ + OFPPMFC_BAD_PORT, /* Specified port does not exist. */ + OFPPMFC_BAD_HW_ADDR, /* Specified hardware address is wrong. */ }; /* ofp_error msg 'code' values for OFPET_QUEUE_OP_FAILED. 'data' contains * at least the first 64 bytes of the failed request */ enum ofp_queue_op_failed_code { - OFPQOFC_BAD_PORT, /* Invalid port (or port does not exist). */ - OFPQOFC_BAD_QUEUE, /* Queue does not exist. */ - OFPQOFC_EPERM /* Permissions error. */ + OFPQOFC_BAD_PORT, /* Invalid port (or port does not exist). */ + OFPQOFC_BAD_QUEUE, /* Queue does not exist. */ + OFPQOFC_EPERM /* Permissions error. */ }; /* OFPT_ERROR: Error message (datapath -> controller). */ struct ofp_error_msg { - struct ofp_header header; + struct ofp_header header; - uint16_t type; - uint16_t code; - uint8_t data[0]; /* Variable-length data. Interpreted based - on the type and code. */ + uint16_t type; + uint16_t code; + uint8_t data[0]; /* Variable-length data. Interpreted based + on the type and code. */ }; OFP_ASSERT(sizeof(struct ofp_error_msg) == 12); enum ofp_stats_types { - /* Description of this OpenFlow switch. - * The request body is empty. - * The reply body is struct ofp_desc_stats. */ - OFPST_DESC, - - /* Individual flow statistics. - * The request body is struct ofp_flow_stats_request. - * The reply body is an array of struct ofp_flow_stats. */ - OFPST_FLOW, - - /* Aggregate flow statistics. - * The request body is struct ofp_aggregate_stats_request. - * The reply body is struct ofp_aggregate_stats_reply. */ - OFPST_AGGREGATE, - - /* Flow table statistics. - * The request body is empty. - * The reply body is an array of struct ofp_table_stats. */ - OFPST_TABLE, - - /* Physical port statistics. - * The request body is struct ofp_port_stats_request. - * The reply body is an array of struct ofp_port_stats. */ - OFPST_PORT, - - /* Queue statistics for a port - * The request body defines the port - * The reply body is an array of struct ofp_queue_stats */ - OFPST_QUEUE, - - /* Vendor extension. - * The request and reply bodies begin with a 32-bit vendor ID, which takes - * the same form as in "struct ofp_vendor_header". The request and reply - * bodies are otherwise vendor-defined. */ - OFPST_VENDOR = 0xffff + /* Description of this OpenFlow switch. + * The request body is empty. + * The reply body is struct ofp_desc_stats. */ + OFPST_DESC, + + /* Individual flow statistics. + * The request body is struct ofp_flow_stats_request. + * The reply body is an array of struct ofp_flow_stats. */ + OFPST_FLOW, + + /* Aggregate flow statistics. + * The request body is struct ofp_aggregate_stats_request. + * The reply body is struct ofp_aggregate_stats_reply. */ + OFPST_AGGREGATE, + + /* Flow table statistics. + * The request body is empty. + * The reply body is an array of struct ofp_table_stats. */ + OFPST_TABLE, + + /* Physical port statistics. + * The request body is struct ofp_port_stats_request. + * The reply body is an array of struct ofp_port_stats. */ + OFPST_PORT, + + /* Queue statistics for a port + * The request body defines the port + * The reply body is an array of struct ofp_queue_stats */ + OFPST_QUEUE, + + /* Vendor extension. + * The request and reply bodies begin with a 32-bit vendor ID, which takes + * the same form as in "struct ofp_vendor_header". The request and reply + * bodies are otherwise vendor-defined. */ + OFPST_VENDOR = 0xffff }; struct ofp_stats_request { - struct ofp_header header; - uint16_t type; /* One of the OFPST_* constants. */ - uint16_t flags; /* OFPSF_REQ_* flags (none yet defined). */ - uint8_t body[0]; /* Body of the request. */ + struct ofp_header header; + uint16_t type; /* One of the OFPST_* constants. */ + uint16_t flags; /* OFPSF_REQ_* flags (none yet defined). */ + uint8_t body[0]; /* Body of the request. */ }; OFP_ASSERT(sizeof(struct ofp_stats_request) == 12); enum ofp_stats_reply_flags { - OFPSF_REPLY_MORE = 1 << 0 /* More replies to follow. */ + OFPSF_REPLY_MORE = 1 << 0 /* More replies to follow. */ }; struct ofp_stats_reply { - struct ofp_header header; - uint16_t type; /* One of the OFPST_* constants. */ - uint16_t flags; /* OFPSF_REPLY_* flags. */ - uint8_t body[0]; /* Body of the reply. */ + struct ofp_header header; + uint16_t type; /* One of the OFPST_* constants. */ + uint16_t flags; /* OFPSF_REPLY_* flags. */ + uint8_t body[0]; /* Body of the reply. */ }; OFP_ASSERT(sizeof(struct ofp_stats_reply) == 12); -#define DESC_STR_LEN 256 +#define DESC_STR_LEN 256 #define SERIAL_NUM_LEN 32 /* Body of reply to OFPST_DESC request. Each entry is a NULL-terminated * ASCII string. */ struct ofp_desc_stats { - char mfr_desc[DESC_STR_LEN]; /* Manufacturer description. */ - char hw_desc[DESC_STR_LEN]; /* Hardware description. */ - char sw_desc[DESC_STR_LEN]; /* Software description. */ - char serial_num[SERIAL_NUM_LEN]; /* Serial number. */ - char dp_desc[DESC_STR_LEN]; /* Human readable description of datapath. */ + char mfr_desc[DESC_STR_LEN]; /* Manufacturer description. */ + char hw_desc[DESC_STR_LEN]; /* Hardware description. */ + char sw_desc[DESC_STR_LEN]; /* Software description. */ + char serial_num[SERIAL_NUM_LEN]; /* Serial number. */ + char dp_desc[DESC_STR_LEN]; /* Human readable description of datapath. */ }; OFP_ASSERT(sizeof(struct ofp_desc_stats) == 1056); /* Body for ofp_stats_request of type OFPST_FLOW. */ struct ofp_flow_stats_request { - struct ofp_match match; /* Fields to match. */ - uint8_t table_id; /* ID of table to read (from ofp_table_stats), - 0xff for all tables or 0xfe for emergency. */ - uint8_t pad; /* Align to 32 bits. */ - uint16_t out_port; /* Require matching entries to include this - as an output port. A value of OFPP_NONE - indicates no restriction. */ + struct ofp_match match; /* Fields to match. */ + uint8_t table_id; /* ID of table to read (from ofp_table_stats), + 0xff for all tables or 0xfe for emergency. */ + uint8_t pad; /* Align to 32 bits. */ + uint16_t out_port; /* Require matching entries to include this + as an output port. A value of OFPP_NONE + indicates no restriction. */ }; OFP_ASSERT(sizeof(struct ofp_flow_stats_request) == 44); /* Body of reply to OFPST_FLOW request. */ struct ofp_flow_stats { - uint16_t length; /* Length of this entry. */ - uint8_t table_id; /* ID of table flow came from. */ - uint8_t pad; - struct ofp_match match; /* Description of fields. */ - uint32_t duration_sec; /* Time flow has been alive in seconds. */ - uint32_t duration_nsec; /* Time flow has been alive in nanoseconds beyond - duration_sec. */ - uint16_t priority; /* Priority of the entry. Only meaningful - when this is not an exact-match entry. */ - uint16_t idle_timeout; /* Number of seconds idle before expiration. */ - uint16_t hard_timeout; /* Number of seconds before expiration. */ - uint8_t pad2[6]; /* Align to 64-bits. */ - uint64_t cookie; /* Opaque controller-issued identifier. */ - uint64_t packet_count; /* Number of packets in flow. */ - uint64_t byte_count; /* Number of bytes in flow. */ - struct ofp_action_header actions[0]; /* Actions. */ + uint16_t length; /* Length of this entry. */ + uint8_t table_id; /* ID of table flow came from. */ + uint8_t pad; + struct ofp_match match; /* Description of fields. */ + uint32_t duration_sec; /* Time flow has been alive in seconds. */ + uint32_t duration_nsec; /* Time flow has been alive in nanoseconds beyond + duration_sec. */ + uint16_t priority; /* Priority of the entry. Only meaningful + when this is not an exact-match entry. */ + uint16_t idle_timeout; /* Number of seconds idle before expiration. */ + uint16_t hard_timeout; /* Number of seconds before expiration. */ + uint8_t pad2[6]; /* Align to 64-bits. */ + uint64_t cookie; /* Opaque controller-issued identifier. */ + uint64_t packet_count; /* Number of packets in flow. */ + uint64_t byte_count; /* Number of bytes in flow. */ + struct ofp_action_header actions[0]; /* Actions. */ }; OFP_ASSERT(sizeof(struct ofp_flow_stats) == 88); /* Body for ofp_stats_request of type OFPST_AGGREGATE. */ struct ofp_aggregate_stats_request { - struct ofp_match match; /* Fields to match. */ - uint8_t table_id; /* ID of table to read (from ofp_table_stats) - 0xff for all tables or 0xfe for emergency. */ - uint8_t pad; /* Align to 32 bits. */ - uint16_t out_port; /* Require matching entries to include this - as an output port. A value of OFPP_NONE - indicates no restriction. */ + struct ofp_match match; /* Fields to match. */ + uint8_t table_id; /* ID of table to read (from ofp_table_stats) + 0xff for all tables or 0xfe for emergency. */ + uint8_t pad; /* Align to 32 bits. */ + uint16_t out_port; /* Require matching entries to include this + as an output port. A value of OFPP_NONE + indicates no restriction. */ }; OFP_ASSERT(sizeof(struct ofp_aggregate_stats_request) == 44); /* Body of reply to OFPST_AGGREGATE request. */ struct ofp_aggregate_stats_reply { - uint64_t packet_count; /* Number of packets in flows. */ - uint64_t byte_count; /* Number of bytes in flows. */ - uint32_t flow_count; /* Number of flows. */ - uint8_t pad[4]; /* Align to 64 bits. */ + uint64_t packet_count; /* Number of packets in flows. */ + uint64_t byte_count; /* Number of bytes in flows. */ + uint32_t flow_count; /* Number of flows. */ + uint8_t pad[4]; /* Align to 64 bits. */ }; OFP_ASSERT(sizeof(struct ofp_aggregate_stats_reply) == 24); /* Body of reply to OFPST_TABLE request. */ struct ofp_table_stats { - uint8_t table_id; /* Identifier of table. Lower numbered tables - are consulted first. */ - uint8_t pad[3]; /* Align to 32-bits. */ - char name[OFP_MAX_TABLE_NAME_LEN]; - uint32_t wildcards; /* Bitmap of OFPFW_* wildcards that are - supported by the table. */ - uint32_t max_entries; /* Max number of entries supported. */ - uint32_t active_count; /* Number of active entries. */ - uint64_t lookup_count; /* Number of packets looked up in table. */ - uint64_t matched_count; /* Number of packets that hit table. */ + uint8_t table_id; /* Identifier of table. Lower numbered tables + are consulted first. */ + uint8_t pad[3]; /* Align to 32-bits. */ + char name[OFP_MAX_TABLE_NAME_LEN]; + uint32_t wildcards; /* Bitmap of OFPFW_* wildcards that are + supported by the table. */ + uint32_t max_entries; /* Max number of entries supported. */ + uint32_t active_count; /* Number of active entries. */ + uint64_t lookup_count; /* Number of packets looked up in table. */ + uint64_t matched_count; /* Number of packets that hit table. */ }; OFP_ASSERT(sizeof(struct ofp_table_stats) == 64); /* Body for ofp_stats_request of type OFPST_PORT. */ struct ofp_port_stats_request { - uint16_t port_no; /* OFPST_PORT message must request statistics - * either for a single port (specified in - * port_no) or for all ports (if port_no == - * OFPP_NONE). */ - uint8_t pad[6]; + uint16_t port_no; /* OFPST_PORT message must request statistics + * either for a single port (specified in + * port_no) or for all ports (if port_no == + * OFPP_NONE). */ + uint8_t pad[6]; }; OFP_ASSERT(sizeof(struct ofp_port_stats_request) == 8); /* Body of reply to OFPST_PORT request. If a counter is unsupported, set * the field to all ones. */ struct ofp_port_stats { - uint16_t port_no; - uint8_t pad[6]; /* Align to 64-bits. */ - uint64_t rx_packets; /* Number of received packets. */ - uint64_t tx_packets; /* Number of transmitted packets. */ - uint64_t rx_bytes; /* Number of received bytes. */ - uint64_t tx_bytes; /* Number of transmitted bytes. */ - uint64_t rx_dropped; /* Number of packets dropped by RX. */ - uint64_t tx_dropped; /* Number of packets dropped by TX. */ - uint64_t rx_errors; /* Number of receive errors. This is a super-set - of more specific receive errors and should be - greater than or equal to the sum of all - rx_*_err values. */ - uint64_t tx_errors; /* Number of transmit errors. This is a super-set - of more specific transmit errors and should be - greater than or equal to the sum of all - tx_*_err values (none currently defined.) */ - uint64_t rx_frame_err; /* Number of frame alignment errors. */ - uint64_t rx_over_err; /* Number of packets with RX overrun. */ - uint64_t rx_crc_err; /* Number of CRC errors. */ - uint64_t collisions; /* Number of collisions. */ + uint16_t port_no; + uint8_t pad[6]; /* Align to 64-bits. */ + uint64_t rx_packets; /* Number of received packets. */ + uint64_t tx_packets; /* Number of transmitted packets. */ + uint64_t rx_bytes; /* Number of received bytes. */ + uint64_t tx_bytes; /* Number of transmitted bytes. */ + uint64_t rx_dropped; /* Number of packets dropped by RX. */ + uint64_t tx_dropped; /* Number of packets dropped by TX. */ + uint64_t rx_errors; /* Number of receive errors. This is a super-set + of more specific receive errors and should be + greater than or equal to the sum of all + rx_*_err values. */ + uint64_t tx_errors; /* Number of transmit errors. This is a super-set + of more specific transmit errors and should be + greater than or equal to the sum of all + tx_*_err values (none currently defined.) */ + uint64_t rx_frame_err; /* Number of frame alignment errors. */ + uint64_t rx_over_err; /* Number of packets with RX overrun. */ + uint64_t rx_crc_err; /* Number of CRC errors. */ + uint64_t collisions; /* Number of collisions. */ }; OFP_ASSERT(sizeof(struct ofp_port_stats) == 104); /* Vendor extension. */ struct ofp_vendor_header { - struct ofp_header header; /* Type OFPT_VENDOR. */ - uint32_t vendor; /* Vendor ID: - * - MSB 0: low-order bytes are IEEE OUI. - * - MSB != 0: defined by OpenFlow - * consortium. */ - /* Vendor-defined arbitrary additional data. */ + struct ofp_header header; /* Type OFPT_VENDOR. */ + uint32_t vendor; /* Vendor ID: + * - MSB 0: low-order bytes are IEEE OUI. + * - MSB != 0: defined by OpenFlow + * consortium. */ + /* Vendor-defined arbitrary additional data. */ }; OFP_ASSERT(sizeof(struct ofp_vendor_header) == 12); /* All ones is used to indicate all queues in a port (for stats retrieval). */ -#define OFPQ_ALL 0xffffffff +#define OFPQ_ALL 0xffffffff /* Min rate > 1000 means not configured. */ -#define OFPQ_MIN_RATE_UNCFG 0xffff +#define OFPQ_MIN_RATE_UNCFG 0xffff enum ofp_queue_properties { - OFPQT_NONE = 0, /* No property defined for queue (default). */ - OFPQT_MIN_RATE, /* Minimum datarate guaranteed. */ - /* Other types should be added here - * (i.e. max rate, precedence, etc). */ + OFPQT_NONE = 0, /* No property defined for queue (default). */ + OFPQT_MIN_RATE, /* Minimum datarate guaranteed. */ + /* Other types should be added here + * (i.e. max rate, precedence, etc). */ }; /* Common description for a queue. */ struct ofp_queue_prop_header { - uint16_t property; /* One of OFPQT_. */ - uint16_t len; /* Length of property, including this header. */ - uint8_t pad[4]; /* 64-bit alignemnt. */ + uint16_t property; /* One of OFPQT_. */ + uint16_t len; /* Length of property, including this header. */ + uint8_t pad[4]; /* 64-bit alignemnt. */ }; OFP_ASSERT(sizeof(struct ofp_queue_prop_header) == 8); /* Min-Rate queue property description. */ struct ofp_queue_prop_min_rate { - struct ofp_queue_prop_header prop_header; /* prop: OFPQT_MIN, len: 16. */ - uint16_t rate; /* In 1/10 of a percent; >1000 -> disabled. */ - uint8_t pad[6]; /* 64-bit alignment */ + struct ofp_queue_prop_header prop_header; /* prop: OFPQT_MIN, len: 16. */ + uint16_t rate; /* In 1/10 of a percent; >1000 -> disabled. */ + uint8_t pad[6]; /* 64-bit alignment */ }; OFP_ASSERT(sizeof(struct ofp_queue_prop_min_rate) == 16); /* Full description for a queue. */ struct ofp_packet_queue { - uint32_t queue_id; /* id for the specific queue. */ - uint16_t len; /* Length in bytes of this queue desc. */ - uint8_t pad[2]; /* 64-bit alignment. */ - struct ofp_queue_prop_header properties[0]; /* List of properties. */ + uint32_t queue_id; /* id for the specific queue. */ + uint16_t len; /* Length in bytes of this queue desc. */ + uint8_t pad[2]; /* 64-bit alignment. */ + struct ofp_queue_prop_header properties[0]; /* List of properties. */ }; OFP_ASSERT(sizeof(struct ofp_packet_queue) == 8); /* Query for port queue configuration. */ struct ofp_queue_get_config_request { - struct ofp_header header; - uint16_t port; /* Port to be queried. Should refer - to a valid physical port (i.e. < OFPP_MAX) */ - uint8_t pad[2]; /* 32-bit alignment. */ + struct ofp_header header; + uint16_t port; /* Port to be queried. Should refer + to a valid physical port (i.e. < OFPP_MAX) */ + uint8_t pad[2]; /* 32-bit alignment. */ }; OFP_ASSERT(sizeof(struct ofp_queue_get_config_request) == 12); /* Queue configuration for a given port. */ struct ofp_queue_get_config_reply { - struct ofp_header header; - uint16_t port; - uint8_t pad[6]; - struct ofp_packet_queue queues[0]; /* List of configured queues. */ + struct ofp_header header; + uint16_t port; + uint8_t pad[6]; + struct ofp_packet_queue queues[0]; /* List of configured queues. */ }; OFP_ASSERT(sizeof(struct ofp_queue_get_config_reply) == 16); /* OFPAT_ENQUEUE action struct: send packets to given queue on port. */ struct ofp_action_enqueue { - uint16_t type; /* OFPAT_ENQUEUE. */ - uint16_t len; /* Len is 16. */ - uint16_t port; /* Port that queue belongs. Should - refer to a valid physical port - (i.e. < OFPP_MAX) or OFPP_IN_PORT. */ - uint8_t pad[6]; /* Pad for 64-bit alignment. */ - uint32_t queue_id; /* Where to enqueue the packets. */ + uint16_t type; /* OFPAT_ENQUEUE. */ + uint16_t len; /* Len is 16. */ + uint16_t port; /* Port that queue belongs. Should + refer to a valid physical port + (i.e. < OFPP_MAX) or OFPP_IN_PORT. */ + uint8_t pad[6]; /* Pad for 64-bit alignment. */ + uint32_t queue_id; /* Where to enqueue the packets. */ }; OFP_ASSERT(sizeof(struct ofp_action_enqueue) == 16); struct ofp_queue_stats_request { - uint16_t port_no; /* All ports if OFPT_ALL. */ - uint8_t pad[2]; /* Align to 32-bits. */ - uint32_t queue_id; /* All queues if OFPQ_ALL. */ + uint16_t port_no; /* All ports if OFPT_ALL. */ + uint8_t pad[2]; /* Align to 32-bits. */ + uint32_t queue_id; /* All queues if OFPQ_ALL. */ }; OFP_ASSERT(sizeof(struct ofp_queue_stats_request) == 8); struct ofp_queue_stats { - uint16_t port_no; - uint8_t pad[2]; /* Align to 32-bits. */ - uint32_t queue_id; /* Queue i.d */ - uint64_t tx_bytes; /* Number of transmitted bytes. */ - uint64_t tx_packets; /* Number of transmitted packets. */ - uint64_t tx_errors; /* Number of packets dropped due to overrun. */ + uint16_t port_no; + uint8_t pad[2]; /* Align to 32-bits. */ + uint32_t queue_id; /* Queue i.d */ + uint64_t tx_bytes; /* Number of transmitted bytes. */ + uint64_t tx_packets; /* Number of transmitted packets. */ + uint64_t tx_errors; /* Number of packets dropped due to overrun. */ }; OFP_ASSERT(sizeof(struct ofp_queue_stats) == 32); diff --git a/examples/flow_table/sdn.c b/examples/flow_table/sdn.c index f5b6f4608..ec9f5c042 100644 --- a/examples/flow_table/sdn.c +++ b/examples/flow_table/sdn.c @@ -38,207 +38,197 @@ * sdn.c - contact the controller, send request and parse response ********************************************************************/ -#include -#include #include #include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include #include #include #include -#include -#include -#include #include -#include #include -#include -#include -#include -#include +#include +#include +#include -#include "sdn.h" -#include "sdn_pkt_list.h" #include "onvm_common.h" -#include "onvm_nflib.h" +#include "onvm_flow_dir.h" #include "onvm_flow_table.h" -#include "setupconn.h" +#include "onvm_nflib.h" #include "onvm_sc_common.h" -#include "onvm_flow_dir.h" +#include "sdn.h" +#include "sdn_pkt_list.h" +#include "setupconn.h" extern struct onvm_nf_info *nf_info; -extern struct rte_ring* ring_to_sdn; -extern struct rte_ring* ring_from_sdn; +extern struct rte_ring *ring_to_sdn; +extern struct rte_ring *ring_from_sdn; extern uint16_t def_destination; struct onvm_ft *pkt_buf_ft; static struct ofp_switch_config Switch_config = { - .header = { OFP_VERSION, - OFPT_GET_CONFIG_REPLY, - sizeof(struct ofp_switch_config), - 0}, - .flags = 0, - .miss_send_len = 0, + .header = {OFP_VERSION, OFPT_GET_CONFIG_REPLY, sizeof(struct ofp_switch_config), 0}, .flags = 0, .miss_send_len = 0, }; -static inline uint64_t htonll(uint64_t n) -{ - return htonl(1) == 1 ? n : ((uint64_t) htonl(n) << 32) | htonl(n >> 32); +static inline uint64_t +htonll(uint64_t n) { + return htonl(1) == 1 ? n : ((uint64_t)htonl(n) << 32) | htonl(n >> 32); } -static inline uint64_t ntohll(uint64_t n) -{ - return htonl(1) == 1 ? n : ((uint64_t) ntohl(n) << 32) | ntohl(n >> 32); +static inline uint64_t +ntohll(uint64_t n) { + return htonl(1) == 1 ? n : ((uint64_t)ntohl(n) << 32) | ntohl(n >> 32); } -void datapath_init(struct datapath *dp, int sock, int bufsize, int debug) -{ - static int ID = 1 ; - struct ofp_header ofph; - dp->sock = sock; - dp->debug = debug; - dp->id = ID++; - dp->inbuf = msgbuf_new(bufsize); - dp->outbuf = msgbuf_new(bufsize); - dp->xid = 1; - dp->switch_status = START; - - ofph.version = OFP_VERSION; - ofph.type = OFPT_HELLO; - ofph.length = htons(sizeof(ofph)); - ofph.xid = htonl(1); - msgbuf_push(dp->outbuf,(char *) &ofph, sizeof(ofph)); - debug_msg(dp, " sent hello"); +void +datapath_init(struct datapath *dp, int sock, int bufsize, int debug) { + static int ID = 1; + struct ofp_header ofph; + dp->sock = sock; + dp->debug = debug; + dp->id = ID++; + dp->inbuf = msgbuf_new(bufsize); + dp->outbuf = msgbuf_new(bufsize); + dp->xid = 1; + dp->switch_status = START; + + ofph.version = OFP_VERSION; + ofph.type = OFPT_HELLO; + ofph.length = htons(sizeof(ofph)); + ofph.xid = htonl(1); + msgbuf_push(dp->outbuf, (char *)&ofph, sizeof(ofph)); + debug_msg(dp, " sent hello"); } -void datapath_set_pollfd(struct datapath *dp, struct pollfd *pfd) -{ - pfd->events = POLLIN|POLLOUT; - pfd->fd = dp->sock; +void +datapath_set_pollfd(struct datapath *dp, struct pollfd *pfd) { + pfd->events = POLLIN | POLLOUT; + pfd->fd = dp->sock; } -void datapath_handle_io(struct datapath *dp, const struct pollfd *pfd) -{ - if(pfd->revents & POLLIN) - datapath_handle_read(dp); - if(pfd->revents & POLLOUT) - datapath_handle_write(dp); +void +datapath_handle_io(struct datapath *dp, const struct pollfd *pfd) { + if (pfd->revents & POLLIN) + datapath_handle_read(dp); + if (pfd->revents & POLLOUT) + datapath_handle_write(dp); } -void datapath_handle_read(struct datapath *dp) -{ - printf("DEBUG: handle read \n"); - struct ofp_header *ofph; - struct ofp_header echo; - struct ofp_header barrier; - struct ofp_stats_request *stats_req; - char buf[BUFLEN]; - int count; - - count = msgbuf_read(dp->inbuf, dp->sock); // read any queued data - if (count <= 0) - { - fprintf(stderr, "controller msgbuf_read() = %d: ", count); - if(count < 0) - perror("msgbuf_read"); - else { - fprintf(stderr, " closed connection "); - } - fprintf(stderr, "... exiting\n"); - exit(1); - } - while((count= msgbuf_count_buffered(dp->inbuf)) >= (int)sizeof(struct ofp_header )) - { - ofph = msgbuf_peek(dp->inbuf); - if(count < ntohs(ofph->length)) - return; // msg not all there yet - msgbuf_pull(dp->inbuf, NULL, ntohs(ofph->length)); - switch(ofph->type) - { - case OFPT_HELLO: - debug_msg(dp, "got hello"); - // we already sent our own HELLO; don't respond - datapath_change_status(dp, READY_TO_SEND); - break; - case OFPT_FEATURES_REQUEST: - debug_msg(dp, "got feature_req"); - count = make_features_reply(dp->id, ofph->xid, buf, BUFLEN); - msgbuf_push(dp->outbuf, buf, count); - debug_msg(dp, "sent feature_rsp"); - datapath_change_status(dp, READY_TO_SEND); - break; - case OFPT_SET_CONFIG: - debug_msg(dp, "parsing set_config"); - parse_set_config(ofph); - break; - case OFPT_GET_CONFIG_REQUEST: - debug_msg(dp, "got get_config_request"); - count = make_config_reply(ofph->xid, buf, BUFLEN); - msgbuf_push(dp->outbuf, buf, count); - debug_msg(dp, "sent get_config_reply"); - break; - case OFPT_VENDOR: - debug_msg(dp, "got vendor"); - count = make_vendor_reply(ofph->xid, buf, BUFLEN); - msgbuf_push(dp->outbuf, buf, count); - debug_msg(dp, "sent vendor"); - break; - case OFPT_ECHO_REQUEST: - debug_msg(dp, "got echo, sent echo_resp"); - echo.version= OFP_VERSION; - echo.length = htons(sizeof(echo)); - echo.type = OFPT_ECHO_REPLY; - echo.xid = ofph->xid; - msgbuf_push(dp->outbuf,(char *) &echo, sizeof(echo)); - break; - case OFPT_BARRIER_REQUEST: - debug_msg(dp, "got barrier, sent barrier_resp"); - barrier.version= OFP_VERSION; - barrier.length = htons(sizeof(barrier)); - barrier.type = OFPT_BARRIER_REPLY; - barrier.xid = ofph->xid; - msgbuf_push(dp->outbuf,(char *) &barrier, sizeof(barrier)); - break; - case OFPT_STATS_REQUEST: - stats_req = (struct ofp_stats_request *) ofph; - if ( ntohs(stats_req->type) == OFPST_DESC ) { - count = make_stats_desc_reply(stats_req, buf); - msgbuf_push(dp->outbuf, buf, count); - debug_msg(dp, "sent description stats_reply"); - } else { - debug_msg(dp, "Silently ignoring non-desc stats_request msg\n"); - } - break; - case OFPT_FLOW_MOD: +void +datapath_handle_read(struct datapath *dp) { + printf("DEBUG: handle read \n"); + struct ofp_header *ofph; + struct ofp_header echo; + struct ofp_header barrier; + struct ofp_stats_request *stats_req; + char buf[BUFLEN]; + int count; + + count = msgbuf_read(dp->inbuf, dp->sock); // read any queued data + if (count <= 0) { + fprintf(stderr, "controller msgbuf_read() = %d: ", count); + if (count < 0) { + perror("msgbuf_read"); + } else { + fprintf(stderr, " closed connection "); + } + fprintf(stderr, "... exiting\n"); + exit(1); + } + while ((count = msgbuf_count_buffered(dp->inbuf)) >= (int)sizeof(struct ofp_header)) { + ofph = msgbuf_peek(dp->inbuf); + if (count < ntohs(ofph->length)) + return; // msg not all there yet + msgbuf_pull(dp->inbuf, NULL, ntohs(ofph->length)); + switch (ofph->type) { + case OFPT_HELLO: + debug_msg(dp, "got hello"); + // we already sent our own HELLO; don't respond + datapath_change_status(dp, READY_TO_SEND); + break; + case OFPT_FEATURES_REQUEST: + debug_msg(dp, "got feature_req"); + count = make_features_reply(dp->id, ofph->xid, buf, BUFLEN); + msgbuf_push(dp->outbuf, buf, count); + debug_msg(dp, "sent feature_rsp"); + datapath_change_status(dp, READY_TO_SEND); + break; + case OFPT_SET_CONFIG: + debug_msg(dp, "parsing set_config"); + parse_set_config(ofph); + break; + case OFPT_GET_CONFIG_REQUEST: + debug_msg(dp, "got get_config_request"); + count = make_config_reply(ofph->xid, buf, BUFLEN); + msgbuf_push(dp->outbuf, buf, count); + debug_msg(dp, "sent get_config_reply"); + break; + case OFPT_VENDOR: + debug_msg(dp, "got vendor"); + count = make_vendor_reply(ofph->xid, buf, BUFLEN); + msgbuf_push(dp->outbuf, buf, count); + debug_msg(dp, "sent vendor"); + break; + case OFPT_ECHO_REQUEST: + debug_msg(dp, "got echo, sent echo_resp"); + echo.version = OFP_VERSION; + echo.length = htons(sizeof(echo)); + echo.type = OFPT_ECHO_REPLY; + echo.xid = ofph->xid; + msgbuf_push(dp->outbuf, (char *)&echo, sizeof(echo)); + break; + case OFPT_BARRIER_REQUEST: + debug_msg(dp, "got barrier, sent barrier_resp"); + barrier.version = OFP_VERSION; + barrier.length = htons(sizeof(barrier)); + barrier.type = OFPT_BARRIER_REPLY; + barrier.xid = ofph->xid; + msgbuf_push(dp->outbuf, (char *)&barrier, sizeof(barrier)); + break; + case OFPT_STATS_REQUEST: + stats_req = (struct ofp_stats_request *)ofph; + if (ntohs(stats_req->type) == OFPST_DESC) { + count = make_stats_desc_reply(stats_req, buf); + msgbuf_push(dp->outbuf, buf, count); + debug_msg(dp, "sent description stats_reply"); + } else { + debug_msg(dp, "Silently ignoring non-desc stats_request msg\n"); + } + break; + case OFPT_FLOW_MOD: debug_msg(dp, "got flow_mod"); - struct ofp_flow_mod *fm; - fm = (struct ofp_flow_mod *) ofph; + struct ofp_flow_mod *fm; + fm = (struct ofp_flow_mod *)ofph; int ret; struct onvm_ft_ipv4_5tuple *fk; struct onvm_service_chain *sc; struct onvm_flow_entry *flow_entry = NULL; uint32_t buffer_id = ntohl(fm->buffer_id); - if (buffer_id == UINT32_MAX) { - break; - } - struct sdn_pkt_list* sdn_list; + if (buffer_id == UINT32_MAX) { + break; + } + struct sdn_pkt_list *sdn_list; fk = flow_key_extract(&fm->match); size_t actions_len = ntohs(fm->header.length) - sizeof(*fm); sc = flow_action_extract(&fm->actions[0], actions_len); ret = onvm_flow_dir_get_key(fk, &flow_entry); if (ret == -ENOENT) { ret = onvm_flow_dir_add_key(fk, &flow_entry); + } else if (ret >= 0) { + rte_free(flow_entry->key); + rte_free(flow_entry->sc); + } else { + rte_exit(EXIT_FAILURE, "onvm_flow_dir_get parameters are invalid"); } - else if (ret >= 0) { - rte_free(flow_entry->key); - rte_free(flow_entry->sc); - } - else { - rte_exit(EXIT_FAILURE, "onvm_flow_dir_get parameters are invalid"); - } memset(flow_entry, 0, sizeof(struct onvm_flow_entry)); flow_entry->key = fk; flow_entry->sc = sc; @@ -247,204 +237,199 @@ void datapath_handle_read(struct datapath *dp) sdn_list = (struct sdn_pkt_list *)onvm_ft_get_data(pkt_buf_ft, buffer_id); sdn_pkt_list_flush(nf_info, sdn_list); break; - case OFPT_PORT_MOD: - debug_msg(dp, "got port_mod"); - break; - case OFPT_PACKET_OUT: - debug_msg(dp, "got packet_out"); - break; - case OFPT_ERROR: - debug_msg(dp, "got error"); - break; - default: - fprintf(stderr, "Ignoring OpenFlow message type %d\n", ofph->type); - } - } + case OFPT_PORT_MOD: + debug_msg(dp, "got port_mod"); + break; + case OFPT_PACKET_OUT: + debug_msg(dp, "got packet_out"); + break; + case OFPT_ERROR: + debug_msg(dp, "got error"); + break; + default: + fprintf(stderr, "Ignoring OpenFlow message type %d\n", ofph->type); + } + } } -void datapath_handle_write(struct datapath *dp) -{ - char buf[BUFLEN]; - int count = 0; - int buffer_id = 0; - - if (dp->switch_status == READY_TO_SEND) { - struct rte_mbuf* pkt; - int ret; - - ret = rte_ring_dequeue(ring_to_sdn, (void**)&pkt); - if (ret == 0) { - struct sdn_pkt_list* flow; - ret = onvm_ft_lookup_pkt(pkt_buf_ft, pkt, (char**) &flow); - if(ret == -ENOENT) { - #ifdef DEBUG_PRINT - printf("SDN: not in pkt buffer table, creating list. RSS=%d port=%d\n", pkt->hash.rss, pkt->port); - #endif - ret = onvm_ft_add_pkt(pkt_buf_ft, pkt, (char**) &flow); - if (ret == -ENOSPC) { - #ifdef DEBUG_PRINT - printf("Pkt buffer table no space\n"); - #endif - exit(1); +void +datapath_handle_write(struct datapath *dp) { + char buf[BUFLEN]; + int count = 0; + int buffer_id = 0; + + if (dp->switch_status == READY_TO_SEND) { + struct rte_mbuf *pkt; + int ret; + + ret = rte_ring_dequeue(ring_to_sdn, (void **)&pkt); + if (ret == 0) { + struct sdn_pkt_list *flow; + ret = onvm_ft_lookup_pkt(pkt_buf_ft, pkt, (char **)&flow); + if (ret == -ENOENT) { +#ifdef DEBUG_PRINT + printf("SDN: not in pkt buffer table, creating list. RSS=%d port=%d\n", pkt->hash.rss, + pkt->port); +#endif + ret = onvm_ft_add_pkt(pkt_buf_ft, pkt, (char **)&flow); + if (ret == -ENOSPC) { +#ifdef DEBUG_PRINT + printf("Pkt buffer table no space\n"); +#endif + exit(1); + } + } + buffer_id = ret; +#ifdef DEBUG_PRINT + printf("SDN: in pkt buffer table, adding to list. RSS=%d port=%d\n", pkt->hash.rss, pkt->port); +#endif + sdn_pkt_list_add(flow, pkt); + memset(buf, 0, BUFLEN); + if (sdn_pkt_list_get_flag(flow) == 0) { + count = make_packet_in(dp->xid++, buffer_id, buf, pkt); + sdn_pkt_list_set_flag(flow); + if (count > 0) { + msgbuf_push(dp->outbuf, buf, count); + } + } } - } - buffer_id = ret; - #ifdef DEBUG_PRINT - printf("SDN: in pkt buffer table, adding to list. RSS=%d port=%d\n", pkt->hash.rss, pkt->port); - #endif - sdn_pkt_list_add(flow, pkt); - memset(buf, 0, BUFLEN); - if (sdn_pkt_list_get_flag(flow) == 0) { - count = make_packet_in(dp->xid++, buffer_id, buf, pkt); - sdn_pkt_list_set_flag(flow); - if (count > 0) { - msgbuf_push(dp->outbuf, buf, count); - } - } - } - - } - - if (msgbuf_count_buffered(dp->outbuf) > 0) { - msgbuf_write(dp->outbuf, dp->sock, 0); - } + } + if (msgbuf_count_buffered(dp->outbuf) > 0) { + msgbuf_write(dp->outbuf, dp->sock, 0); + } } -void datapath_change_status(struct datapath *dp, int new_status) -{ +void +datapath_change_status(struct datapath *dp, int new_status) { dp->switch_status = new_status; debug_msg(dp, "next status %d", new_status); } -int parse_set_config(struct ofp_header *msg) -{ - struct ofp_switch_config *sc; - assert(msg->type == OFPT_SET_CONFIG); - sc = (struct ofp_switch_config *) msg; - memcpy(&Switch_config, sc, sizeof(struct ofp_switch_config)); +int +parse_set_config(struct ofp_header *msg) { + struct ofp_switch_config *sc; + assert(msg->type == OFPT_SET_CONFIG); + sc = (struct ofp_switch_config *)msg; + memcpy(&Switch_config, sc, sizeof(struct ofp_switch_config)); - return 0; + return 0; } -int make_config_reply( int xid, char *buf, int buflen) -{ - int len = sizeof(struct ofp_switch_config); - assert(buflen >= len); - Switch_config.header.type = OFPT_GET_CONFIG_REPLY; - Switch_config.header.xid = xid; - memcpy(buf, &Switch_config, len); +int +make_config_reply(int xid, char *buf, int buflen) { + int len = sizeof(struct ofp_switch_config); + assert(buflen >= len); + Switch_config.header.type = OFPT_GET_CONFIG_REPLY; + Switch_config.header.xid = xid; + memcpy(buf, &Switch_config, len); - return len; + return len; } -int make_features_reply(int id, int xid, char *buf, unsigned int buflen) -{ - struct ofp_switch_features *features; - const char fake[] = // stolen from wireshark - { - - 0x97,0x06,0x00,0xe0,0x04,0x01,0x00,0x00,0x00,0x00,0x76,0xa9, - 0xd4,0x0d,0x25,0x48,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x07,0xff,0x00,0x01,0x1a,0xc1,0x51,0xff,0xef,0x8a,0x76,0x65,0x74,0x68, - 0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x02,0xce,0x2f,0xa2,0x87,0xf6,0x70,0x76,0x65,0x74,0x68, - 0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x03,0xca,0x8a,0x1e,0xf3,0x77,0xef,0x76,0x65,0x74,0x68, - 0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x04,0xfa,0xbc,0x77,0x8d,0x7e,0x0b,0x76,0x65,0x74,0x68, - 0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00 - }; - - assert(buflen> sizeof(fake)); - memcpy(buf, fake, sizeof(fake)); - features = (struct ofp_switch_features *) buf; - features->header.version = OFP_VERSION; - features->header.xid = xid; - features->datapath_id = htonll(id); - - return sizeof(fake); +int +make_features_reply(int id, int xid, char *buf, unsigned int buflen) { + struct ofp_switch_features *features; + const char fake[] = // stolen from wireshark + { + + 0x97, 0x06, 0x00, 0xe0, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76, 0xa9, 0xd4, 0x0d, 0x25, 0x48, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, + 0x00, 0x01, 0x1a, 0xc1, 0x51, 0xff, 0xef, 0x8a, 0x76, 0x65, 0x74, 0x68, 0x31, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0xce, 0x2f, 0xa2, 0x87, 0xf6, 0x70, 0x76, 0x65, 0x74, 0x68, 0x33, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xca, 0x8a, 0x1e, 0xf3, 0x77, 0xef, 0x76, 0x65, 0x74, 0x68, 0x35, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0xfa, 0xbc, 0x77, 0x8d, 0x7e, 0x0b, 0x76, 0x65, 0x74, 0x68, 0x37, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + assert(buflen > sizeof(fake)); + memcpy(buf, fake, sizeof(fake)); + features = (struct ofp_switch_features *)buf; + features->header.version = OFP_VERSION; + features->header.xid = xid; + features->datapath_id = htonll(id); + + return sizeof(fake); } -int make_stats_desc_reply(struct ofp_stats_request *req, char *buf) -{ - static struct ofp_desc_stats cbench_desc = { - .mfr_desc = "Cbench - controller I/O benchmark", - .hw_desc = "this is actually software...", - //.sw_desc = "version " VERSION, - .sw_desc = "version 1", - .serial_num= "none", - .dp_desc = "none" - }; - struct ofp_stats_reply *reply; - int len = sizeof(struct ofp_stats_reply) + sizeof(struct ofp_desc_stats); - - assert(BUFLEN > len); - assert(ntohs(req->type) == OFPST_DESC); - memcpy( buf, req, sizeof(*req)); - reply = (struct ofp_stats_reply *) buf; - reply->header.type = OFPT_STATS_REPLY; - reply->header.length = htons(len); - reply->flags = 0; - memcpy(reply->body, &cbench_desc, sizeof(cbench_desc)); - - return len; +int +make_stats_desc_reply(struct ofp_stats_request *req, char *buf) { + static struct ofp_desc_stats cbench_desc = {.mfr_desc = "Cbench - controller I/O benchmark", + .hw_desc = "this is actually software...", + //.sw_desc = "version " VERSION, + .sw_desc = "version 1", + .serial_num = "none", + .dp_desc = "none"}; + struct ofp_stats_reply *reply; + int len = sizeof(struct ofp_stats_reply) + sizeof(struct ofp_desc_stats); + + assert(BUFLEN > len); + assert(ntohs(req->type) == OFPST_DESC); + memcpy(buf, req, sizeof(*req)); + reply = (struct ofp_stats_reply *)buf; + reply->header.type = OFPT_STATS_REPLY; + reply->header.length = htons(len); + reply->flags = 0; + memcpy(reply->body, &cbench_desc, sizeof(cbench_desc)); + + return len; } -int make_vendor_reply(int xid, char *buf, unsigned int buflen) -{ - struct ofp_error_msg *e; +int +make_vendor_reply(int xid, char *buf, unsigned int buflen) { + struct ofp_error_msg *e; - assert(buflen> sizeof(struct ofp_error_msg)); - e = (struct ofp_error_msg *) buf; - e->header.type = OFPT_ERROR; - e->header.version = OFP_VERSION; - e->header.length = htons(sizeof(struct ofp_error_msg)); - e->header.xid = xid; - e->type = htons(OFPET_BAD_REQUEST); - e->code = htons(OFPBRC_BAD_VENDOR); + assert(buflen > sizeof(struct ofp_error_msg)); + e = (struct ofp_error_msg *)buf; + e->header.type = OFPT_ERROR; + e->header.version = OFP_VERSION; + e->header.length = htons(sizeof(struct ofp_error_msg)); + e->header.xid = xid; + e->type = htons(OFPET_BAD_REQUEST); + e->code = htons(OFPBRC_BAD_VENDOR); - return sizeof(struct ofp_error_msg); + return sizeof(struct ofp_error_msg); } -int debug_msg(struct datapath *dp, const char *msg, ...) -{ - va_list aq; - - if(dp->debug == 0 ) - return 0; - fprintf(stderr,"-------Switch %d: ", dp->id); - va_start(aq,msg); - vfprintf(stderr,msg,aq); - if(msg[strlen(msg)-1] != '\n') - fprintf(stderr, "\n"); - // fflush(stderr); // should be redundant, but often isn't :-( - - return 1; +int +debug_msg(struct datapath *dp, const char *msg, ...) { + va_list aq; + + if (dp->debug == 0) + return 0; + fprintf(stderr, "-------Switch %d: ", dp->id); + va_start(aq, msg); + vfprintf(stderr, msg, aq); + if (msg[strlen(msg) - 1] != '\n') + fprintf(stderr, "\n"); + // fflush(stderr); // should be redundant, but often isn't :-( + + return 1; } -void get_header(struct rte_mbuf *pkt, struct ofp_packet_in *pi) -{ +void +get_header(struct rte_mbuf *pkt, struct ofp_packet_in *pi) { char *header; header = (char *)(rte_pktmbuf_mtod(pkt, unsigned char *)); memcpy(pi->data, header, OFP_DEFAULT_MISS_SEND_LEN); } -int make_packet_in(int xid, uint32_t buffer_id, char *buf, struct rte_mbuf *pkt) -{ +int +make_packet_in(int xid, uint32_t buffer_id, char *buf, struct rte_mbuf *pkt) { struct ofp_packet_in *pi; - struct onvm_pkt_meta *meta; + struct onvm_pkt_meta *meta; int len; pi = (struct ofp_packet_in *)buf; pi->header.version = OFP_VERSION; pi->header.type = OFPT_PACKET_IN; pi->header.xid = htonl(xid); - meta = onvm_get_pkt_meta(pkt); + meta = onvm_get_pkt_meta(pkt); pi->in_port = htons(meta->src); pi->buffer_id = htonl(buffer_id); pi->reason = OFPR_NO_MATCH; @@ -457,11 +442,10 @@ int make_packet_in(int xid, uint32_t buffer_id, char *buf, struct rte_mbuf *pkt) return len; } -struct onvm_ft_ipv4_5tuple* flow_key_extract(struct ofp_match *match) -{ - struct onvm_ft_ipv4_5tuple* fk; - fk = rte_calloc("flow_key", - 1, sizeof(struct onvm_ft_ipv4_5tuple), 0); +struct onvm_ft_ipv4_5tuple * +flow_key_extract(struct ofp_match *match) { + struct onvm_ft_ipv4_5tuple *fk; + fk = rte_calloc("flow_key", 1, sizeof(struct onvm_ft_ipv4_5tuple), 0); if (fk == NULL) { rte_exit(EXIT_FAILURE, "Cannot allocate memory for flow key\n"); } @@ -469,107 +453,108 @@ struct onvm_ft_ipv4_5tuple* flow_key_extract(struct ofp_match *match) fk->src_addr = match->nw_src; fk->dst_addr = match->nw_dst; fk->proto = match->nw_proto; - fk->src_port = match->tp_src; - fk->dst_port = match->tp_dst; + fk->src_port = match->tp_src; + fk->dst_port = match->tp_dst; return fk; } -struct onvm_service_chain* -flow_action_extract(struct ofp_action_header *oah, size_t actions_len) -{ - uint8_t *p = (uint8_t *)oah; - struct onvm_service_chain *chain; - - chain = rte_calloc("service chain", - 1, sizeof(struct onvm_service_chain), 0); - if (chain == NULL) { - rte_exit(EXIT_FAILURE, "Cannot allocate memory for service chain\n"); - } - - if (actions_len == 0) { - onvm_sc_append_entry(chain, ONVM_NF_ACTION_DROP, 0); - } - else { - while (actions_len > 0) { - struct ofp_action_header *ah = (struct ofp_action_header *)p; - size_t len = htons(ah->len); - if (ah->type == htons(OFPAT_OUTPUT)) { //OFPAT_OUTPUT action - struct ofp_action_output *oao = (struct ofp_action_output *)p; - onvm_sc_append_entry(chain, ONVM_NF_ACTION_OUT, ntohs(oao->port)); - } - else if (ah->type == htons(OFPAT_ENQUEUE)) { - struct ofp_action_enqueue *oae = (struct ofp_action_enqueue *)p; - onvm_sc_append_entry(chain, ONVM_NF_ACTION_TONF, (uint16_t)(ntohl(oae->queue_id))); - } - p += len; - actions_len -= len; +struct onvm_service_chain * +flow_action_extract(struct ofp_action_header *oah, size_t actions_len) { + uint8_t *p = (uint8_t *)oah; + struct onvm_service_chain *chain; + + chain = rte_calloc("service chain", 1, sizeof(struct onvm_service_chain), 0); + if (chain == NULL) { + rte_exit(EXIT_FAILURE, "Cannot allocate memory for service chain\n"); + } + + if (actions_len == 0) { + onvm_sc_append_entry(chain, ONVM_NF_ACTION_DROP, 0); + } else { + while (actions_len > 0) { + struct ofp_action_header *ah = (struct ofp_action_header *)p; + size_t len = htons(ah->len); + if (ah->type == htons(OFPAT_OUTPUT)) { // OFPAT_OUTPUT action + struct ofp_action_output *oao = (struct ofp_action_output *)p; + onvm_sc_append_entry(chain, ONVM_NF_ACTION_OUT, ntohs(oao->port)); + } else if (ah->type == htons(OFPAT_ENQUEUE)) { + struct ofp_action_enqueue *oae = (struct ofp_action_enqueue *)p; + onvm_sc_append_entry(chain, ONVM_NF_ACTION_TONF, (uint16_t)(ntohl(oae->queue_id))); + } + p += len; + actions_len -= len; + } } - } - return chain; + return chain; } -int setup_securechannel(void *ptr) { - (void)ptr; // TODO: should take SDN controller IP/port as argument - struct datapath *dp; - int sock; - const char *controller_hostname = "localhost"; - int controller_port = 6633; - int debug = 1; - struct sdn_pkt_list *sdn_list; - int i; - - printf("SDN Connection running on %d\n", rte_lcore_id()); - - fprintf(stderr, "Connecting to controller at %s:%d \n" - "Debugging info is %s\n", - controller_hostname, controller_port, - debug == 1 ? "on":"off"); - - dp = malloc(sizeof(struct datapath)); - assert(dp); - sock = make_tcp_connection(controller_hostname, controller_port); //FIXIT - if (sock<0) { - fprintf(stderr, "make_nonblock_tcp_connection :: returned %d", sock); - exit(1); - } - - if(debug) fprintf(stderr,"Initializing switch...\n"); - fflush(stderr); - datapath_init(dp, sock, 65536, debug); - - if(debug) fprintf(stderr," :: done.\n"); - fflush(stderr); - - if(debug) fprintf(stderr,"Creating pkt buffer table...\n"); - pkt_buf_ft = onvm_ft_create(1024, sizeof(struct sdn_pkt_list)); - if(pkt_buf_ft == NULL) { - rte_exit(EXIT_FAILURE, "Unable to create pkt buffer table\n"); - } - for (i = 0; i < 1024; i++) { - sdn_list = (struct sdn_pkt_list *)onvm_ft_get_data(pkt_buf_ft, i); - sdn_pkt_list_init(sdn_list); - } - - if(debug) fprintf(stderr,"Running secure channel\n"); - run_securechannel(dp); - return 0; +int +setup_securechannel(void *ptr) { + (void)ptr; // TODO: should take SDN controller IP/port as argument + struct datapath *dp; + int sock; + const char *controller_hostname = "localhost"; + int controller_port = 6633; + int debug = 1; + struct sdn_pkt_list *sdn_list; + int i; + + printf("SDN Connection running on %d\n", rte_lcore_id()); + + fprintf(stderr, + "Connecting to controller at %s:%d \n" + "Debugging info is %s\n", + controller_hostname, controller_port, debug == 1 ? "on" : "off"); + + dp = malloc(sizeof(struct datapath)); + assert(dp); + sock = make_tcp_connection(controller_hostname, controller_port); // FIXIT + if (sock < 0) { + fprintf(stderr, "make_nonblock_tcp_connection :: returned %d", sock); + exit(1); + } + + if (debug) + fprintf(stderr, "Initializing switch...\n"); + fflush(stderr); + datapath_init(dp, sock, 65536, debug); + + if (debug) + fprintf(stderr, " :: done.\n"); + fflush(stderr); + + if (debug) + fprintf(stderr, "Creating pkt buffer table...\n"); + pkt_buf_ft = onvm_ft_create(1024, sizeof(struct sdn_pkt_list)); + if (pkt_buf_ft == NULL) { + rte_exit(EXIT_FAILURE, "Unable to create pkt buffer table\n"); + } + for (i = 0; i < 1024; i++) { + sdn_list = (struct sdn_pkt_list *)onvm_ft_get_data(pkt_buf_ft, i); + sdn_pkt_list_init(sdn_list); + } + + if (debug) + fprintf(stderr, "Running secure channel\n"); + run_securechannel(dp); + return 0; } /* loop secure channel thread and monitor io event */ -void* run_securechannel(void *dp) -{ - struct pollfd *pollfds; - dp = (struct datapath *)dp; - int n_switches = 1; - - pollfds = malloc(n_switches * sizeof(struct pollfd)); - assert(pollfds); - while(1) { - datapath_set_pollfd(dp, pollfds); - poll(pollfds, n_switches, 1000); - datapath_handle_io(dp, pollfds); - } - free(pollfds); +void * +run_securechannel(void *dp) { + struct pollfd *pollfds; + dp = (struct datapath *)dp; + int n_switches = 1; + + pollfds = malloc(n_switches * sizeof(struct pollfd)); + assert(pollfds); + while (1) { + datapath_set_pollfd(dp, pollfds); + poll(pollfds, n_switches, 1000); + datapath_handle_io(dp, pollfds); + } + free(pollfds); } diff --git a/examples/flow_table/sdn.h b/examples/flow_table/sdn.h index e17bcabc0..ea6a5b3be 100644 --- a/examples/flow_table/sdn.h +++ b/examples/flow_table/sdn.h @@ -38,52 +38,67 @@ * sdn.h - contact the controller, send request and parse response ********************************************************************/ - #ifndef SDN_H #define SDN_H #include #include #include "msgbuf.h" -#include "openflow.h" #include "onvm_flow_table.h" +#include "openflow.h" #define NUM_BUFFER_IDS 100000 #define ETH_ADDR_LEN 6 enum handshake_status { - START = 0, - READY_TO_SEND = 99, + START = 0, + READY_TO_SEND = 99, }; - -struct datapath -{ - int id; //switch dpid - int sock; //secure channel, connected to controller - struct msgbuf *inbuf, *outbuf; //input, output buffer - int count; //number of responses received??? - int xid; //transaction id - int switch_status; //current switch status - int debug; //print debug info +struct datapath { + int id; // switch dpid + int sock; // secure channel, connected to controller + struct msgbuf *inbuf, *outbuf; // input, output buffer + int count; // number of responses received??? + int xid; // transaction id + int switch_status; // current switch status + int debug; // print debug info }; -void datapath_init(struct datapath *dp, int sock, int bufsize, int debug); -void datapath_set_pollfd(struct datapath *dp, struct pollfd *pfd); -void datapath_handle_io(struct datapath *dp, const struct pollfd *pfd); -void datapath_handle_read(struct datapath *dp); -void datapath_handle_write(struct datapath *dp); -void datapath_change_status(struct datapath *dp, int new_status); -int debug_msg(struct datapath *dp, const char *msg, ...); -int make_features_reply(int switch_id, int xid, char *buf, unsigned int buflen); -int parse_set_config(struct ofp_header *msg); -int make_packet_in(int xid, uint32_t buffer_id, char *buf, struct rte_mbuf *pkt); -int make_config_reply( int xid, char *buf, int buflen); -int make_vendor_reply(int xid, char *buf, unsigned int buflen); -int make_stats_desc_reply(struct ofp_stats_request *req, char *buf); -struct onvm_ft_ipv4_5tuple* flow_key_extract(struct ofp_match *match); -struct onvm_service_chain* flow_action_extract(struct ofp_action_header *oah, size_t actions_len); -void get_header(struct rte_mbuf *pkt, struct ofp_packet_in *pi); -int setup_securechannel(void *); -void* run_securechannel(void *dp); +void +datapath_init(struct datapath *dp, int sock, int bufsize, int debug); +void +datapath_set_pollfd(struct datapath *dp, struct pollfd *pfd); +void +datapath_handle_io(struct datapath *dp, const struct pollfd *pfd); +void +datapath_handle_read(struct datapath *dp); +void +datapath_handle_write(struct datapath *dp); +void +datapath_change_status(struct datapath *dp, int new_status); +int +debug_msg(struct datapath *dp, const char *msg, ...); +int +make_features_reply(int switch_id, int xid, char *buf, unsigned int buflen); +int +parse_set_config(struct ofp_header *msg); +int +make_packet_in(int xid, uint32_t buffer_id, char *buf, struct rte_mbuf *pkt); +int +make_config_reply(int xid, char *buf, int buflen); +int +make_vendor_reply(int xid, char *buf, unsigned int buflen); +int +make_stats_desc_reply(struct ofp_stats_request *req, char *buf); +struct onvm_ft_ipv4_5tuple * +flow_key_extract(struct ofp_match *match); +struct onvm_service_chain * +flow_action_extract(struct ofp_action_header *oah, size_t actions_len); +void +get_header(struct rte_mbuf *pkt, struct ofp_packet_in *pi); +int +setup_securechannel(void *); +void * +run_securechannel(void *dp); #endif diff --git a/examples/flow_table/sdn_pkt_list.h b/examples/flow_table/sdn_pkt_list.h index 75e06e9b2..9c1de7dda 100644 --- a/examples/flow_table/sdn_pkt_list.h +++ b/examples/flow_table/sdn_pkt_list.h @@ -45,15 +45,15 @@ #include "onvm_nflib.h" struct sdn_pkt_list { - struct sdn_pkt_entry *head; - struct sdn_pkt_entry *tail; + struct sdn_pkt_entry* head; + struct sdn_pkt_entry* tail; int flag; - int counter; + int counter; }; struct sdn_pkt_entry { - struct rte_mbuf *pkt; - struct sdn_pkt_entry *next; + struct rte_mbuf* pkt; + struct sdn_pkt_entry* next; }; // FIXME: These functions should have return codes to indicate errors. @@ -64,60 +64,59 @@ sdn_pkt_list_init(struct sdn_pkt_list* list) { list->head = NULL; list->tail = NULL; list->flag = 0; - list->counter = 0; + list->counter = 0; } static inline void -sdn_pkt_list_add(struct sdn_pkt_list* list, struct rte_mbuf *pkt) { - list->counter++; +sdn_pkt_list_add(struct sdn_pkt_list* list, struct rte_mbuf* pkt) { + list->counter++; /* FIXME: check for malloc errors */ struct sdn_pkt_entry* entry; - entry = (struct sdn_pkt_entry*) calloc(1, sizeof(struct sdn_pkt_entry)); + entry = (struct sdn_pkt_entry*)calloc(1, sizeof(struct sdn_pkt_entry)); entry->pkt = pkt; entry->next = NULL; - if (list->head == NULL) { - list->head = entry; - list->tail = list->head; - } - else { - list->tail->next = entry; - list->tail = entry; - } + if (list->head == NULL) { + list->head = entry; + list->tail = list->head; + } else { + list->tail->next = entry; + list->tail = entry; + } } static inline void sdn_pkt_list_set_flag(struct sdn_pkt_list* list) { - list->flag = 1; + list->flag = 1; } static inline int sdn_pkt_list_get_flag(struct sdn_pkt_list* list) { - return list->flag; + return list->flag; } static inline void -sdn_pkt_list_flush(struct onvm_nf_info *nf_info, struct sdn_pkt_list* list) { - struct sdn_pkt_entry* entry; - struct rte_mbuf *pkt; - struct onvm_pkt_meta* meta; +sdn_pkt_list_flush(struct onvm_nf_info* nf_info, struct sdn_pkt_list* list) { + struct sdn_pkt_entry* entry; + struct rte_mbuf* pkt; + struct onvm_pkt_meta* meta; - printf("list items:%d\n", list->counter); + printf("list items:%d\n", list->counter); - while(list->head) { - entry = list->head; - list->head = entry->next; - pkt = entry->pkt; - meta = onvm_get_pkt_meta(pkt); - meta->action = ONVM_NF_ACTION_NEXT; - meta->chain_index = 0; - onvm_nflib_return_pkt(nf_info, pkt); - free(entry); - list->counter--; - } + while (list->head) { + entry = list->head; + list->head = entry->next; + pkt = entry->pkt; + meta = onvm_get_pkt_meta(pkt); + meta->action = ONVM_NF_ACTION_NEXT; + meta->chain_index = 0; + onvm_nflib_return_pkt(nf_info, pkt); + free(entry); + list->counter--; + } - list->flag = 0; - list->head = NULL; - list->tail = NULL; - list->counter = 0; + list->flag = 0; + list->head = NULL; + list->tail = NULL; + list->counter = 0; } #endif diff --git a/examples/flow_table/setupconn.c b/examples/flow_table/setupconn.c index 0ac39c5a4..672920419 100644 --- a/examples/flow_table/setupconn.c +++ b/examples/flow_table/setupconn.c @@ -44,120 +44,114 @@ #include #include #include +#include #include #include #include -#include -#include -#include #include -#include #include +#include +#include +#include #include "setupconn.h" /**********************************************************************/ -int timeout_connect(int fd, const char *hostname, int port, int mstimeout) { - int ret = 0; - int flags; - fd_set fds; - struct timeval tv; - struct addrinfo *res=NULL; - struct addrinfo hints; - char sport[BUFLEN]; - int err; +int +timeout_connect(int fd, const char *hostname, int port, int mstimeout) { + int ret = 0; + int flags; + fd_set fds; + struct timeval tv; + struct addrinfo *res = NULL; + struct addrinfo hints; + char sport[BUFLEN]; + int err; - hints.ai_flags = 0; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_addrlen = 0; - hints.ai_addr = NULL; - hints.ai_canonname = NULL; - hints.ai_next = NULL; + hints.ai_flags = 0; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_addrlen = 0; + hints.ai_addr = NULL; + hints.ai_canonname = NULL; + hints.ai_next = NULL; - snprintf(sport,BUFLEN,"%d",port); + snprintf(sport, BUFLEN, "%d", port); - err = getaddrinfo(hostname,sport,&hints,&res); - if(err|| (res==NULL)) - { - if(res) - freeaddrinfo(res); - return -1; - } - // set non blocking - if((flags = fcntl(fd, F_GETFL)) < 0) { - fprintf(stderr, "timeout_connect: unable to get socket flags\n"); - freeaddrinfo(res); - return -1; - } - if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { - fprintf(stderr, "timeout_connect: unable to put the socket in non-blocking mode\n"); - freeaddrinfo(res); - return -1; - } - FD_ZERO(&fds); - FD_SET(fd, &fds); + err = getaddrinfo(hostname, sport, &hints, &res); + if (err || (res == NULL)) { + if (res) + freeaddrinfo(res); + return -1; + } + // set non blocking + if ((flags = fcntl(fd, F_GETFL)) < 0) { + fprintf(stderr, "timeout_connect: unable to get socket flags\n"); + freeaddrinfo(res); + return -1; + } + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { + fprintf(stderr, "timeout_connect: unable to put the socket in non-blocking mode\n"); + freeaddrinfo(res); + return -1; + } + FD_ZERO(&fds); + FD_SET(fd, &fds); - if(mstimeout >= 0) - { - tv.tv_sec = mstimeout / 1000; - tv.tv_usec = (mstimeout % 1000) * 1000; + if (mstimeout >= 0) { + tv.tv_sec = mstimeout / 1000; + tv.tv_usec = (mstimeout % 1000) * 1000; - errno = 0; + errno = 0; - if(connect(fd, res->ai_addr, res->ai_addrlen) < 0) - { - if((errno != EWOULDBLOCK) && (errno != EINPROGRESS)) - { - fprintf(stderr, "timeout_connect: error connecting: %d\n", errno); - freeaddrinfo(res); - return -1; - } - } - ret = select(fd+1, NULL, &fds, NULL, &tv); - } - freeaddrinfo(res); + if (connect(fd, res->ai_addr, res->ai_addrlen) < 0) { + if ((errno != EWOULDBLOCK) && (errno != EINPROGRESS)) { + fprintf(stderr, "timeout_connect: error connecting: %d\n", errno); + freeaddrinfo(res); + return -1; + } + } + ret = select(fd + 1, NULL, &fds, NULL, &tv); + } + freeaddrinfo(res); - if(ret != 1) - { - if(ret == 0) - return -1; - else - return ret; - } - return 0; + if (ret != 1) { + if (ret == 0) + return -1; + else + return ret; + } + return 0; } /**********************************************************************/ -int make_tcp_connection(const char *hostname, unsigned short port) -{ - struct sockaddr_in local; - int s; - int err; - int mstimeout = 3000; +int +make_tcp_connection(const char *hostname, unsigned short port) { + struct sockaddr_in local; + int s; + int err; + int mstimeout = 3000; - s = socket(AF_INET, SOCK_STREAM, 0); - if(s<0) { - perror("make_tcp_connection: socket"); - exit(1); - } - local.sin_family = PF_INET; - local.sin_addr.s_addr = INADDR_ANY; - local.sin_port = htons(INADDR_ANY); + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) { + perror("make_tcp_connection: socket"); + exit(1); + } + local.sin_family = PF_INET; + local.sin_addr.s_addr = INADDR_ANY; + local.sin_port = htons(INADDR_ANY); - err=bind(s,(struct sockaddr *)&local, sizeof(local)); - if(err) - { - perror("make_tcp_connection_from_port::bind"); - return -4; - } + err = bind(s, (struct sockaddr *)&local, sizeof(local)); + if (err) { + perror("make_tcp_connection_from_port::bind"); + return -4; + } - err = timeout_connect(s,hostname,port, mstimeout); - if(err) - { - perror("make_tcp_connection: connect"); - close(s); - return err; // bad connect - } - return s; + err = timeout_connect(s, hostname, port, mstimeout); + if (err) { + perror("make_tcp_connection: connect"); + close(s); + return err; // bad connect + } + return s; } diff --git a/examples/flow_table/setupconn.h b/examples/flow_table/setupconn.h index 56248fa92..7925f359e 100644 --- a/examples/flow_table/setupconn.h +++ b/examples/flow_table/setupconn.h @@ -37,7 +37,7 @@ * * setupconn.h - set up the connection to sdn controller ********************************************************************/ - + #ifndef SETUPCONN_H #define SETUPCONN_H @@ -45,8 +45,9 @@ #define BUFLEN 65536 #endif - -int timeout_connect(int fd, const char *hostname, int port, int mstimeout); -int make_tcp_connection(const char *hostname, unsigned short port); +int +timeout_connect(int fd, const char *hostname, int port, int mstimeout); +int +make_tcp_connection(const char *hostname, unsigned short port); #endif diff --git a/examples/flow_tracker/flow_tracker.c b/examples/flow_tracker/flow_tracker.c index 12346728a..1d812147a 100644 --- a/examples/flow_tracker/flow_tracker.c +++ b/examples/flow_tracker/flow_tracker.c @@ -38,26 +38,26 @@ * flow_tracker.c - an example using onvm. Stores incoming flows and prints info about them. ********************************************************************/ -#include -#include -#include +#include +#include #include #include -#include +#include +#include #include -#include #include +#include #include -#include -#include +#include #include +#include #include -#include +#include +#include "onvm_flow_table.h" #include "onvm_nflib.h" #include "onvm_pkt_helper.h" -#include "onvm_flow_table.h" #define NF_TAG "flow_tracker" #define TBL_SIZE 100 @@ -102,39 +102,39 @@ usage(const char *progname) { */ static int parse_app_args(int argc, char *argv[], const char *progname) { - int c, dst_flag = 0; - - while ((c = getopt(argc, argv, "d:p:")) != -1) { - switch(c) { - case 'd': - state_info->destination = strtoul(optarg, NULL, 10); - dst_flag = 1; - RTE_LOG(INFO, APP, "Sending packets to service ID %d\n", state_info->destination); - break; - case 'p': - state_info->print_delay = strtoul(optarg, NULL, 10); - break; - case '?': - usage(progname); - if (optopt == 'd') - RTE_LOG(INFO, APP, "Option -%c requires an argument\n", optopt); - else if (optopt == 'p') - RTE_LOG(INFO, APP, "Option -%c requires an argument\n", optopt); - else - RTE_LOG(INFO, APP, "Unknown option character\n"); - return -1; - default: - usage(progname); - return -1; + int c, dst_flag = 0; + + while ((c = getopt(argc, argv, "d:p:")) != -1) { + switch (c) { + case 'd': + state_info->destination = strtoul(optarg, NULL, 10); + dst_flag = 1; + RTE_LOG(INFO, APP, "Sending packets to service ID %d\n", state_info->destination); + break; + case 'p': + state_info->print_delay = strtoul(optarg, NULL, 10); + break; + case '?': + usage(progname); + if (optopt == 'd') + RTE_LOG(INFO, APP, "Option -%c requires an argument\n", optopt); + else if (optopt == 'p') + RTE_LOG(INFO, APP, "Option -%c requires an argument\n", optopt); + else + RTE_LOG(INFO, APP, "Unknown option character\n"); + return -1; + default: + usage(progname); + return -1; } - } + } - if (!dst_flag) { + if (!dst_flag) { RTE_LOG(INFO, APP, "Flow Tracker NF requires a destination NF service ID with the -d flag \n"); return -1; - } + } - return optind; + return optind; } /* @@ -206,8 +206,7 @@ do_stats_display(struct state_info *state_info) { printf("%d. Status: ", index); if (data->is_active) { printf("Active\n"); - } - else { + } else { printf("Expired\n"); } @@ -222,7 +221,7 @@ do_stats_display(struct state_info *state_info) { * if so, it calls clear_entries() to free up space. */ static int -table_add_entry(struct onvm_ft_ipv4_5tuple* key, struct state_info *state_info) { +table_add_entry(struct onvm_ft_ipv4_5tuple *key, struct state_info *state_info) { struct flow_stats *data = NULL; if (unlikely(key == NULL || state_info == NULL)) { @@ -254,7 +253,7 @@ table_add_entry(struct onvm_ft_ipv4_5tuple* key, struct state_info *state_info) * and if it doesn't, it calls table_add_entry() to add it to the table. */ static int -table_lookup_entry(struct rte_mbuf* pkt, struct state_info *state_info) { +table_lookup_entry(struct rte_mbuf *pkt, struct state_info *state_info) { struct flow_stats *data = NULL; struct onvm_ft_ipv4_5tuple key; diff --git a/examples/load_balancer/load_balancer.c b/examples/load_balancer/load_balancer.c index 684bb07bf..0d609c3bd 100644 --- a/examples/load_balancer/load_balancer.c +++ b/examples/load_balancer/load_balancer.c @@ -38,37 +38,37 @@ * load_balancer.c - an example Layer 3 round-robin load balancer. ********************************************************************/ -#include -#include -#include +#include +#include +#include #include #include -#include -#include +#include +#include #include -#include #include -#include +#include +#include -#include -#include -#include -#include #include +#include +#include +#include +#include #include -#include +#include +#include +#include #include #include -#include +#include #include -#include -#include -#include +#include +#include "onvm_flow_table.h" #include "onvm_nflib.h" #include "onvm_pkt_helper.h" -#include "onvm_flow_table.h" #define NF_TAG "load_balancer" #define TABLE_SIZE 65536 @@ -93,10 +93,10 @@ struct loadbalance { uint8_t server_port; uint8_t client_port; - /* config file, interface names */ - char * cfg_filename; - char * client_iface_name; - char * server_iface_name; + /* config file, interface names */ + char *cfg_filename; + char *client_iface_name; + char *server_iface_name; }; /* Struct for backend servers */ @@ -129,7 +129,10 @@ extern struct port_info *ports; static void usage(const char *progname) { printf("Usage:\n"); - printf("%s [EAL args] -- [NF_LIB args] -- [ -c client_iface] [-s server_iface] [-f server_config] -p \n", progname); + printf( + "%s [EAL args] -- [NF_LIB args] -- [ -c client_iface] [-s server_iface] [-f server_config] -p " + "\n", + progname); printf("%s -F [EAL args] -- [NF_LIB args] -- [NF args]\n\n", progname); printf("Flags:\n"); printf(" - `-c CLIENT_IFACE` : name of the client interface\n"); @@ -144,61 +147,62 @@ usage(const char *progname) { static int parse_app_args(int argc, char *argv[], const char *progname) { int c; - + lb->cfg_filename = NULL; lb->client_iface_name = NULL; lb->server_iface_name = NULL; while ((c = getopt(argc, argv, "c:s:f:p:")) != -1) { switch (c) { - case 'c': - lb->client_iface_name = strdup(optarg); - break; - case 's': - lb->server_iface_name = strdup(optarg); - break; - case 'f': - lb->cfg_filename = strdup(optarg); - break; - case 'p': - print_delay = strtoul(optarg, NULL, 10); - break; - case '?': - usage(progname); - if (optopt == 'd') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (optopt == 'p') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (isprint(optopt)) - RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); - else - RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); - return -1; - default: - usage(progname); - return -1; + case 'c': + lb->client_iface_name = strdup(optarg); + break; + case 's': + lb->server_iface_name = strdup(optarg); + break; + case 'f': + lb->cfg_filename = strdup(optarg); + break; + case 'p': + print_delay = strtoul(optarg, NULL, 10); + break; + case '?': + usage(progname); + if (optopt == 'd') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (optopt == 'p') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (isprint(optopt)) + RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); + else + RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); + return -1; + default: + usage(progname); + return -1; } } if (!lb->cfg_filename) { RTE_LOG(INFO, APP, "Load balancer NF requires a backend server config file.\n"); return -1; - - if (!lb->client_iface_name) { - RTE_LOG(INFO, APP, "Load balancer NF requires a client interface name.\n"); - return -1; + + if (!lb->client_iface_name) { + RTE_LOG(INFO, APP, "Load balancer NF requires a client interface name.\n"); + return -1; + } + if (!lb->server_iface_name) { + RTE_LOG(INFO, APP, "Load balancer NF requires a backend server interface name.\n"); + return -1; + } } - if (!lb->server_iface_name) { - RTE_LOG(INFO, APP, "Load balancer NF requires a backend server interface name.\n"); - return -1; - } } return optind; } /* - * This function parses the backend config. It takes the filename - * and fills up the backend_server array. This includes the mac and ip + * This function parses the backend config. It takes the filename + * and fills up the backend_server array. This includes the mac and ip * address of the backend servers */ static int @@ -206,9 +210,9 @@ parse_backend_config(void) { int ret, temp, i; char ip[32]; char mac[32]; - FILE * cfg; + FILE *cfg; - cfg = fopen(lb->cfg_filename, "r"); + cfg = fopen(lb->cfg_filename, "r"); if (cfg == NULL) { rte_exit(EXIT_FAILURE, "Error openning server \'%s\' config\n", lb->cfg_filename); } @@ -218,7 +222,8 @@ parse_backend_config(void) { } lb->server_count = temp; - lb->server = (struct backend_server *)rte_malloc("backend server info", sizeof(struct backend_server) * lb->server_count, 0); + lb->server = (struct backend_server *)rte_malloc("backend server info", + sizeof(struct backend_server) * lb->server_count, 0); if (lb->server == NULL) { rte_exit(EXIT_FAILURE, "Malloc failed, can't allocate server information\n"); } @@ -234,7 +239,7 @@ parse_backend_config(void) { rte_exit(EXIT_FAILURE, "Error parsing config IP address #%d\n", i); } - ret =onvm_pkt_parse_mac(mac, lb->server[i].d_addr_bytes); + ret = onvm_pkt_parse_mac(mac, lb->server[i].d_addr_bytes); if (ret < 0) { rte_exit(EXIT_FAILURE, "Error parsing config MAC address #%d\n", i); } @@ -243,12 +248,12 @@ parse_backend_config(void) { fclose(cfg); printf("\nARP config:\n"); for (i = 0; i < lb->server_count; i++) { - printf("%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 " ", - lb->server[i].d_ip & 0xFF, (lb->server[i].d_ip >> 8) & 0xFF, (lb->server[i].d_ip >> 16) & 0xFF, (lb->server[i].d_ip >> 24) & 0xFF); - printf("%02x:%02x:%02x:%02x:%02x:%02x\n", - lb->server[i].d_addr_bytes[0], lb->server[i].d_addr_bytes[1], - lb->server[i].d_addr_bytes[2], lb->server[i].d_addr_bytes[3], - lb->server[i].d_addr_bytes[4], lb->server[i].d_addr_bytes[5]); + printf("%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 " ", lb->server[i].d_ip & 0xFF, + (lb->server[i].d_ip >> 8) & 0xFF, (lb->server[i].d_ip >> 16) & 0xFF, + (lb->server[i].d_ip >> 24) & 0xFF); + printf("%02x:%02x:%02x:%02x:%02x:%02x\n", lb->server[i].d_addr_bytes[0], lb->server[i].d_addr_bytes[1], + lb->server[i].d_addr_bytes[2], lb->server[i].d_addr_bytes[3], lb->server[i].d_addr_bytes[4], + lb->server[i].d_addr_bytes[5]); } return ret; @@ -261,11 +266,11 @@ parse_backend_config(void) { * than one lcore enabled. */ static void -do_stats_display(struct rte_mbuf* pkt) { - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; +do_stats_display(struct rte_mbuf *pkt) { + const char clr[] = {27, '[', '2', 'J', '\0'}; + const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'}; static uint64_t pkt_process = 0; - struct ipv4_hdr* ip; + struct ipv4_hdr *ip; pkt_process += print_delay; @@ -276,7 +281,7 @@ do_stats_display(struct rte_mbuf* pkt) { printf("-----\n"); printf("Port : %d\n", pkt->port); printf("Size : %d\n", pkt->pkt_len); - printf("N° : %"PRIu64"\n", pkt_process); + printf("N° : %" PRIu64 "\n", pkt_process); printf("\n\n"); ip = onvm_pkt_ipv4_hdr(pkt); @@ -291,14 +296,12 @@ do_stats_display(struct rte_mbuf* pkt) { * Print flow information */ static void -print_flow_info(struct flow_info* f) { +print_flow_info(struct flow_info *f) { printf("Flow INFO\n"); printf("Destination server: %d\n", f->dest); - printf("Source mac %02x:%02x:%02x:%02x:%02x:%02x\n", - f->s_addr_bytes[0], f->s_addr_bytes[1], - f->s_addr_bytes[2], f->s_addr_bytes[3], - f->s_addr_bytes[4], f->s_addr_bytes[5]); -} + printf("Source mac %02x:%02x:%02x:%02x:%02x:%02x\n", f->s_addr_bytes[0], f->s_addr_bytes[1], f->s_addr_bytes[2], + f->s_addr_bytes[3], f->s_addr_bytes[4], f->s_addr_bytes[5]); +} /* * Parse and assign load balancer server/client interface information @@ -314,20 +317,20 @@ get_iface_inf(void) { ifr.ifr_addr.sa_family = AF_INET; /* Parse server interface */ - strncpy(ifr.ifr_name, lb->server_iface_name, IFNAMSIZ-1); + strncpy(ifr.ifr_name, lb->server_iface_name, IFNAMSIZ - 1); ioctl(fd, SIOCGIFADDR, &ifr); - lb->ip_lb_server = *(uint32_t *)(&((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr); + lb->ip_lb_server = *(uint32_t *)(&((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr); ioctl(fd, SIOCGIFHWADDR, &ifr); for (i = 0; i < ETHER_ADDR_LEN; i++) server_addr_bytes[i] = ifr.ifr_hwaddr.sa_data[i]; /* Parse client interface */ - strncpy(ifr.ifr_name, lb->client_iface_name, IFNAMSIZ-1); + strncpy(ifr.ifr_name, lb->client_iface_name, IFNAMSIZ - 1); ioctl(fd, SIOCGIFADDR, &ifr); - lb->ip_lb_client = *(uint32_t *)(&((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr); + lb->ip_lb_client = *(uint32_t *)(&((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr); ioctl(fd, SIOCGIFHWADDR, &ifr); for (i = 0; i < ETHER_ADDR_LEN; i++) @@ -346,19 +349,15 @@ get_iface_inf(void) { printf("\nLoad balancer interfaces:\n"); printf("Client iface \'%s\' ID: %d, IP: %" PRIu32 " (%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 "), ", - lb->client_iface_name, lb->client_port, lb->ip_lb_client, - lb->ip_lb_client & 0xFF, (lb->ip_lb_client >> 8) & 0xFF, (lb->ip_lb_client >> 16) & 0xFF, (lb->ip_lb_client >> 24) & 0xFF); - printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", - client_addr_bytes[0], client_addr_bytes[1], - client_addr_bytes[2], client_addr_bytes[3], - client_addr_bytes[4], client_addr_bytes[5]); + lb->client_iface_name, lb->client_port, lb->ip_lb_client, lb->ip_lb_client & 0xFF, + (lb->ip_lb_client >> 8) & 0xFF, (lb->ip_lb_client >> 16) & 0xFF, (lb->ip_lb_client >> 24) & 0xFF); + printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", client_addr_bytes[0], client_addr_bytes[1], client_addr_bytes[2], + client_addr_bytes[3], client_addr_bytes[4], client_addr_bytes[5]); printf("Server iface \'%s\' ID: %d, IP: %" PRIu32 " (%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 "), ", - lb->server_iface_name, lb->server_port, lb->ip_lb_server, - lb->ip_lb_server & 0xFF, (lb->ip_lb_server >> 8) & 0xFF, (lb->ip_lb_server >> 16) & 0xFF, (lb->ip_lb_server >> 24) & 0xFF); - printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", - server_addr_bytes[0], server_addr_bytes[1], - server_addr_bytes[2], server_addr_bytes[3], - server_addr_bytes[4], server_addr_bytes[5]); + lb->server_iface_name, lb->server_port, lb->ip_lb_server, lb->ip_lb_server & 0xFF, + (lb->ip_lb_server >> 8) & 0xFF, (lb->ip_lb_server >> 16) & 0xFF, (lb->ip_lb_server >> 24) & 0xFF); + printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", server_addr_bytes[0], server_addr_bytes[1], server_addr_bytes[2], + server_addr_bytes[3], server_addr_bytes[4], server_addr_bytes[5]); } /* @@ -416,7 +415,7 @@ clear_entries(void) { * if so, it calls clear_entries() to free up space. */ static int -table_add_entry(struct onvm_ft_ipv4_5tuple* key, struct flow_info **flow) { +table_add_entry(struct onvm_ft_ipv4_5tuple *key, struct flow_info **flow) { struct flow_info *data = NULL; if (unlikely(key == NULL || lb == NULL)) { @@ -439,7 +438,7 @@ table_add_entry(struct onvm_ft_ipv4_5tuple* key, struct flow_info **flow) { data->dest = lb->num_stored % lb->server_count; data->last_pkt_cycles = lb->elapsed_cycles; data->is_active = 0; - + *flow = data; return 0; @@ -451,14 +450,14 @@ table_add_entry(struct onvm_ft_ipv4_5tuple* key, struct flow_info **flow) { * and if it doesn't, it calls table_add_entry() to add it to the table. */ static int -table_lookup_entry(struct rte_mbuf* pkt, struct flow_info **flow) { +table_lookup_entry(struct rte_mbuf *pkt, struct flow_info **flow) { struct flow_info *data = NULL; struct onvm_ft_ipv4_5tuple key; if (unlikely(pkt == NULL || lb == NULL || flow == NULL)) { return -1; } - + int ret = onvm_ft_fill_key_symmetric(&key, pkt); if (ret < 0) return -1; @@ -490,7 +489,7 @@ callback_handler(__attribute__((unused)) struct onvm_nf_info *nf_info) { static int packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__((unused)) struct onvm_nf_info *nf_info) { static uint32_t counter = 0; - struct ipv4_hdr* ip; + struct ipv4_hdr *ip; struct ether_hdr *ehdr; struct flow_info *flow_info; int i, ret; @@ -564,10 +563,11 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( return 0; } -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; - + if ((arg_offset = onvm_nflib_init(argc, argv, NF_TAG, &nf_info)) < 0) return -1; argc -= arg_offset; diff --git a/examples/load_generator/load_generator.c b/examples/load_generator/load_generator.c index cdf5e95d1..5fba40439 100644 --- a/examples/load_generator/load_generator.c +++ b/examples/load_generator/load_generator.c @@ -38,31 +38,31 @@ * load_generator.c - send pkts at defined rate and measure received pkts. ********************************************************************/ -#include -#include -#include -#include +#include +#include #include +#include +#include #include -#include -#include +#include +#include #include -#include #include -#include +#include +#include #include -#include -#include -#include #include -#include #include #include +#include +#include +#include +#include +#include "onvm_flow_table.h" #include "onvm_nflib.h" #include "onvm_pkt_helper.h" -#include "onvm_flow_table.h" #define LOCAL_EXPERIMENTAL_ETHER 0x88B5 #define NF_TAG "load_generator" @@ -100,7 +100,8 @@ static uint8_t action_out = 0; static struct ether_hdr *ehdr; /* Sets up variables for the load generator */ -void nf_setup(struct onvm_nf_info *nf_info); +void +nf_setup(struct onvm_nf_info *nf_info); /* * Print a usage message @@ -108,14 +109,23 @@ void nf_setup(struct onvm_nf_info *nf_info); static void usage(const char *progname) { printf("Usage:\n"); - printf("%s [EAL args] -- [NF_LIB args] -- -d [-m ] " - "[-p ] [-s ] [-t ] [-o]\n\n", progname); + printf( + "%s [EAL args] -- [NF_LIB args] -- -d [-m ] " + "[-p ] [-s ] [-t ] [-o]\n\n", + progname); printf("%s -F [EAL args] -- [NF_LIB args] -- [NF args]\n\n", progname); printf("Flags:\n"); printf(" - `-d DST`: destination service ID to foward to, or dst port if `-o` is used.\n"); - printf(" - `-p `: number of seconds between each print (e.g. `-p 0.1` prints every 0.1 seconds).\n"); - printf(" - `-t `: the desired transmission rate for the packets (e.g. `-t 3000000 transmits 3 million packets per second). Note that the actual transmission rate may be limited based on system performance and NF configuration. If the load generator is experiencing high levels of dropped packets either transmitting or receiving, lowering the transmission rate could solve this.\n"); - printf(" - `-m `: user specified destination MAC address (e.g. `-m aa:bb:cc:dd:ee:ff` sets the destination address within the ethernet header that is located at the start of the packet data).\n"); + printf( + " - `-p `: number of seconds between each print (e.g. `-p 0.1` prints every 0.1 seconds).\n"); + printf( + " - `-t `: the desired transmission rate for the packets (e.g. `-t 3000000 transmits 3 " + "million packets per second). Note that the actual transmission rate may be limited based on system " + "performance and NF configuration. If the load generator is experiencing high levels of dropped packets " + "either transmitting or receiving, lowering the transmission rate could solve this.\n"); + printf( + " - `-m `: user specified destination MAC address (e.g. `-m aa:bb:cc:dd:ee:ff` sets the " + "destination address within the ethernet header that is located at the start of the packet data).\n"); printf(" - `-s `: the desired size of the generated packets in bytes.\n"); printf(" - `-o`: send the packets out the NIC port.\n"); } @@ -141,17 +151,11 @@ parse_app_args(int argc, char *argv[], const char *progname) { packet_rate = strtoul(optarg, NULL, 10); break; case 'm': - count = sscanf(optarg, - "%x:%x:%x:%x:%x:%x", - &values[0], - &values[1], - &values[2], - &values[3], - &values[4], - &values[5]); + count = sscanf(optarg, "%x:%x:%x:%x:%x:%x", &values[0], &values[1], &values[2], + &values[3], &values[4], &values[5]); if (count == ETHER_ADDR_LEN) { for (i = 0; i < ETHER_ADDR_LEN; ++i) { - d_addr_bytes[i] = (uint8_t) values[i]; + d_addr_bytes[i] = (uint8_t)values[i]; } } else { usage(progname); @@ -163,7 +167,8 @@ parse_app_args(int argc, char *argv[], const char *progname) { if (packet_size >= ETHER_HDR_LEN) { break; } else { - RTE_LOG(INFO, APP, "Load generator NF requires a packet size of at least 14.\n"); + RTE_LOG(INFO, APP, + "Load generator NF requires a packet size of at least 14.\n"); return -1; } case 'o': @@ -185,12 +190,12 @@ parse_app_args(int argc, char *argv[], const char *progname) { static void do_stats_display(void) { - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; + const char clr[] = {27, '[', '2', 'J', '\0'}; + const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'}; uint64_t cur_cycle = rte_get_tsc_cycles(); double time_elapsed = (cur_cycle - start_cycle) / (double)rte_get_timer_hz(); - double time_since_update = (cur_cycle - last_update_cycle) / (double) rte_get_timer_hz(); + double time_since_update = (cur_cycle - last_update_cycle) / (double)rte_get_timer_hz(); double tx_rate_average = packets_sent / time_elapsed; double tx_rate_current = packets_sent_since_update / time_since_update; @@ -198,7 +203,8 @@ do_stats_display(void) { double rx_rate_average = packets_received / time_elapsed; double rx_rate_current = packets_received_since_update / time_since_update; - double latency_current_mean = total_latency_since_update / (double)packets_received_since_update / (double) (rte_get_timer_hz() / 1000000); + double latency_current_mean = + total_latency_since_update / (double)packets_received_since_update / (double)(rte_get_timer_hz() / 1000000); last_update_cycle = cur_cycle; packets_sent_since_update = 0; @@ -211,14 +217,14 @@ do_stats_display(void) { printf("Time elapsed: %.2f\n", time_elapsed); printf("\n"); - printf("Tx total packets: %"PRIu64"\n", packets_sent); - printf("Tx packets sent this iteration: %"PRIu32"\n", batch_size); - printf("Tx rate (set): %"PRIu64"\n", packet_rate); + printf("Tx total packets: %" PRIu64 "\n", packets_sent); + printf("Tx packets sent this iteration: %" PRIu32 "\n", batch_size); + printf("Tx rate (set): %" PRIu64 "\n", packet_rate); printf("Tx rate (average): %.2f\n", tx_rate_average); printf("Tx rate (current): %.2f\n", tx_rate_current); printf("\n"); - printf("Rx total packets: %"PRIu64" \n", packets_received); + printf("Rx total packets: %" PRIu64 " \n", packets_received); printf("Rx rate (average): %.2f\n", rx_rate_average); printf("Rx rate (current): %.2f\n", rx_rate_current); printf("Latency (current mean): %.2f us\n", latency_current_mean); @@ -228,7 +234,7 @@ do_stats_display(void) { static int packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__((unused)) struct onvm_nf_info *nf_info) { - uint64_t* timestamp; + uint64_t *timestamp; if (!ONVM_CHECK_BIT(meta->flags, LOAD_GEN_BIT)) { meta->action = ONVM_NF_ACTION_DROP; @@ -254,12 +260,12 @@ callback_handler(__attribute__((unused)) struct onvm_nf_info *nf_info) { last_cycle = cur_cycle; if (packets_to_send >= 1) { - batch_size = (packets_to_send <= BATCH_LIMIT) ? (int) packets_to_send : BATCH_LIMIT; + batch_size = (packets_to_send <= BATCH_LIMIT) ? (int)packets_to_send : BATCH_LIMIT; struct rte_mbuf *pkts[batch_size]; for (i = 0; i < batch_size; i++) { struct ether_hdr *pkt_ehdr; struct rte_mbuf *pkt = rte_pktmbuf_alloc(pktmbuf_pool); - uint64_t* timestamp; + uint64_t *timestamp; if (pkt == NULL) { printf("Failed to allocate packets\n"); @@ -267,10 +273,10 @@ callback_handler(__attribute__((unused)) struct onvm_nf_info *nf_info) { } /* Append and copy ether header */ - pkt_ehdr = (struct ether_hdr *) rte_pktmbuf_append(pkt, packet_size); + pkt_ehdr = (struct ether_hdr *)rte_pktmbuf_append(pkt, packet_size); rte_memcpy(pkt_ehdr, ehdr, sizeof(struct ether_hdr)); - struct onvm_pkt_meta* pmeta = onvm_get_pkt_meta(pkt); + struct onvm_pkt_meta *pmeta = onvm_get_pkt_meta(pkt); pmeta->destination = destination; pmeta->flags |= ONVM_SET_BIT(0, LOAD_GEN_BIT); if (action_out) { @@ -280,7 +286,7 @@ callback_handler(__attribute__((unused)) struct onvm_nf_info *nf_info) { } /* Add data to measure latency */ - timestamp = (uint64_t *) rte_pktmbuf_append(pkt, sizeof(uint64_t)); + timestamp = (uint64_t *)rte_pktmbuf_append(pkt, sizeof(uint64_t)); *timestamp = rte_get_tsc_cycles(); pkts[i] = pkt; @@ -301,7 +307,6 @@ callback_handler(__attribute__((unused)) struct onvm_nf_info *nf_info) { return 0; } - /* * Sets up load generator values */ @@ -319,7 +324,7 @@ nf_setup(struct onvm_nf_info *nf_info) { rte_exit(EXIT_FAILURE, "Cannot find mbuf pool!\n"); } - ehdr = (struct ether_hdr *) malloc(sizeof(struct ether_hdr)); + ehdr = (struct ether_hdr *)malloc(sizeof(struct ether_hdr)); if (ehdr == NULL) { rte_exit(EXIT_FAILURE, "Failed to allocate common ehdr\n"); } @@ -331,7 +336,8 @@ nf_setup(struct onvm_nf_info *nf_info) { ehdr->ether_type = rte_cpu_to_be_16(LOCAL_EXPERIMENTAL_ETHER); } -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; diff --git a/examples/ndpi_stats/ndpi_stats.c b/examples/ndpi_stats/ndpi_stats.c index 272d73435..35886d7a9 100644 --- a/examples/ndpi_stats/ndpi_stats.c +++ b/examples/ndpi_stats/ndpi_stats.c @@ -38,20 +38,20 @@ * ndpi_stats.c - an example using onvm, nDPI. Inspect packets using nDPI ********************************************************************/ -#include -#include -#include +#include +#include #include #include -#include -#include +#include +#include #include -#include #include +#include +#include #include -#include #include +#include #include #include "ndpi_main.h" @@ -70,15 +70,15 @@ struct onvm_nf_info *nf_info; extern struct port_info *ports; /* user defined settings */ -static uint32_t destination = (uint16_t) -1; +static uint32_t destination = (uint16_t)-1; /* pcap stucts */ -const uint16_t MAX_SNAPLEN = (uint16_t) -1; +const uint16_t MAX_SNAPLEN = (uint16_t)-1; pcap_t *pd; /* nDPI structs */ -struct ndpi_detection_module_struct * module; -struct ndpi_workflow * workflow; +struct ndpi_detection_module_struct *module; +struct ndpi_workflow *workflow; uint32_t current_ndpi_memory = 0, max_ndpi_memory = 0; static u_int8_t quiet_mode = 0; static u_int16_t decode_tunnels = 0; @@ -86,65 +86,69 @@ static FILE *results_file = NULL; static struct timeval begin, end; /* nDPI methods */ -void setup_ndpi(void); -char* formatTraffic(float numBits, int bits, char *buf); -char* formatPackets(float numPkts, char *buf); -static void node_proto_guess_walker(const void *node, ndpi_VISIT which, int depth, void *user_data); -static void print_results(void); +void +setup_ndpi(void); +char * +formatTraffic(float numBits, int bits, char *buf); +char * +formatPackets(float numPkts, char *buf); +static void +node_proto_guess_walker(const void *node, ndpi_VISIT which, int depth, void *user_data); +static void +print_results(void); /** * Source https://github.com/ntop/nDPI ndpiReader.c * @brief Traffic stats format */ -char* formatTraffic(float numBits, int bits, char *buf) { - - char unit; - - if(bits) - unit = 'b'; - else - unit = 'B'; - - if(numBits < 1024) { - snprintf(buf, 32, "%lu %c", (unsigned long)numBits, unit); - } else if(numBits < (1024*1024)) { - snprintf(buf, 32, "%.2f K%c", (float)(numBits)/1024, unit); - } else { - float tmpMBits = ((float)numBits)/(1024*1024); - - if(tmpMBits < 1024) { - snprintf(buf, 32, "%.2f M%c", tmpMBits, unit); - } else { - tmpMBits /= 1024; - - if(tmpMBits < 1024) { - snprintf(buf, 32, "%.2f G%c", tmpMBits, unit); - } else { - snprintf(buf, 32, "%.2f T%c", (float)(tmpMBits)/1024, unit); - } - } - } - - return(buf); -} +char * +formatTraffic(float numBits, int bits, char *buf) { + char unit; + + if (bits) + unit = 'b'; + else + unit = 'B'; + + if (numBits < 1024) { + snprintf(buf, 32, "%lu %c", (unsigned long)numBits, unit); + } else if (numBits < (1024 * 1024)) { + snprintf(buf, 32, "%.2f K%c", (float)(numBits) / 1024, unit); + } else { + float tmpMBits = ((float)numBits) / (1024 * 1024); + + if (tmpMBits < 1024) { + snprintf(buf, 32, "%.2f M%c", tmpMBits, unit); + } else { + tmpMBits /= 1024; + + if (tmpMBits < 1024) { + snprintf(buf, 32, "%.2f G%c", tmpMBits, unit); + } else { + snprintf(buf, 32, "%.2f T%c", (float)(tmpMBits) / 1024, unit); + } + } + } + return (buf); +} /** * Source https://github.com/ntop/nDPI ndpiReader.c * @brief Packets stats format */ -char* formatPackets(float numPkts, char *buf) { - - if(numPkts < 1000) { - snprintf(buf, 32, "%.2f", numPkts); - } else if(numPkts < (1000*1000)) { - snprintf(buf, 32, "%.2f K", numPkts/1000); - } else { - numPkts /= (1000*1000); - snprintf(buf, 32, "%.2f M", numPkts); - } - - return(buf); +char * +formatPackets(float numPkts, char *buf) { + if (numPkts < 1000) { + snprintf(buf, 32, "%.2f", numPkts); + } else if (numPkts < (1000 * 1000)) { + snprintf(buf, 32, "%.2f K", numPkts / 1000); + } else { + numPkts /= (1000 * 1000); + snprintf(buf, 32, "%.2f M", numPkts); + } + + return (buf); } /* @@ -167,7 +171,7 @@ static int parse_app_args(int argc, char *argv[], const char *progname) { int c; - while ((c = getopt (argc, argv, "d:w:")) != -1) { + while ((c = getopt(argc, argv, "d:w:")) != -1) { switch (c) { case 'w': results_file = fopen(strdup(optarg), "w"); @@ -198,7 +202,7 @@ parse_app_args(int argc, char *argv[], const char *progname) { return optind; } -void +void setup_ndpi(void) { pd = pcap_open_dead(DLT_EN10MB, MAX_SNAPLEN); @@ -225,20 +229,22 @@ setup_ndpi(void) { * Source https://github.com/ntop/nDPI ndpiReader.c * Modified for single workflow */ -static void +static void node_proto_guess_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) { - struct ndpi_flow_info *flow = *(struct ndpi_flow_info **) node; - u_int16_t thread_id = *((u_int16_t *) user_data); - - if((which == ndpi_preorder) || (which == ndpi_leaf)) { /* Avoid walking the same node multiple times */ - if((!flow->detection_completed) && flow->ndpi_flow) - flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, flow->ndpi_flow); - - process_ndpi_collected_info(workflow, flow); - workflow->stats.protocol_counter[flow->detected_protocol.app_protocol] += flow->src2dst_packets + flow->dst2src_packets; - workflow->stats.protocol_counter_bytes[flow->detected_protocol.app_protocol] += flow->src2dst_bytes + flow->dst2src_bytes; - workflow->stats.protocol_flows[flow->detected_protocol.app_protocol]++; - } + struct ndpi_flow_info *flow = *(struct ndpi_flow_info **)node; + u_int16_t thread_id = *((u_int16_t *)user_data); + + if ((which == ndpi_preorder) || (which == ndpi_leaf)) { /* Avoid walking the same node multiple times */ + if ((!flow->detection_completed) && flow->ndpi_flow) + flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, flow->ndpi_flow); + + process_ndpi_collected_info(workflow, flow); + workflow->stats.protocol_counter[flow->detected_protocol.app_protocol] += + flow->src2dst_packets + flow->dst2src_packets; + workflow->stats.protocol_counter_bytes[flow->detected_protocol.app_protocol] += + flow->src2dst_bytes + flow->dst2src_bytes; + workflow->stats.protocol_flows[flow->detected_protocol.app_protocol]++; + } } /* @@ -251,27 +257,27 @@ print_results(void) { u_int32_t avg_pkt_size = 0; u_int64_t tot_usec; - if(workflow->stats.total_wire_bytes == 0) return; + if (workflow->stats.total_wire_bytes == 0) + return; - for(i=0; indpi_flows_root[i], node_proto_guess_walker, 0); } - tot_usec = end.tv_sec*1000000 + end.tv_usec - (begin.tv_sec*1000000 + begin.tv_usec); + tot_usec = end.tv_sec * 1000000 + end.tv_usec - (begin.tv_sec * 1000000 + begin.tv_usec); printf("\nTraffic statistics:\n"); printf("\tEthernet bytes: %-13llu (includes ethernet CRC/IFC/trailer)\n", - (long long unsigned int)workflow->stats.total_wire_bytes); - printf("\tDiscarded bytes: %-13llu\n", - (long long unsigned int)workflow->stats.total_discarded_bytes); + (long long unsigned int)workflow->stats.total_wire_bytes); + printf("\tDiscarded bytes: %-13llu\n", (long long unsigned int)workflow->stats.total_discarded_bytes); printf("\tIP packets: %-13llu of %llu packets total\n", - (long long unsigned int)workflow->stats.ip_packet_count, - (long long unsigned int)workflow->stats.raw_packet_count); + (long long unsigned int)workflow->stats.ip_packet_count, + (long long unsigned int)workflow->stats.raw_packet_count); /* In order to prevent Floating point exception in case of no traffic*/ - if(workflow->stats.total_ip_bytes && workflow->stats.raw_packet_count) - avg_pkt_size = (unsigned int)(workflow->stats.total_ip_bytes/workflow->stats.raw_packet_count); + if (workflow->stats.total_ip_bytes && workflow->stats.raw_packet_count) + avg_pkt_size = (unsigned int)(workflow->stats.total_ip_bytes / workflow->stats.raw_packet_count); printf("\tIP bytes: %-13llu (avg pkt size %u bytes)\n", - (long long unsigned int)workflow->stats.total_ip_bytes,avg_pkt_size); + (long long unsigned int)workflow->stats.total_ip_bytes, avg_pkt_size); printf("\tUnique flows: %-13u\n", workflow->stats.ndpi_flow_count); printf("\tTCP Packets: %-13lu\n", (unsigned long)workflow->stats.tcp_count); @@ -280,7 +286,7 @@ print_results(void) { printf("\tMPLS Packets: %-13lu\n", (unsigned long)workflow->stats.mpls_count); printf("\tPPPoE Packets: %-13lu\n", (unsigned long)workflow->stats.pppoe_count); printf("\tFragmented Packets: %-13lu\n", (unsigned long)workflow->stats.fragmented_count); - printf("\tMax Packet size: %-13u\n", workflow->stats.max_packet_len); + printf("\tMax Packet size: %-13u\n", workflow->stats.max_packet_len); printf("\tPacket Len < 64: %-13lu\n", (unsigned long)workflow->stats.packet_len[0]); printf("\tPacket Len 64-128: %-13lu\n", (unsigned long)workflow->stats.packet_len[1]); printf("\tPacket Len 128-256: %-13lu\n", (unsigned long)workflow->stats.packet_len[2]); @@ -288,39 +294,40 @@ print_results(void) { printf("\tPacket Len 1024-1500: %-13lu\n", (unsigned long)workflow->stats.packet_len[4]); printf("\tPacket Len > 1500: %-13lu\n", (unsigned long)workflow->stats.packet_len[5]); - if(tot_usec > 0) { + if (tot_usec > 0) { char buf[32], buf1[32], when[64]; - float t = (float)(workflow->stats.ip_packet_count*1000000)/(float)tot_usec; - float b = (float)(workflow->stats.total_wire_bytes * 8 *1000000)/(float)tot_usec; + float t = (float)(workflow->stats.ip_packet_count * 1000000) / (float)tot_usec; + float b = (float)(workflow->stats.total_wire_bytes * 8 * 1000000) / (float)tot_usec; float traffic_duration; /* This currently assumes traffic starts to flow instantly */ traffic_duration = tot_usec; printf("\tnDPI throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); - t = (float)(workflow->stats.ip_packet_count*1000000)/(float)traffic_duration; - b = (float)(workflow->stats.total_wire_bytes * 8 *1000000)/(float)traffic_duration; + t = (float)(workflow->stats.ip_packet_count * 1000000) / (float)traffic_duration; + b = (float)(workflow->stats.total_wire_bytes * 8 * 1000000) / (float)traffic_duration; strftime(when, sizeof(when), "%d/%b/%Y %H:%M:%S", localtime(&begin.tv_sec)); printf("\tAnalysis begin: %s\n", when); strftime(when, sizeof(when), "%d/%b/%Y %H:%M:%S", localtime(&end.tv_sec)); printf("\tAnalysis end: %s\n", when); printf("\tTraffic throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); - printf("\tTraffic duration: %.3f sec\n", traffic_duration/1000000); + printf("\tTraffic duration: %.3f sec\n", traffic_duration / 1000000); } for (i = 0; i <= ndpi_get_num_supported_protocols(workflow->ndpi_struct); i++) { if (workflow->stats.protocol_counter[i] > 0) { if (results_file) fprintf(results_file, "%s\t%llu\t%llu\t%u\n", - ndpi_get_proto_name(workflow->ndpi_struct, i), - (long long unsigned int)workflow->stats.protocol_counter[i], - (long long unsigned int)workflow->stats.protocol_counter_bytes[i], - workflow->stats.protocol_flows[i]); - printf("\t%-20s packets: %-13llu bytes: %-13llu " - "flows: %-13u\n", - ndpi_get_proto_name(workflow->ndpi_struct, i), - (long long unsigned int)workflow->stats.protocol_counter[i], - (long long unsigned int)workflow->stats.protocol_counter_bytes[i], - workflow->stats.protocol_flows[i]); + ndpi_get_proto_name(workflow->ndpi_struct, i), + (long long unsigned int)workflow->stats.protocol_counter[i], + (long long unsigned int)workflow->stats.protocol_counter_bytes[i], + workflow->stats.protocol_flows[i]); + printf( + "\t%-20s packets: %-13llu bytes: %-13llu " + "flows: %-13u\n", + ndpi_get_proto_name(workflow->ndpi_struct, i), + (long long unsigned int)workflow->stats.protocol_counter[i], + (long long unsigned int)workflow->stats.protocol_counter_bytes[i], + workflow->stats.protocol_flows[i]); } } } @@ -337,13 +344,13 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( pkt_hdr.ts = time; pkt_hdr.caplen = rte_pktmbuf_data_len(pkt); pkt_hdr.len = rte_pktmbuf_data_len(pkt); - packet = rte_pktmbuf_mtod(pkt, u_char * ); + packet = rte_pktmbuf_mtod(pkt, u_char *); - prot = ndpi_workflow_process_packet(workflow, &pkt_hdr, packet); + prot = ndpi_workflow_process_packet(workflow, &pkt_hdr, packet); workflow->stats.protocol_counter[prot.app_protocol]++; workflow->stats.protocol_counter_bytes[prot.app_protocol] += pkt_hdr.len; - if (destination != (uint16_t) -1) { + if (destination != (uint16_t)-1) { meta->action = ONVM_NF_ACTION_TONF; meta->destination = destination; } else { @@ -358,7 +365,8 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( return 0; } -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; diff --git a/examples/ndpi_stats/ndpi_util.c b/examples/ndpi_stats/ndpi_util.c index bd0f51ba8..3886f52dd 100644 --- a/examples/ndpi_stats/ndpi_util.c +++ b/examples/ndpi_stats/ndpi_util.c @@ -24,47 +24,47 @@ #include #ifdef WIN32 -#include /* winsock.h is included automatically */ -#include #include +#include +#include /* winsock.h is included automatically */ #else -#include #include +#include #endif #ifndef ETH_P_IP -#define ETH_P_IP 0x0800 /* IPv4 */ +#define ETH_P_IP 0x0800 /* IPv4 */ #endif #ifndef ETH_P_IPv6 -#define ETH_P_IPV6 0x86dd /* IPv6 */ +#define ETH_P_IPV6 0x86dd /* IPv6 */ #endif -#define SLARP 0x8035 /* Cisco Slarp */ -#define CISCO_D_PROTO 0x2000 /* Cisco Discovery Protocol */ +#define SLARP 0x8035 /* Cisco Slarp */ +#define CISCO_D_PROTO 0x2000 /* Cisco Discovery Protocol */ -#define VLAN 0x8100 -#define MPLS_UNI 0x8847 -#define MPLS_MULTI 0x8848 -#define PPPoE 0x8864 -#define SNAP 0xaa -#define BSTP 0x42 /* Bridge Spanning Tree Protocol */ +#define VLAN 0x8100 +#define MPLS_UNI 0x8847 +#define MPLS_MULTI 0x8848 +#define PPPoE 0x8864 +#define SNAP 0xaa +#define BSTP 0x42 /* Bridge Spanning Tree Protocol */ /* mask for FCF */ -#define WIFI_DATA 0x2 /* 0000 0010 */ -#define FCF_TYPE(fc) (((fc) >> 2) & 0x3) /* 0000 0011 = 0x3 */ -#define FCF_SUBTYPE(fc) (((fc) >> 4) & 0xF) /* 0000 1111 = 0xF */ -#define FCF_TO_DS(fc) ((fc) & 0x0100) -#define FCF_FROM_DS(fc) ((fc) & 0x0200) +#define WIFI_DATA 0x2 /* 0000 0010 */ +#define FCF_TYPE(fc) (((fc) >> 2) & 0x3) /* 0000 0011 = 0x3 */ +#define FCF_SUBTYPE(fc) (((fc) >> 4) & 0xF) /* 0000 1111 = 0xF */ +#define FCF_TO_DS(fc) ((fc)&0x0100) +#define FCF_FROM_DS(fc) ((fc)&0x0200) /* mask for Bad FCF presence */ -#define BAD_FCS 0x50 /* 0101 0000 */ +#define BAD_FCS 0x50 /* 0101 0000 */ -#define GTP_U_V1_PORT 2152 -#define TZSP_PORT 37008 +#define GTP_U_V1_PORT 2152 +#define TZSP_PORT 37008 #ifndef DLT_LINUX_SLL -#define DLT_LINUX_SLL 113 +#define DLT_LINUX_SLL 113 #endif #include "ndpi_main.h" @@ -72,10 +72,20 @@ /* ***************************************************** */ -void ndpi_free_flow_info_half(struct ndpi_flow_info *flow) { - if(flow->ndpi_flow) { ndpi_flow_free(flow->ndpi_flow); flow->ndpi_flow = NULL; } - if(flow->src_id) { ndpi_free(flow->src_id); flow->src_id = NULL; } - if(flow->dst_id) { ndpi_free(flow->dst_id); flow->dst_id = NULL; } +void +ndpi_free_flow_info_half(struct ndpi_flow_info *flow) { + if (flow->ndpi_flow) { + ndpi_flow_free(flow->ndpi_flow); + flow->ndpi_flow = NULL; + } + if (flow->src_id) { + ndpi_free(flow->src_id); + flow->src_id = NULL; + } + if (flow->dst_id) { + ndpi_free(flow->dst_id); + flow->dst_id = NULL; + } } /* ***************************************************** */ @@ -85,13 +95,14 @@ extern u_int32_t current_ndpi_memory, max_ndpi_memory; /** * @brief malloc wrapper function */ -static void *malloc_wrapper(size_t size) { - current_ndpi_memory += size; +static void * +malloc_wrapper(size_t size) { + current_ndpi_memory += size; - if(current_ndpi_memory > max_ndpi_memory) - max_ndpi_memory = current_ndpi_memory; + if (current_ndpi_memory > max_ndpi_memory) + max_ndpi_memory = current_ndpi_memory; - return malloc(size); + return malloc(size); } /* ***************************************************** */ @@ -99,371 +110,379 @@ static void *malloc_wrapper(size_t size) { /** * @brief free wrapper function */ -static void free_wrapper(void *freeable) { - free(freeable); +static void +free_wrapper(void *freeable) { + free(freeable); } /* ***************************************************** */ -struct ndpi_workflow * ndpi_workflow_init(const struct ndpi_workflow_prefs * prefs, pcap_t * pcap_handle) { +struct ndpi_workflow * +ndpi_workflow_init(const struct ndpi_workflow_prefs *prefs, pcap_t *pcap_handle) { + set_ndpi_malloc(malloc_wrapper), set_ndpi_free(free_wrapper); + set_ndpi_flow_malloc(NULL), set_ndpi_flow_free(NULL); + /* TODO: just needed here to init ndpi malloc wrapper */ + struct ndpi_detection_module_struct *module = ndpi_init_detection_module(); - set_ndpi_malloc(malloc_wrapper), set_ndpi_free(free_wrapper); - set_ndpi_flow_malloc(NULL), set_ndpi_flow_free(NULL); - /* TODO: just needed here to init ndpi malloc wrapper */ - struct ndpi_detection_module_struct * module = ndpi_init_detection_module(); + struct ndpi_workflow *workflow = ndpi_calloc(1, sizeof(struct ndpi_workflow)); - struct ndpi_workflow * workflow = ndpi_calloc(1, sizeof(struct ndpi_workflow)); + workflow->pcap_handle = pcap_handle; + workflow->prefs = *prefs; + workflow->ndpi_struct = module; - workflow->pcap_handle = pcap_handle; - workflow->prefs = *prefs; - workflow->ndpi_struct = module; + if (workflow->ndpi_struct == NULL) { + NDPI_LOG(0, NULL, NDPI_LOG_ERROR, "global structure initialization failed\n"); + exit(-1); + } - if(workflow->ndpi_struct == NULL) { - NDPI_LOG(0, NULL, NDPI_LOG_ERROR, "global structure initialization failed\n"); - exit(-1); - } - - workflow->ndpi_flows_root = ndpi_calloc(workflow->prefs.num_roots, sizeof(void *)); - return workflow; + workflow->ndpi_flows_root = ndpi_calloc(workflow->prefs.num_roots, sizeof(void *)); + return workflow; } /* ***************************************************** */ -void ndpi_flow_info_freer(void *node) { - struct ndpi_flow_info *flow = (struct ndpi_flow_info*)node; +void +ndpi_flow_info_freer(void *node) { + struct ndpi_flow_info *flow = (struct ndpi_flow_info *)node; - ndpi_free_flow_info_half(flow); - ndpi_free(flow); + ndpi_free_flow_info_half(flow); + ndpi_free(flow); } /* ***************************************************** */ -void ndpi_workflow_free(struct ndpi_workflow * workflow) { - int i; +void +ndpi_workflow_free(struct ndpi_workflow *workflow) { + int i; - for(i=0; iprefs.num_roots; i++) - ndpi_tdestroy(workflow->ndpi_flows_root[i], ndpi_flow_info_freer); + for (i = 0; i < workflow->prefs.num_roots; i++) + ndpi_tdestroy(workflow->ndpi_flows_root[i], ndpi_flow_info_freer); - ndpi_exit_detection_module(workflow->ndpi_struct); - free(workflow->ndpi_flows_root); - free(workflow); + ndpi_exit_detection_module(workflow->ndpi_struct); + free(workflow->ndpi_flows_root); + free(workflow); } /* ***************************************************** */ -int ndpi_workflow_node_cmp(const void *a, const void *b) { - struct ndpi_flow_info *fa = (struct ndpi_flow_info*)a; - struct ndpi_flow_info *fb = (struct ndpi_flow_info*)b; - - if(fa->hashval < fb->hashval) return(-1); else if(fa->hashval > fb->hashval) return(1); - - /* Flows have the same hash */ - - if(fa->vlan_id < fb->vlan_id ) return(-1); else { if(fa->vlan_id > fb->vlan_id ) return(1); } - if(fa->protocol < fb->protocol ) return(-1); else { if(fa->protocol > fb->protocol ) return(1); } - - if( - ( - (fa->src_ip == fb->src_ip ) - && (fa->src_port == fb->src_port) - && (fa->dst_ip == fb->dst_ip ) - && (fa->dst_port == fb->dst_port) - ) - || - ( - (fa->src_ip == fb->dst_ip ) - && (fa->src_port == fb->dst_port) - && (fa->dst_ip == fb->src_ip ) - && (fa->dst_port == fb->src_port) - ) - ) - return(0); - - if(fa->src_ip < fb->src_ip ) return(-1); else { if(fa->src_ip > fb->src_ip ) return(1); } - if(fa->src_port < fb->src_port) return(-1); else { if(fa->src_port > fb->src_port) return(1); } - if(fa->dst_ip < fb->dst_ip ) return(-1); else { if(fa->dst_ip > fb->dst_ip ) return(1); } - if(fa->dst_port < fb->dst_port) return(-1); else { if(fa->dst_port > fb->dst_port) return(1); } - - return(0); /* notreached */ +int +ndpi_workflow_node_cmp(const void *a, const void *b) { + struct ndpi_flow_info *fa = (struct ndpi_flow_info *)a; + struct ndpi_flow_info *fb = (struct ndpi_flow_info *)b; + + if (fa->hashval < fb->hashval) + return (-1); + else if (fa->hashval > fb->hashval) + return (1); + + /* Flows have the same hash */ + + if (fa->vlan_id < fb->vlan_id) + return (-1); + else { + if (fa->vlan_id > fb->vlan_id) + return (1); + } + if (fa->protocol < fb->protocol) + return (-1); + else { + if (fa->protocol > fb->protocol) + return (1); + } + + if (((fa->src_ip == fb->src_ip) && (fa->src_port == fb->src_port) && (fa->dst_ip == fb->dst_ip) && + (fa->dst_port == fb->dst_port)) || + ((fa->src_ip == fb->dst_ip) && (fa->src_port == fb->dst_port) && (fa->dst_ip == fb->src_ip) && + (fa->dst_port == fb->src_port))) + return (0); + + if (fa->src_ip < fb->src_ip) + return (-1); + else { + if (fa->src_ip > fb->src_ip) + return (1); + } + if (fa->src_port < fb->src_port) + return (-1); + else { + if (fa->src_port > fb->src_port) + return (1); + } + if (fa->dst_ip < fb->dst_ip) + return (-1); + else { + if (fa->dst_ip > fb->dst_ip) + return (1); + } + if (fa->dst_port < fb->dst_port) + return (-1); + else { + if (fa->dst_port > fb->dst_port) + return (1); + } + + return (0); /* notreached */ } /* ***************************************************** */ -static void patchIPv6Address(char *str) { - int i = 0, j = 0; - - while(str[i] != '\0') { - if((str[i] == ':') - && (str[i+1] == '0') - && (str[i+2] == ':')) { - str[j++] = ':'; - str[j++] = ':'; - i += 3; - } else - str[j++] = str[i++]; - } - if(str[j] != '\0') str[j] = '\0'; +static void +patchIPv6Address(char *str) { + int i = 0, j = 0; + + while (str[i] != '\0') { + if ((str[i] == ':') && (str[i + 1] == '0') && (str[i + 2] == ':')) { + str[j++] = ':'; + str[j++] = ':'; + i += 3; + } else + str[j++] = str[i++]; + } + if (str[j] != '\0') + str[j] = '\0'; } /* ***************************************************** */ -static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow, - const u_int8_t version, - u_int16_t vlan_id, - const struct ndpi_iphdr *iph, - const struct ndpi_ipv6hdr *iph6, - u_int16_t ip_offset, - u_int16_t ipsize, - u_int16_t l4_packet_len, - struct ndpi_tcphdr **tcph, - struct ndpi_udphdr **udph, - u_int16_t *sport, u_int16_t *dport, - struct ndpi_id_struct **src, - struct ndpi_id_struct **dst, - u_int8_t *proto, - u_int8_t **payload, - u_int16_t *payload_len, - u_int8_t *src_to_dst_direction) { - u_int32_t idx, l4_offset, hashval; - struct ndpi_flow_info flow; - void *ret; - u_int8_t *l3, *l4; - - /* - Note: to keep things simple (ndpiReader is just a demo app) - we handle IPv6 a-la-IPv4. - */ - if(version == IPVERSION) { - if(ipsize < 20) - return NULL; - - if((iph->ihl * 4) > ipsize || ipsize < ntohs(iph->tot_len) - /* || (iph->frag_off & htons(0x1FFF)) != 0 */) - return NULL; - - l4_offset = iph->ihl * 4; - l3 = (u_int8_t*)iph; - } else { - l4_offset = sizeof(struct ndpi_ipv6hdr); - l3 = (u_int8_t*)iph6; - } - - if(l4_packet_len < 64) - workflow->stats.packet_len[0]++; - else if(l4_packet_len >= 64 && l4_packet_len < 128) - workflow->stats.packet_len[1]++; - else if(l4_packet_len >= 128 && l4_packet_len < 256) - workflow->stats.packet_len[2]++; - else if(l4_packet_len >= 256 && l4_packet_len < 1024) - workflow->stats.packet_len[3]++; - else if(l4_packet_len >= 1024 && l4_packet_len < 1500) - workflow->stats.packet_len[4]++; - else if(l4_packet_len >= 1500) - workflow->stats.packet_len[5]++; - - if(l4_packet_len > workflow->stats.max_packet_len) - workflow->stats.max_packet_len = l4_packet_len; - - *proto = iph->protocol; - l4 = ((u_int8_t *) l3 + l4_offset); - - if(iph->protocol == IPPROTO_TCP && l4_packet_len >= 20) { - u_int tcp_len; - - // tcp - workflow->stats.tcp_count++; - *tcph = (struct ndpi_tcphdr *)l4; - *sport = ntohs((*tcph)->source), *dport = ntohs((*tcph)->dest); - tcp_len = ndpi_min(4*(*tcph)->doff, l4_packet_len); - *payload = &l4[tcp_len]; - *payload_len = ndpi_max(0, l4_packet_len-4*(*tcph)->doff); - } else if(iph->protocol == IPPROTO_UDP && l4_packet_len >= 8) { - // udp - - workflow->stats.udp_count++; - *udph = (struct ndpi_udphdr *)l4; - *sport = ntohs((*udph)->source), *dport = ntohs((*udph)->dest); - *payload = &l4[sizeof(struct ndpi_udphdr)]; - *payload_len = ndpi_max(0, l4_packet_len-sizeof(struct ndpi_udphdr)); - } else { - // non tcp/udp protocols - *sport = *dport = 0; - } - - flow.protocol = iph->protocol, flow.vlan_id = vlan_id; - flow.src_ip = iph->saddr, flow.dst_ip = iph->daddr; - flow.src_port = htons(*sport), flow.dst_port = htons(*dport); - flow.hashval = hashval = flow.protocol + flow.vlan_id + flow.src_ip + flow.dst_ip + flow.src_port + flow.dst_port; - idx = hashval % workflow->prefs.num_roots; - ret = ndpi_tfind(&flow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp); - - if(ret == NULL) { - if(workflow->stats.ndpi_flow_count == workflow->prefs.max_ndpi_flows) { - NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_ERROR, - "maximum flow count (%u) has been exceeded\n", - workflow->prefs.max_ndpi_flows); - exit(-1); - } else { - struct ndpi_flow_info *newflow = (struct ndpi_flow_info*)malloc(sizeof(struct ndpi_flow_info)); - - if(newflow == NULL) { - NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(1): not enough memory\n", __FUNCTION__); - return(NULL); - } - - memset(newflow, 0, sizeof(struct ndpi_flow_info)); - newflow->hashval = hashval; - newflow->protocol = iph->protocol, newflow->vlan_id = vlan_id; - newflow->src_ip = iph->saddr, newflow->dst_ip = iph->daddr; - newflow->src_port = htons(*sport), newflow->dst_port = htons(*dport); - newflow->ip_version = version; - - if(version == IPVERSION) { - inet_ntop(AF_INET, &newflow->src_ip, newflow->src_name, sizeof(newflow->src_name)); - inet_ntop(AF_INET, &newflow->dst_ip, newflow->dst_name, sizeof(newflow->dst_name)); - } else { - inet_ntop(AF_INET6, &iph6->ip6_src, newflow->src_name, sizeof(newflow->src_name)); - inet_ntop(AF_INET6, &iph6->ip6_dst, newflow->dst_name, sizeof(newflow->dst_name)); - /* For consistency across platforms replace :0: with :: */ - patchIPv6Address(newflow->src_name), patchIPv6Address(newflow->dst_name); - } - - if((newflow->ndpi_flow = ndpi_flow_malloc(SIZEOF_FLOW_STRUCT)) == NULL) { - NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(2): not enough memory\n", __FUNCTION__); - free(newflow); - return(NULL); - } else - memset(newflow->ndpi_flow, 0, SIZEOF_FLOW_STRUCT); - - if((newflow->src_id = ndpi_malloc(SIZEOF_ID_STRUCT)) == NULL) { - NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(3): not enough memory\n", __FUNCTION__); - free(newflow); - return(NULL); - } else - memset(newflow->src_id, 0, SIZEOF_ID_STRUCT); - - if((newflow->dst_id = ndpi_malloc(SIZEOF_ID_STRUCT)) == NULL) { - NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(4): not enough memory\n", __FUNCTION__); - free(newflow); - return(NULL); - } else - memset(newflow->dst_id, 0, SIZEOF_ID_STRUCT); - - ndpi_tsearch(newflow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp); /* Add */ - workflow->stats.ndpi_flow_count++; - - *src = newflow->src_id, *dst = newflow->dst_id; - - return newflow; - } - } else { - struct ndpi_flow_info *flow = *(struct ndpi_flow_info**)ret; - - if(flow->src_ip == iph->saddr - && flow->dst_ip == iph->daddr - && flow->src_port == htons(*sport) - && flow->dst_port == htons(*dport) - ) - *src = flow->src_id, *dst = flow->dst_id, *src_to_dst_direction = 1; - else - *src = flow->dst_id, *dst = flow->src_id, *src_to_dst_direction = 0, flow->bidirectional = 1; - - return flow; - } +static struct ndpi_flow_info * +get_ndpi_flow_info(struct ndpi_workflow *workflow, const u_int8_t version, u_int16_t vlan_id, + const struct ndpi_iphdr *iph, const struct ndpi_ipv6hdr *iph6, u_int16_t ip_offset, u_int16_t ipsize, + u_int16_t l4_packet_len, struct ndpi_tcphdr **tcph, struct ndpi_udphdr **udph, u_int16_t *sport, + u_int16_t *dport, struct ndpi_id_struct **src, struct ndpi_id_struct **dst, u_int8_t *proto, + u_int8_t **payload, u_int16_t *payload_len, u_int8_t *src_to_dst_direction) { + u_int32_t idx, l4_offset, hashval; + struct ndpi_flow_info flow; + void *ret; + u_int8_t *l3, *l4; + + /* + Note: to keep things simple (ndpiReader is just a demo app) + we handle IPv6 a-la-IPv4. + */ + if (version == IPVERSION) { + if (ipsize < 20) + return NULL; + + if ((iph->ihl * 4) > ipsize || ipsize < ntohs(iph->tot_len) + /* || (iph->frag_off & htons(0x1FFF)) != 0 */) + return NULL; + + l4_offset = iph->ihl * 4; + l3 = (u_int8_t *)iph; + } else { + l4_offset = sizeof(struct ndpi_ipv6hdr); + l3 = (u_int8_t *)iph6; + } + + if (l4_packet_len < 64) + workflow->stats.packet_len[0]++; + else if (l4_packet_len >= 64 && l4_packet_len < 128) + workflow->stats.packet_len[1]++; + else if (l4_packet_len >= 128 && l4_packet_len < 256) + workflow->stats.packet_len[2]++; + else if (l4_packet_len >= 256 && l4_packet_len < 1024) + workflow->stats.packet_len[3]++; + else if (l4_packet_len >= 1024 && l4_packet_len < 1500) + workflow->stats.packet_len[4]++; + else if (l4_packet_len >= 1500) + workflow->stats.packet_len[5]++; + + if (l4_packet_len > workflow->stats.max_packet_len) + workflow->stats.max_packet_len = l4_packet_len; + + *proto = iph->protocol; + l4 = ((u_int8_t *)l3 + l4_offset); + + if (iph->protocol == IPPROTO_TCP && l4_packet_len >= 20) { + u_int tcp_len; + + // tcp + workflow->stats.tcp_count++; + *tcph = (struct ndpi_tcphdr *)l4; + *sport = ntohs((*tcph)->source), *dport = ntohs((*tcph)->dest); + tcp_len = ndpi_min(4 * (*tcph)->doff, l4_packet_len); + *payload = &l4[tcp_len]; + *payload_len = ndpi_max(0, l4_packet_len - 4 * (*tcph)->doff); + } else if (iph->protocol == IPPROTO_UDP && l4_packet_len >= 8) { + // udp + + workflow->stats.udp_count++; + *udph = (struct ndpi_udphdr *)l4; + *sport = ntohs((*udph)->source), *dport = ntohs((*udph)->dest); + *payload = &l4[sizeof(struct ndpi_udphdr)]; + *payload_len = ndpi_max(0, l4_packet_len - sizeof(struct ndpi_udphdr)); + } else { + // non tcp/udp protocols + *sport = *dport = 0; + } + + flow.protocol = iph->protocol, flow.vlan_id = vlan_id; + flow.src_ip = iph->saddr, flow.dst_ip = iph->daddr; + flow.src_port = htons(*sport), flow.dst_port = htons(*dport); + flow.hashval = hashval = + flow.protocol + flow.vlan_id + flow.src_ip + flow.dst_ip + flow.src_port + flow.dst_port; + idx = hashval % workflow->prefs.num_roots; + ret = ndpi_tfind(&flow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp); + + if (ret == NULL) { + if (workflow->stats.ndpi_flow_count == workflow->prefs.max_ndpi_flows) { + NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_ERROR, + "maximum flow count (%u) has been exceeded\n", workflow->prefs.max_ndpi_flows); + exit(-1); + } else { + struct ndpi_flow_info *newflow = (struct ndpi_flow_info *)malloc(sizeof(struct ndpi_flow_info)); + + if (newflow == NULL) { + NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(1): not enough memory\n", + __FUNCTION__); + return (NULL); + } + + memset(newflow, 0, sizeof(struct ndpi_flow_info)); + newflow->hashval = hashval; + newflow->protocol = iph->protocol, newflow->vlan_id = vlan_id; + newflow->src_ip = iph->saddr, newflow->dst_ip = iph->daddr; + newflow->src_port = htons(*sport), newflow->dst_port = htons(*dport); + newflow->ip_version = version; + + if (version == IPVERSION) { + inet_ntop(AF_INET, &newflow->src_ip, newflow->src_name, sizeof(newflow->src_name)); + inet_ntop(AF_INET, &newflow->dst_ip, newflow->dst_name, sizeof(newflow->dst_name)); + } else { + inet_ntop(AF_INET6, &iph6->ip6_src, newflow->src_name, sizeof(newflow->src_name)); + inet_ntop(AF_INET6, &iph6->ip6_dst, newflow->dst_name, sizeof(newflow->dst_name)); + /* For consistency across platforms replace :0: with :: */ + patchIPv6Address(newflow->src_name), patchIPv6Address(newflow->dst_name); + } + + if ((newflow->ndpi_flow = ndpi_flow_malloc(SIZEOF_FLOW_STRUCT)) == NULL) { + NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(2): not enough memory\n", + __FUNCTION__); + free(newflow); + return (NULL); + } else + memset(newflow->ndpi_flow, 0, SIZEOF_FLOW_STRUCT); + + if ((newflow->src_id = ndpi_malloc(SIZEOF_ID_STRUCT)) == NULL) { + NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(3): not enough memory\n", + __FUNCTION__); + free(newflow); + return (NULL); + } else + memset(newflow->src_id, 0, SIZEOF_ID_STRUCT); + + if ((newflow->dst_id = ndpi_malloc(SIZEOF_ID_STRUCT)) == NULL) { + NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(4): not enough memory\n", + __FUNCTION__); + free(newflow); + return (NULL); + } else + memset(newflow->dst_id, 0, SIZEOF_ID_STRUCT); + + ndpi_tsearch(newflow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp); /* Add */ + workflow->stats.ndpi_flow_count++; + + *src = newflow->src_id, *dst = newflow->dst_id; + + return newflow; + } + } else { + struct ndpi_flow_info *flow = *(struct ndpi_flow_info **)ret; + + if (flow->src_ip == iph->saddr && flow->dst_ip == iph->daddr && flow->src_port == htons(*sport) && + flow->dst_port == htons(*dport)) + *src = flow->src_id, *dst = flow->dst_id, *src_to_dst_direction = 1; + else + *src = flow->dst_id, *dst = flow->src_id, *src_to_dst_direction = 0, flow->bidirectional = 1; + + return flow; + } } /* ****************************************************** */ -static struct ndpi_flow_info *get_ndpi_flow_info6(struct ndpi_workflow * workflow, - u_int16_t vlan_id, - const struct ndpi_ipv6hdr *iph6, - u_int16_t ip_offset, - struct ndpi_tcphdr **tcph, - struct ndpi_udphdr **udph, - u_int16_t *sport, u_int16_t *dport, - struct ndpi_id_struct **src, - struct ndpi_id_struct **dst, - u_int8_t *proto, - u_int8_t **payload, - u_int16_t *payload_len, - u_int8_t *src_to_dst_direction) { - struct ndpi_iphdr iph; - - memset(&iph, 0, sizeof(iph)); - iph.version = IPVERSION; - iph.saddr = iph6->ip6_src.u6_addr.u6_addr32[2] + iph6->ip6_src.u6_addr.u6_addr32[3]; - iph.daddr = iph6->ip6_dst.u6_addr.u6_addr32[2] + iph6->ip6_dst.u6_addr.u6_addr32[3]; - iph.protocol = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt; - - if(iph.protocol == IPPROTO_DSTOPTS /* IPv6 destination option */) { - u_int8_t *options = (u_int8_t*)iph6 + sizeof(const struct ndpi_ipv6hdr); - - iph.protocol = options[0]; - } - - return(get_ndpi_flow_info(workflow, 6, vlan_id, &iph, iph6, ip_offset, - sizeof(struct ndpi_ipv6hdr), - ntohs(iph6->ip6_ctlun.ip6_un1.ip6_un1_plen), - tcph, udph, sport, dport, - src, dst, proto, payload, payload_len, src_to_dst_direction)); +static struct ndpi_flow_info * +get_ndpi_flow_info6(struct ndpi_workflow *workflow, u_int16_t vlan_id, const struct ndpi_ipv6hdr *iph6, + u_int16_t ip_offset, struct ndpi_tcphdr **tcph, struct ndpi_udphdr **udph, u_int16_t *sport, + u_int16_t *dport, struct ndpi_id_struct **src, struct ndpi_id_struct **dst, u_int8_t *proto, + u_int8_t **payload, u_int16_t *payload_len, u_int8_t *src_to_dst_direction) { + struct ndpi_iphdr iph; + + memset(&iph, 0, sizeof(iph)); + iph.version = IPVERSION; + iph.saddr = iph6->ip6_src.u6_addr.u6_addr32[2] + iph6->ip6_src.u6_addr.u6_addr32[3]; + iph.daddr = iph6->ip6_dst.u6_addr.u6_addr32[2] + iph6->ip6_dst.u6_addr.u6_addr32[3]; + iph.protocol = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt; + + if (iph.protocol == IPPROTO_DSTOPTS /* IPv6 destination option */) { + u_int8_t *options = (u_int8_t *)iph6 + sizeof(const struct ndpi_ipv6hdr); + + iph.protocol = options[0]; + } + + return (get_ndpi_flow_info(workflow, 6, vlan_id, &iph, iph6, ip_offset, sizeof(struct ndpi_ipv6hdr), + ntohs(iph6->ip6_ctlun.ip6_un1.ip6_un1_plen), tcph, udph, sport, dport, src, dst, + proto, payload, payload_len, src_to_dst_direction)); } /* ****************************************************** */ -void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_flow_info *flow) { - if(!flow->ndpi_flow) return; - - snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", - flow->ndpi_flow->host_server_name); - - /* BITTORRENT */ - if(flow->detected_protocol.app_protocol == NDPI_PROTOCOL_BITTORRENT) { - int i, j, n = 0; - - for(i=0, j = 0; j < sizeof(flow->bittorent_hash)-1; i++) { - sprintf(&flow->bittorent_hash[j], "%02x", flow->ndpi_flow->bittorent_hash[i]); - j += 2, n += flow->ndpi_flow->bittorent_hash[i]; - } - - if(n == 0) flow->bittorent_hash[0] = '\0'; - } - /* MDNS */ - else if(flow->detected_protocol.app_protocol == NDPI_PROTOCOL_MDNS) { - snprintf(flow->info, sizeof(flow->info), "%s", flow->ndpi_flow->protos.mdns.answer); - } - /* UBNTAC2 */ - else if(flow->detected_protocol.app_protocol == NDPI_PROTOCOL_UBNTAC2) { - snprintf(flow->info, sizeof(flow->info), "%s", flow->ndpi_flow->protos.ubntac2.version); - } - if(flow->detected_protocol.app_protocol != NDPI_PROTOCOL_DNS) { - /* SSH */ - if(flow->detected_protocol.app_protocol == NDPI_PROTOCOL_SSH) { - snprintf(flow->ssh_ssl.client_info, sizeof(flow->ssh_ssl.client_info), "%s", - flow->ndpi_flow->protos.ssh.client_signature); - snprintf(flow->ssh_ssl.server_info, sizeof(flow->ssh_ssl.server_info), "%s", - flow->ndpi_flow->protos.ssh.server_signature); - } - /* SSL */ - else if((flow->detected_protocol.app_protocol == NDPI_PROTOCOL_SSL) - || (flow->detected_protocol.master_protocol == NDPI_PROTOCOL_SSL)) { - snprintf(flow->ssh_ssl.client_info, sizeof(flow->ssh_ssl.client_info), "%s", - flow->ndpi_flow->protos.ssl.client_certificate); - snprintf(flow->ssh_ssl.server_info, sizeof(flow->ssh_ssl.server_info), "%s", - flow->ndpi_flow->protos.ssl.server_certificate); - } - } - - if(flow->detection_completed) { - if(flow->detected_protocol.app_protocol == NDPI_PROTOCOL_UNKNOWN) { - if (workflow->__flow_giveup_callback != NULL) - workflow->__flow_giveup_callback(workflow, flow, workflow->__flow_giveup_udata); - } else { - if (workflow->__flow_detected_callback != NULL) - workflow->__flow_detected_callback(workflow, flow, workflow->__flow_detected_udata); - } - - ndpi_free_flow_info_half(flow); - } +void +process_ndpi_collected_info(struct ndpi_workflow *workflow, struct ndpi_flow_info *flow) { + if (!flow->ndpi_flow) + return; + + snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name); + + /* BITTORRENT */ + if (flow->detected_protocol.app_protocol == NDPI_PROTOCOL_BITTORRENT) { + int i, j, n = 0; + + for (i = 0, j = 0; j < sizeof(flow->bittorent_hash) - 1; i++) { + sprintf(&flow->bittorent_hash[j], "%02x", flow->ndpi_flow->bittorent_hash[i]); + j += 2, n += flow->ndpi_flow->bittorent_hash[i]; + } + + if (n == 0) + flow->bittorent_hash[0] = '\0'; + } + /* MDNS */ + else if (flow->detected_protocol.app_protocol == NDPI_PROTOCOL_MDNS) { + snprintf(flow->info, sizeof(flow->info), "%s", flow->ndpi_flow->protos.mdns.answer); + } + /* UBNTAC2 */ + else if (flow->detected_protocol.app_protocol == NDPI_PROTOCOL_UBNTAC2) { + snprintf(flow->info, sizeof(flow->info), "%s", flow->ndpi_flow->protos.ubntac2.version); + } + if (flow->detected_protocol.app_protocol != NDPI_PROTOCOL_DNS) { + /* SSH */ + if (flow->detected_protocol.app_protocol == NDPI_PROTOCOL_SSH) { + snprintf(flow->ssh_ssl.client_info, sizeof(flow->ssh_ssl.client_info), "%s", + flow->ndpi_flow->protos.ssh.client_signature); + snprintf(flow->ssh_ssl.server_info, sizeof(flow->ssh_ssl.server_info), "%s", + flow->ndpi_flow->protos.ssh.server_signature); + } + /* SSL */ + else if ((flow->detected_protocol.app_protocol == NDPI_PROTOCOL_SSL) || + (flow->detected_protocol.master_protocol == NDPI_PROTOCOL_SSL)) { + snprintf(flow->ssh_ssl.client_info, sizeof(flow->ssh_ssl.client_info), "%s", + flow->ndpi_flow->protos.ssl.client_certificate); + snprintf(flow->ssh_ssl.server_info, sizeof(flow->ssh_ssl.server_info), "%s", + flow->ndpi_flow->protos.ssl.server_certificate); + } + } + + if (flow->detection_completed) { + if (flow->detected_protocol.app_protocol == NDPI_PROTOCOL_UNKNOWN) { + if (workflow->__flow_giveup_callback != NULL) + workflow->__flow_giveup_callback(workflow, flow, workflow->__flow_giveup_udata); + } else { + if (workflow->__flow_detected_callback != NULL) + workflow->__flow_detected_callback(workflow, flow, workflow->__flow_detected_udata); + } + + ndpi_free_flow_info_half(flow); + } } /* ****************************************************** */ @@ -475,436 +494,431 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl @Note: ipsize = header->len - ip_offset ; rawsize = header->len */ -static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow, - const u_int64_t time, - u_int16_t vlan_id, - const struct ndpi_iphdr *iph, - struct ndpi_ipv6hdr *iph6, - u_int16_t ip_offset, - u_int16_t ipsize, u_int16_t rawsize) { - struct ndpi_id_struct *src, *dst; - struct ndpi_flow_info *flow = NULL; - struct ndpi_flow_struct *ndpi_flow = NULL; - u_int8_t proto; - struct ndpi_tcphdr *tcph = NULL; - struct ndpi_udphdr *udph = NULL; - u_int16_t sport, dport, payload_len; - u_int8_t *payload; - u_int8_t src_to_dst_direction = 1; - u_int8_t guess = 0; - struct ndpi_proto nproto = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN }; - - if(iph) - flow = get_ndpi_flow_info(workflow, IPVERSION, vlan_id, iph, NULL, - ip_offset, ipsize, - ntohs(iph->tot_len) - (iph->ihl * 4), - &tcph, &udph, &sport, &dport, - &src, &dst, &proto, - &payload, &payload_len, &src_to_dst_direction); - else - flow = get_ndpi_flow_info6(workflow, vlan_id, iph6, ip_offset, - &tcph, &udph, &sport, &dport, - &src, &dst, &proto, - &payload, &payload_len, &src_to_dst_direction); - - if(flow != NULL) { - workflow->stats.ip_packet_count++; - workflow->stats.total_wire_bytes += rawsize + 24 /* CRC etc */, - workflow->stats.total_ip_bytes += rawsize; - ndpi_flow = flow->ndpi_flow; - - if(src_to_dst_direction) - flow->src2dst_packets++, flow->src2dst_bytes += rawsize; - else - flow->dst2src_packets++, flow->dst2src_bytes += rawsize; - - flow->last_seen = time; - } else { // flow is NULL - workflow->stats.total_discarded_bytes++; - return(nproto); - } - - /* Protocol already detected */ - if(flow->detection_completed) return(flow->detected_protocol); - - flow->detected_protocol = ndpi_detection_process_packet(workflow->ndpi_struct, ndpi_flow, - iph ? (uint8_t *)iph : (uint8_t *)iph6, - ipsize, time, src, dst); - - if((flow->detected_protocol.app_protocol != NDPI_PROTOCOL_UNKNOWN) - || ((proto == IPPROTO_UDP) && ((flow->src2dst_packets + flow->dst2src_packets) > 8)) - || ((proto == IPPROTO_TCP) && ((flow->src2dst_packets + flow->dst2src_packets) > 10))) { - /* New protocol detected or give up */ - flow->detection_completed = 1; - - if(flow->detected_protocol.app_protocol == NDPI_PROTOCOL_UNKNOWN) - flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, - flow->ndpi_flow); - process_ndpi_collected_info(workflow, flow); - } - - if (guess && flow->detected_protocol.app_protocol == NDPI_PROTOCOL_UNKNOWN) - flow->detected_protocol = ndpi_guess_undetected_protocol(workflow->ndpi_struct, - flow->protocol, - ntohl(flow->src_ip), - ntohs(flow->src_port), - ntohl(flow->dst_ip), - ntohs(flow->dst_port)); - /*printf("Guess = %d\n",guess);*/ - - - - return(flow->detected_protocol); +static struct ndpi_proto +packet_processing(struct ndpi_workflow *workflow, const u_int64_t time, u_int16_t vlan_id, const struct ndpi_iphdr *iph, + struct ndpi_ipv6hdr *iph6, u_int16_t ip_offset, u_int16_t ipsize, u_int16_t rawsize) { + struct ndpi_id_struct *src, *dst; + struct ndpi_flow_info *flow = NULL; + struct ndpi_flow_struct *ndpi_flow = NULL; + u_int8_t proto; + struct ndpi_tcphdr *tcph = NULL; + struct ndpi_udphdr *udph = NULL; + u_int16_t sport, dport, payload_len; + u_int8_t *payload; + u_int8_t src_to_dst_direction = 1; + u_int8_t guess = 0; + struct ndpi_proto nproto = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN}; + + if (iph) + flow = get_ndpi_flow_info(workflow, IPVERSION, vlan_id, iph, NULL, ip_offset, ipsize, + ntohs(iph->tot_len) - (iph->ihl * 4), &tcph, &udph, &sport, &dport, &src, + &dst, &proto, &payload, &payload_len, &src_to_dst_direction); + else + flow = get_ndpi_flow_info6(workflow, vlan_id, iph6, ip_offset, &tcph, &udph, &sport, &dport, &src, &dst, + &proto, &payload, &payload_len, &src_to_dst_direction); + + if (flow != NULL) { + workflow->stats.ip_packet_count++; + workflow->stats.total_wire_bytes += rawsize + 24 /* CRC etc */, + workflow->stats.total_ip_bytes += rawsize; + ndpi_flow = flow->ndpi_flow; + + if (src_to_dst_direction) + flow->src2dst_packets++, flow->src2dst_bytes += rawsize; + else + flow->dst2src_packets++, flow->dst2src_bytes += rawsize; + + flow->last_seen = time; + } else { // flow is NULL + workflow->stats.total_discarded_bytes++; + return (nproto); + } + + /* Protocol already detected */ + if (flow->detection_completed) + return (flow->detected_protocol); + + flow->detected_protocol = ndpi_detection_process_packet( + workflow->ndpi_struct, ndpi_flow, iph ? (uint8_t *)iph : (uint8_t *)iph6, ipsize, time, src, dst); + + if ((flow->detected_protocol.app_protocol != NDPI_PROTOCOL_UNKNOWN) || + ((proto == IPPROTO_UDP) && ((flow->src2dst_packets + flow->dst2src_packets) > 8)) || + ((proto == IPPROTO_TCP) && ((flow->src2dst_packets + flow->dst2src_packets) > 10))) { + /* New protocol detected or give up */ + flow->detection_completed = 1; + + if (flow->detected_protocol.app_protocol == NDPI_PROTOCOL_UNKNOWN) + flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, flow->ndpi_flow); + process_ndpi_collected_info(workflow, flow); + } + + if (guess && flow->detected_protocol.app_protocol == NDPI_PROTOCOL_UNKNOWN) + flow->detected_protocol = + ndpi_guess_undetected_protocol(workflow->ndpi_struct, flow->protocol, ntohl(flow->src_ip), + ntohs(flow->src_port), ntohl(flow->dst_ip), ntohs(flow->dst_port)); + /*printf("Guess = %d\n",guess);*/ + + return (flow->detected_protocol); } /* ****************************************************** */ -struct ndpi_proto ndpi_workflow_process_packet (struct ndpi_workflow * workflow, - const struct pcap_pkthdr *header, - const u_char *packet) { - /* - * Declare pointers to packet headers - */ - /* --- Ethernet header --- */ - const struct ndpi_ethhdr *ethernet; - /* --- LLC header --- */ - const struct ndpi_llc_header_snap *llc; - - /* --- Cisco HDLC header --- */ - const struct ndpi_chdlc *chdlc; - - /* --- Radio Tap header --- */ - const struct ndpi_radiotap_header *radiotap; - /* --- Wifi header --- */ - const struct ndpi_wifi_header *wifi; - - /* --- MPLS header --- */ - struct ndpi_mpls_header *mpls; - - /** --- IP header --- **/ - struct ndpi_iphdr *iph; - /** --- IPv6 header --- **/ - struct ndpi_ipv6hdr *iph6; - - struct ndpi_proto nproto = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN }; - - /* lengths and offsets */ - u_int16_t eth_offset = 0; - u_int16_t radio_len; - u_int16_t fc; - u_int16_t type = 0; - int wifi_len = 0; - int pyld_eth_len = 0; - int check; - u_int64_t time; - u_int16_t ip_offset = 0, ip_len; - u_int16_t frag_off = 0, vlan_id = 0; - u_int8_t proto = 0; - u_int32_t label; - - /* counters */ - u_int8_t vlan_packet = 0; - - /* Increment raw packet counter */ - workflow->stats.raw_packet_count++; - - /* setting time */ - time = ((uint64_t) header->ts.tv_sec) * TICK_RESOLUTION + header->ts.tv_usec / (1000000 / TICK_RESOLUTION); - - /* safety check */ - if(workflow->last_time > time) { - /* printf("\nWARNING: timestamp bug in the pcap file (ts delta: %llu, repairing)\n", ndpi_thread_info[thread_id].last_time - time); */ - time = workflow->last_time; - } - /* update last time value */ - workflow->last_time = time; - - /*** check Data Link type ***/ - const int datalink_type = pcap_datalink(workflow->pcap_handle); - - datalink_check: - switch(datalink_type) { - case DLT_NULL: - if(ntohl(*((u_int32_t*)&packet[eth_offset])) == 2) - type = ETH_P_IP; - else - type = ETH_P_IPV6; - - ip_offset = 4 + eth_offset; - break; - - /* Cisco PPP in HDLC-like framing - 50 */ - case DLT_PPP_SERIAL: - chdlc = (struct ndpi_chdlc *) &packet[eth_offset]; - ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ - type = ntohs(chdlc->proto_code); - break; - - /* Cisco PPP with HDLC framing - 104 */ - case DLT_C_HDLC: - chdlc = (struct ndpi_chdlc *) &packet[eth_offset]; - ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ - type = ntohs(chdlc->proto_code); - break; - - /* IEEE 802.3 Ethernet - 1 */ - case DLT_EN10MB: - ethernet = (struct ndpi_ethhdr *) &packet[eth_offset]; - ip_offset = sizeof(struct ndpi_ethhdr) + eth_offset; - check = ntohs(ethernet->h_proto); - - if(check <= 1500) - pyld_eth_len = check; - else if (check >= 1536) - type = check; - - if(pyld_eth_len != 0) { - llc = (struct ndpi_llc_header_snap *)(&packet[ip_offset]); - /* check for LLC layer with SNAP extension */ - if(llc->dsap == SNAP || llc->ssap == SNAP) { - type = llc->snap.proto_ID; - ip_offset += + 8; - } - /* No SNAP extension - Spanning Tree pkt must be discarted */ - else if(llc->dsap == BSTP || llc->ssap == BSTP) { - goto v4_warning; - } - } - break; - - /* Linux Cooked Capture - 113 */ - case DLT_LINUX_SLL: - type = (packet[eth_offset+14] << 8) + packet[eth_offset+15]; - ip_offset = 16 + eth_offset; - break; - - /* Radiotap link-layer - 127 */ - case DLT_IEEE802_11_RADIO: - radiotap = (struct ndpi_radiotap_header *) &packet[eth_offset]; - radio_len = radiotap->len; - - /* Check Bad FCS presence */ - if((radiotap->flags & BAD_FCS) == BAD_FCS) { - workflow->stats.total_discarded_bytes += header->len; - return(nproto); - } - - /* Calculate 802.11 header length (variable) */ - wifi = (struct ndpi_wifi_header*)( packet + eth_offset + radio_len); - fc = wifi->fc; - - /* check wifi data presence */ - if(FCF_TYPE(fc) == WIFI_DATA) { - if((FCF_TO_DS(fc) && FCF_FROM_DS(fc) == 0x0) || - (FCF_TO_DS(fc) == 0x0 && FCF_FROM_DS(fc))) - wifi_len = 26; /* + 4 byte fcs */ - } else /* no data frames */ - break; - - /* Check ether_type from LLC */ - llc = (struct ndpi_llc_header_snap*)(packet + eth_offset + wifi_len + radio_len); - if(llc->dsap == SNAP) - type = ntohs(llc->snap.proto_ID); - - /* Set IP header offset */ - ip_offset = wifi_len + radio_len + sizeof(struct ndpi_llc_header_snap) + eth_offset; - break; - - case DLT_RAW: - ip_offset = eth_offset = 0; - break; - - default: - /* printf("Unknown datalink %d\n", datalink_type); */ - return(nproto); - } - - /* check ether type */ - switch(type) { - case VLAN: - vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF; - type = (packet[ip_offset+2] << 8) + packet[ip_offset+3]; - ip_offset += 4; - vlan_packet = 1; - // double tagging for 802.1Q - if(type == 0x8100) { - vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF; - type = (packet[ip_offset+2] << 8) + packet[ip_offset+3]; - ip_offset += 4; - } - break; - case MPLS_UNI: - case MPLS_MULTI: - mpls = (struct ndpi_mpls_header *) &packet[ip_offset]; - label = ntohl(mpls->label); - /* label = ntohl(*((u_int32_t*)&packet[ip_offset])); */ - workflow->stats.mpls_count++; - type = ETH_P_IP, ip_offset += 4; - - while((label & 0x100) != 0x100) { - ip_offset += 4; - label = ntohl(mpls->label); - } - break; - case PPPoE: - workflow->stats.pppoe_count++; - type = ETH_P_IP; - ip_offset += 8; - break; - default: - break; - } - - workflow->stats.vlan_count += vlan_packet; - - iph_check: - /* Check and set IP header size and total packet length */ - iph = (struct ndpi_iphdr *) &packet[ip_offset]; - - /* just work on Ethernet packets that contain IP */ - if(type == ETH_P_IP && header->caplen >= ip_offset) { - frag_off = ntohs(iph->frag_off); - - proto = iph->protocol; - if(header->caplen < header->len) { - static u_int8_t cap_warning_used = 0; - - if(cap_warning_used == 0) { - if(!workflow->prefs.quiet_mode) - NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_DEBUG, "\n\nWARNING: packet capture size is smaller than packet size, DETECTION MIGHT NOT WORK CORRECTLY\n\n"); - cap_warning_used = 1; - } - } - } - - if(iph->version == IPVERSION) { - ip_len = ((u_int16_t)iph->ihl * 4); - iph6 = NULL; - - if(iph->protocol == IPPROTO_IPV6) { - ip_offset += ip_len; - goto iph_check; - } - - if((frag_off & 0x1FFF) != 0) { - static u_int8_t ipv4_frags_warning_used = 0; - workflow->stats.fragmented_count++; - - if(ipv4_frags_warning_used == 0) { - if(!workflow->prefs.quiet_mode) - NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_DEBUG, "\n\nWARNING: IPv4 fragments are not handled by this demo (nDPI supports them)\n"); - ipv4_frags_warning_used = 1; - } - - workflow->stats.total_discarded_bytes += header->len; - return(nproto); - } - } else if(iph->version == 6) { - iph6 = (struct ndpi_ipv6hdr *)&packet[ip_offset]; - proto = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt; - ip_len = sizeof(struct ndpi_ipv6hdr); - - if(proto == IPPROTO_DSTOPTS /* IPv6 destination option */) { - - u_int8_t *options = (u_int8_t*)&packet[ip_offset+ip_len]; - proto = options[0]; - ip_len += 8 * (options[1] + 1); - } - iph = NULL; - - } else { - static u_int8_t ipv4_warning_used = 0; - - v4_warning: - if(ipv4_warning_used == 0) { - if(!workflow->prefs.quiet_mode) - NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_DEBUG, "\n\nWARNING: only IPv4/IPv6 packets are supported in this demo (nDPI supports both IPv4 and IPv6), all other packets will be discarded\n\n"); - ipv4_warning_used = 1; - } - workflow->stats.total_discarded_bytes += header->len; - return(nproto); - } - - if(workflow->prefs.decode_tunnels && (proto == IPPROTO_UDP)) { - struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len]; - u_int16_t sport = ntohs(udp->source), dport = ntohs(udp->dest); - - if((sport == GTP_U_V1_PORT) || (dport == GTP_U_V1_PORT)) { - /* Check if it's GTPv1 */ - u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr); - u_int8_t flags = packet[offset]; - u_int8_t message_type = packet[offset+1]; - - if((((flags & 0xE0) >> 5) == 1 /* GTPv1 */) && - (message_type == 0xFF /* T-PDU */)) { - - ip_offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr)+8; /* GTPv1 header len */ - if(flags & 0x04) ip_offset += 1; /* next_ext_header is present */ - if(flags & 0x02) ip_offset += 4; /* sequence_number is present (it also includes next_ext_header and pdu_number) */ - if(flags & 0x01) ip_offset += 1; /* pdu_number is present */ - - iph = (struct ndpi_iphdr *) &packet[ip_offset]; - - if(iph->version != IPVERSION) { - // printf("WARNING: not good (packet_id=%u)!\n", (unsigned int)workflow->stats.raw_packet_count); - goto v4_warning; - } - } - } else if((sport == TZSP_PORT) || (dport == TZSP_PORT)) { - /* https://en.wikipedia.org/wiki/TZSP */ - u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr); - u_int8_t version = packet[offset]; - u_int8_t type = packet[offset+1]; - u_int16_t encapsulates = ntohs(*((u_int16_t*)&packet[offset+2])); - - if((version == 1) && (type == 0) && (encapsulates == 1)) { - u_int8_t stop = 0; - - offset += 4; - - while((!stop) && (offset < header->caplen)) { - u_int8_t tag_type = packet[offset]; - u_int8_t tag_len; - - switch(tag_type) { - case 0: /* PADDING Tag */ - tag_len = 1; - break; - case 1: /* END Tag */ - tag_len = 1, stop = 1; - break; - default: - tag_len = packet[offset+1]; - break; - } - - offset += tag_len; - - if(offset >= header->caplen) - return(nproto); /* Invalid packet */ - else { - eth_offset = offset; - goto datalink_check; - } - } - } - } - } - - /* process the packet */ - return(packet_processing(workflow, time, vlan_id, iph, iph6, - ip_offset, header->caplen - ip_offset, header->caplen)); +struct ndpi_proto +ndpi_workflow_process_packet(struct ndpi_workflow *workflow, const struct pcap_pkthdr *header, const u_char *packet) { + /* + * Declare pointers to packet headers + */ + /* --- Ethernet header --- */ + const struct ndpi_ethhdr *ethernet; + /* --- LLC header --- */ + const struct ndpi_llc_header_snap *llc; + + /* --- Cisco HDLC header --- */ + const struct ndpi_chdlc *chdlc; + + /* --- Radio Tap header --- */ + const struct ndpi_radiotap_header *radiotap; + /* --- Wifi header --- */ + const struct ndpi_wifi_header *wifi; + + /* --- MPLS header --- */ + struct ndpi_mpls_header *mpls; + + /** --- IP header --- **/ + struct ndpi_iphdr *iph; + /** --- IPv6 header --- **/ + struct ndpi_ipv6hdr *iph6; + + struct ndpi_proto nproto = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN}; + + /* lengths and offsets */ + u_int16_t eth_offset = 0; + u_int16_t radio_len; + u_int16_t fc; + u_int16_t type = 0; + int wifi_len = 0; + int pyld_eth_len = 0; + int check; + u_int64_t time; + u_int16_t ip_offset = 0, ip_len; + u_int16_t frag_off = 0, vlan_id = 0; + u_int8_t proto = 0; + u_int32_t label; + + /* counters */ + u_int8_t vlan_packet = 0; + + /* Increment raw packet counter */ + workflow->stats.raw_packet_count++; + + /* setting time */ + time = ((uint64_t)header->ts.tv_sec) * TICK_RESOLUTION + header->ts.tv_usec / (1000000 / TICK_RESOLUTION); + + /* safety check */ + if (workflow->last_time > time) { + /* printf("\nWARNING: timestamp bug in the pcap file (ts delta: %llu, repairing)\n", + * ndpi_thread_info[thread_id].last_time - time); */ + time = workflow->last_time; + } + /* update last time value */ + workflow->last_time = time; + + /*** check Data Link type ***/ + const int datalink_type = pcap_datalink(workflow->pcap_handle); + +datalink_check: + switch (datalink_type) { + case DLT_NULL: + if (ntohl(*((u_int32_t *)&packet[eth_offset])) == 2) + type = ETH_P_IP; + else + type = ETH_P_IPV6; + + ip_offset = 4 + eth_offset; + break; + + /* Cisco PPP in HDLC-like framing - 50 */ + case DLT_PPP_SERIAL: + chdlc = (struct ndpi_chdlc *)&packet[eth_offset]; + ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ + type = ntohs(chdlc->proto_code); + break; + + /* Cisco PPP with HDLC framing - 104 */ + case DLT_C_HDLC: + chdlc = (struct ndpi_chdlc *)&packet[eth_offset]; + ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ + type = ntohs(chdlc->proto_code); + break; + + /* IEEE 802.3 Ethernet - 1 */ + case DLT_EN10MB: + ethernet = (struct ndpi_ethhdr *)&packet[eth_offset]; + ip_offset = sizeof(struct ndpi_ethhdr) + eth_offset; + check = ntohs(ethernet->h_proto); + + if (check <= 1500) + pyld_eth_len = check; + else if (check >= 1536) + type = check; + + if (pyld_eth_len != 0) { + llc = (struct ndpi_llc_header_snap *)(&packet[ip_offset]); + /* check for LLC layer with SNAP extension */ + if (llc->dsap == SNAP || llc->ssap == SNAP) { + type = llc->snap.proto_ID; + ip_offset += +8; + } + /* No SNAP extension - Spanning Tree pkt must be discarted */ + else if (llc->dsap == BSTP || llc->ssap == BSTP) { + goto v4_warning; + } + } + break; + + /* Linux Cooked Capture - 113 */ + case DLT_LINUX_SLL: + type = (packet[eth_offset + 14] << 8) + packet[eth_offset + 15]; + ip_offset = 16 + eth_offset; + break; + + /* Radiotap link-layer - 127 */ + case DLT_IEEE802_11_RADIO: + radiotap = (struct ndpi_radiotap_header *)&packet[eth_offset]; + radio_len = radiotap->len; + + /* Check Bad FCS presence */ + if ((radiotap->flags & BAD_FCS) == BAD_FCS) { + workflow->stats.total_discarded_bytes += header->len; + return (nproto); + } + + /* Calculate 802.11 header length (variable) */ + wifi = (struct ndpi_wifi_header *)(packet + eth_offset + radio_len); + fc = wifi->fc; + + /* check wifi data presence */ + if (FCF_TYPE(fc) == WIFI_DATA) { + if ((FCF_TO_DS(fc) && FCF_FROM_DS(fc) == 0x0) || + (FCF_TO_DS(fc) == 0x0 && FCF_FROM_DS(fc))) + wifi_len = 26; /* + 4 byte fcs */ + } else /* no data frames */ + break; + + /* Check ether_type from LLC */ + llc = (struct ndpi_llc_header_snap *)(packet + eth_offset + wifi_len + radio_len); + if (llc->dsap == SNAP) + type = ntohs(llc->snap.proto_ID); + + /* Set IP header offset */ + ip_offset = wifi_len + radio_len + sizeof(struct ndpi_llc_header_snap) + eth_offset; + break; + + case DLT_RAW: + ip_offset = eth_offset = 0; + break; + + default: + /* printf("Unknown datalink %d\n", datalink_type); */ + return (nproto); + } + + /* check ether type */ + switch (type) { + case VLAN: + vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset + 1]) & 0xFFF; + type = (packet[ip_offset + 2] << 8) + packet[ip_offset + 3]; + ip_offset += 4; + vlan_packet = 1; + // double tagging for 802.1Q + if (type == 0x8100) { + vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset + 1]) & 0xFFF; + type = (packet[ip_offset + 2] << 8) + packet[ip_offset + 3]; + ip_offset += 4; + } + break; + case MPLS_UNI: + case MPLS_MULTI: + mpls = (struct ndpi_mpls_header *)&packet[ip_offset]; + label = ntohl(mpls->label); + /* label = ntohl(*((u_int32_t*)&packet[ip_offset])); */ + workflow->stats.mpls_count++; + type = ETH_P_IP, ip_offset += 4; + + while ((label & 0x100) != 0x100) { + ip_offset += 4; + label = ntohl(mpls->label); + } + break; + case PPPoE: + workflow->stats.pppoe_count++; + type = ETH_P_IP; + ip_offset += 8; + break; + default: + break; + } + + workflow->stats.vlan_count += vlan_packet; + +iph_check: + /* Check and set IP header size and total packet length */ + iph = (struct ndpi_iphdr *)&packet[ip_offset]; + + /* just work on Ethernet packets that contain IP */ + if (type == ETH_P_IP && header->caplen >= ip_offset) { + frag_off = ntohs(iph->frag_off); + + proto = iph->protocol; + if (header->caplen < header->len) { + static u_int8_t cap_warning_used = 0; + + if (cap_warning_used == 0) { + if (!workflow->prefs.quiet_mode) + NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_DEBUG, + "\n\nWARNING: packet capture size is smaller than packet size, " + "DETECTION MIGHT NOT WORK CORRECTLY\n\n"); + cap_warning_used = 1; + } + } + } + + if (iph->version == IPVERSION) { + ip_len = ((u_int16_t)iph->ihl * 4); + iph6 = NULL; + + if (iph->protocol == IPPROTO_IPV6) { + ip_offset += ip_len; + goto iph_check; + } + + if ((frag_off & 0x1FFF) != 0) { + static u_int8_t ipv4_frags_warning_used = 0; + workflow->stats.fragmented_count++; + + if (ipv4_frags_warning_used == 0) { + if (!workflow->prefs.quiet_mode) + NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_DEBUG, + "\n\nWARNING: IPv4 fragments are not handled by this demo (nDPI " + "supports them)\n"); + ipv4_frags_warning_used = 1; + } + + workflow->stats.total_discarded_bytes += header->len; + return (nproto); + } + } else if (iph->version == 6) { + iph6 = (struct ndpi_ipv6hdr *)&packet[ip_offset]; + proto = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt; + ip_len = sizeof(struct ndpi_ipv6hdr); + + if (proto == IPPROTO_DSTOPTS /* IPv6 destination option */) { + u_int8_t *options = (u_int8_t *)&packet[ip_offset + ip_len]; + proto = options[0]; + ip_len += 8 * (options[1] + 1); + } + iph = NULL; + + } else { + static u_int8_t ipv4_warning_used = 0; + + v4_warning: + if (ipv4_warning_used == 0) { + if (!workflow->prefs.quiet_mode) + NDPI_LOG(0, workflow->ndpi_struct, NDPI_LOG_DEBUG, + "\n\nWARNING: only IPv4/IPv6 packets are supported in this demo (nDPI " + "supports both IPv4 and IPv6), all other packets will be discarded\n\n"); + ipv4_warning_used = 1; + } + workflow->stats.total_discarded_bytes += header->len; + return (nproto); + } + + if (workflow->prefs.decode_tunnels && (proto == IPPROTO_UDP)) { + struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset + ip_len]; + u_int16_t sport = ntohs(udp->source), dport = ntohs(udp->dest); + + if ((sport == GTP_U_V1_PORT) || (dport == GTP_U_V1_PORT)) { + /* Check if it's GTPv1 */ + u_int offset = ip_offset + ip_len + sizeof(struct ndpi_udphdr); + u_int8_t flags = packet[offset]; + u_int8_t message_type = packet[offset + 1]; + + if ((((flags & 0xE0) >> 5) == 1 /* GTPv1 */) && (message_type == 0xFF /* T-PDU */)) { + ip_offset = ip_offset + ip_len + sizeof(struct ndpi_udphdr) + 8; /* GTPv1 header len */ + if (flags & 0x04) + ip_offset += 1; /* next_ext_header is present */ + if (flags & 0x02) + ip_offset += + 4; /* sequence_number is present (it also includes next_ext_header and + pdu_number) */ + if (flags & 0x01) + ip_offset += 1; /* pdu_number is present */ + + iph = (struct ndpi_iphdr *)&packet[ip_offset]; + + if (iph->version != IPVERSION) { + // printf("WARNING: not good (packet_id=%u)!\n", (unsigned + // int)workflow->stats.raw_packet_count); + goto v4_warning; + } + } + } else if ((sport == TZSP_PORT) || (dport == TZSP_PORT)) { + /* https://en.wikipedia.org/wiki/TZSP */ + u_int offset = ip_offset + ip_len + sizeof(struct ndpi_udphdr); + u_int8_t version = packet[offset]; + u_int8_t type = packet[offset + 1]; + u_int16_t encapsulates = ntohs(*((u_int16_t *)&packet[offset + 2])); + + if ((version == 1) && (type == 0) && (encapsulates == 1)) { + u_int8_t stop = 0; + + offset += 4; + + while ((!stop) && (offset < header->caplen)) { + u_int8_t tag_type = packet[offset]; + u_int8_t tag_len; + + switch (tag_type) { + case 0: /* PADDING Tag */ + tag_len = 1; + break; + case 1: /* END Tag */ + tag_len = 1, stop = 1; + break; + default: + tag_len = packet[offset + 1]; + break; + } + + offset += tag_len; + + if (offset >= header->caplen) + return (nproto); /* Invalid packet */ + else { + eth_offset = offset; + goto datalink_check; + } + } + } + } + } + + /* process the packet */ + return (packet_processing(workflow, time, vlan_id, iph, iph6, ip_offset, header->caplen - ip_offset, + header->caplen)); } /* ********************************************************** */ /* http://home.thep.lu.se/~bjorn/crc/crc32_fast.c */ /* ********************************************************** */ -static uint32_t crc32_for_byte(uint32_t r) { - int j; - for(j = 0; j < 8; ++j) - r = (r & 1? 0: (uint32_t)0xEDB88320L) ^ r >> 1; - return r ^ (uint32_t)0xFF000000L; +static uint32_t +crc32_for_byte(uint32_t r) { + int j; + for (j = 0; j < 8; ++j) + r = (r & 1 ? 0 : (uint32_t)0xEDB88320L) ^ r >> 1; + return r ^ (uint32_t)0xFF000000L; } /* Any unsigned integer type with at least 32 bits may be used as @@ -912,36 +926,38 @@ static uint32_t crc32_for_byte(uint32_t r) { * probably the optimal choice for most systems. */ typedef unsigned long accum_t; -static void init_tables(uint32_t* table, uint32_t* wtable) { - size_t i, j, k, w; - for(i = 0; i < 0x100; ++i) - table[i] = crc32_for_byte(i); - for(k = 0; k < sizeof(accum_t); ++k) - for(i = 0; i < 0x100; ++i) { - for(j = w = 0; j < sizeof(accum_t); ++j) - w = table[(uint8_t)(j == k? w ^ i: w)] ^ w >> 8; - wtable[(k << 8) + i] = w ^ (k? wtable[0]: 0); - } +static void +init_tables(uint32_t *table, uint32_t *wtable) { + size_t i, j, k, w; + for (i = 0; i < 0x100; ++i) + table[i] = crc32_for_byte(i); + for (k = 0; k < sizeof(accum_t); ++k) + for (i = 0; i < 0x100; ++i) { + for (j = w = 0; j < sizeof(accum_t); ++j) + w = table[(uint8_t)(j == k ? w ^ i : w)] ^ w >> 8; + wtable[(k << 8) + i] = w ^ (k ? wtable[0] : 0); + } } -static void __crc32(const void* data, size_t n_bytes, uint32_t* crc) { - static uint32_t table[0x100], wtable[0x100*sizeof(accum_t)]; - size_t n_accum = n_bytes/sizeof(accum_t); - size_t i, j; - if(!*table) - init_tables(table, wtable); - for(i = 0; i < n_accum; ++i) { - accum_t a = *crc ^ ((accum_t*)data)[i]; - for(j = *crc = 0; j < sizeof(accum_t); ++j) - *crc ^= wtable[(j << 8) + (uint8_t)(a >> 8*j)]; - } - for(i = n_accum*sizeof(accum_t); i < n_bytes; ++i) - *crc = table[(uint8_t)*crc ^ ((uint8_t*)data)[i]] ^ *crc >> 8; +static void +__crc32(const void *data, size_t n_bytes, uint32_t *crc) { + static uint32_t table[0x100], wtable[0x100 * sizeof(accum_t)]; + size_t n_accum = n_bytes / sizeof(accum_t); + size_t i, j; + if (!*table) + init_tables(table, wtable); + for (i = 0; i < n_accum; ++i) { + accum_t a = *crc ^ ((accum_t *)data)[i]; + for (j = *crc = 0; j < sizeof(accum_t); ++j) + *crc ^= wtable[(j << 8) + (uint8_t)(a >> 8 * j)]; + } + for (i = n_accum * sizeof(accum_t); i < n_bytes; ++i) + *crc = table[(uint8_t)*crc ^ ((uint8_t *)data)[i]] ^ *crc >> 8; } -u_int32_t ethernet_crc32(const void* data, size_t n_bytes) { - u_int32_t crc = 0; - __crc32(data, n_bytes, &crc); - return crc; +u_int32_t +ethernet_crc32(const void *data, size_t n_bytes) { + u_int32_t crc = 0; + __crc32(data, n_bytes, &crc); + return crc; } - diff --git a/examples/ndpi_stats/ndpi_util.h b/examples/ndpi_stats/ndpi_util.h index 6bed00854..5e3b981e2 100644 --- a/examples/ndpi_stats/ndpi_util.h +++ b/examples/ndpi_stats/ndpi_util.h @@ -31,140 +31,142 @@ #include -#define MAX_NUM_READER_THREADS 16 -#define IDLE_SCAN_PERIOD 10 /* msec (use TICK_RESOLUTION = 1000) */ -#define MAX_IDLE_TIME 30000 -#define IDLE_SCAN_BUDGET 1024 -#define NUM_ROOTS 512 -#define MAX_NDPI_FLOWS 200000000 -#define TICK_RESOLUTION 1000 -#define MAX_NUM_IP_ADDRESS 5 /* len of ip address array */ -#define UPDATED_TREE 1 -#define AGGRESSIVE_PERCENT 95.00 -#define DIR_SRC 10 -#define DIR_DST 20 +#define MAX_NUM_READER_THREADS 16 +#define IDLE_SCAN_PERIOD 10 /* msec (use TICK_RESOLUTION = 1000) */ +#define MAX_IDLE_TIME 30000 +#define IDLE_SCAN_BUDGET 1024 +#define NUM_ROOTS 512 +#define MAX_NDPI_FLOWS 200000000 +#define TICK_RESOLUTION 1000 +#define MAX_NUM_IP_ADDRESS 5 /* len of ip address array */ +#define UPDATED_TREE 1 +#define AGGRESSIVE_PERCENT 95.00 +#define DIR_SRC 10 +#define DIR_DST 20 // flow tracking typedef struct ndpi_flow_info { - u_int32_t hashval; - u_int32_t src_ip; - u_int32_t dst_ip; - u_int16_t src_port; - u_int16_t dst_port; - u_int8_t detection_completed, protocol, bidirectional; - u_int16_t vlan_id; - struct ndpi_flow_struct *ndpi_flow; - char src_name[48], dst_name[48]; - u_int8_t ip_version; - u_int64_t last_seen; - u_int64_t src2dst_bytes, dst2src_bytes; - u_int32_t src2dst_packets, dst2src_packets; - - // result only, not used for flow identification - ndpi_protocol detected_protocol; - - char info[96]; - char host_server_name[192]; - char bittorent_hash[41]; - - struct { - char client_info[48], server_info[48]; - } ssh_ssl; - - void *src_id, *dst_id; + u_int32_t hashval; + u_int32_t src_ip; + u_int32_t dst_ip; + u_int16_t src_port; + u_int16_t dst_port; + u_int8_t detection_completed, protocol, bidirectional; + u_int16_t vlan_id; + struct ndpi_flow_struct *ndpi_flow; + char src_name[48], dst_name[48]; + u_int8_t ip_version; + u_int64_t last_seen; + u_int64_t src2dst_bytes, dst2src_bytes; + u_int32_t src2dst_packets, dst2src_packets; + + // result only, not used for flow identification + ndpi_protocol detected_protocol; + + char info[96]; + char host_server_name[192]; + char bittorent_hash[41]; + + struct { + char client_info[48], server_info[48]; + } ssh_ssl; + + void *src_id, *dst_id; } ndpi_flow_info_t; - // flow statistics info typedef struct ndpi_stats { - u_int32_t guessed_flow_protocols; - u_int64_t raw_packet_count; - u_int64_t ip_packet_count; - u_int64_t total_wire_bytes, total_ip_bytes, total_discarded_bytes; - u_int64_t protocol_counter[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; - u_int64_t protocol_counter_bytes[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; - u_int32_t protocol_flows[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; - u_int32_t ndpi_flow_count; - u_int64_t tcp_count, udp_count; - u_int64_t mpls_count, pppoe_count, vlan_count, fragmented_count; - u_int64_t packet_len[6]; - u_int16_t max_packet_len; + u_int32_t guessed_flow_protocols; + u_int64_t raw_packet_count; + u_int64_t ip_packet_count; + u_int64_t total_wire_bytes, total_ip_bytes, total_discarded_bytes; + u_int64_t protocol_counter[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; + u_int64_t protocol_counter_bytes[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; + u_int32_t protocol_flows[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; + u_int32_t ndpi_flow_count; + u_int64_t tcp_count, udp_count; + u_int64_t mpls_count, pppoe_count, vlan_count, fragmented_count; + u_int64_t packet_len[6]; + u_int16_t max_packet_len; } ndpi_stats_t; - // flow preferences typedef struct ndpi_workflow_prefs { - u_int8_t decode_tunnels; - u_int8_t quiet_mode; - u_int32_t num_roots; - u_int32_t max_ndpi_flows; + u_int8_t decode_tunnels; + u_int8_t quiet_mode; + u_int32_t num_roots; + u_int32_t max_ndpi_flows; } ndpi_workflow_prefs_t; struct ndpi_workflow; /** workflow, flow, user data */ -typedef void (*ndpi_workflow_callback_ptr) (struct ndpi_workflow *, struct ndpi_flow_info *, void *); - +typedef void (*ndpi_workflow_callback_ptr)(struct ndpi_workflow *, struct ndpi_flow_info *, void *); // workflow main structure typedef struct ndpi_workflow { - u_int64_t last_time; + u_int64_t last_time; - struct ndpi_workflow_prefs prefs; - struct ndpi_stats stats; + struct ndpi_workflow_prefs prefs; + struct ndpi_stats stats; - ndpi_workflow_callback_ptr __flow_detected_callback; - void * __flow_detected_udata; - ndpi_workflow_callback_ptr __flow_giveup_callback; - void * __flow_giveup_udata; + ndpi_workflow_callback_ptr __flow_detected_callback; + void *__flow_detected_udata; + ndpi_workflow_callback_ptr __flow_giveup_callback; + void *__flow_giveup_udata; - /* outside referencies */ - pcap_t *pcap_handle; + /* outside referencies */ + pcap_t *pcap_handle; - /* allocated by prefs */ - void **ndpi_flows_root; - struct ndpi_detection_module_struct *ndpi_struct; + /* allocated by prefs */ + void **ndpi_flows_root; + struct ndpi_detection_module_struct *ndpi_struct; } ndpi_workflow_t; - /* TODO: remove wrappers parameters and use ndpi global, when their initialization will be fixed... */ -struct ndpi_workflow * ndpi_workflow_init(const struct ndpi_workflow_prefs * prefs, pcap_t * pcap_handle); - - - /* workflow main free function */ -void ndpi_workflow_free(struct ndpi_workflow * workflow); +struct ndpi_workflow * +ndpi_workflow_init(const struct ndpi_workflow_prefs *prefs, pcap_t *pcap_handle); +/* workflow main free function */ +void +ndpi_workflow_free(struct ndpi_workflow *workflow); /** Free flow_info ndpi support structures but not the flow_info itself * * TODO remove! Half freeing things is bad! */ -void ndpi_free_flow_info_half(struct ndpi_flow_info *flow); - +void +ndpi_free_flow_info_half(struct ndpi_flow_info *flow); /* Process a packet and update the workflow */ -struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow, - const struct pcap_pkthdr *header, - const u_char *packet); - +struct ndpi_proto +ndpi_workflow_process_packet(struct ndpi_workflow *workflow, const struct pcap_pkthdr *header, const u_char *packet); /* flow callbacks for complete detected flow (ndpi_flow_info will be freed right after) */ -static inline void ndpi_workflow_set_flow_detected_callback(struct ndpi_workflow * workflow, ndpi_workflow_callback_ptr callback, void * udata) { - workflow->__flow_detected_callback = callback; - workflow->__flow_detected_udata = udata; +static inline void +ndpi_workflow_set_flow_detected_callback(struct ndpi_workflow *workflow, ndpi_workflow_callback_ptr callback, + void *udata) { + workflow->__flow_detected_callback = callback; + workflow->__flow_detected_udata = udata; } /* flow callbacks for sufficient detected flow (ndpi_flow_info will be freed right after) */ -static inline void ndpi_workflow_set_flow_giveup_callback(struct ndpi_workflow * workflow, ndpi_workflow_callback_ptr callback, void * udata) { - workflow->__flow_giveup_callback = callback; - workflow->__flow_giveup_udata = udata; +static inline void +ndpi_workflow_set_flow_giveup_callback(struct ndpi_workflow *workflow, ndpi_workflow_callback_ptr callback, + void *udata) { + workflow->__flow_giveup_callback = callback; + workflow->__flow_giveup_udata = udata; } - /* compare two nodes in workflow */ -int ndpi_workflow_node_cmp(const void *a, const void *b); -void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_flow_info *flow); -u_int32_t ethernet_crc32(const void* data, size_t n_bytes); -void ndpi_flow_info_freer(void *node); +/* compare two nodes in workflow */ +int +ndpi_workflow_node_cmp(const void *a, const void *b); +void +process_ndpi_collected_info(struct ndpi_workflow *workflow, struct ndpi_flow_info *flow); +u_int32_t +ethernet_crc32(const void *data, size_t n_bytes); +void +ndpi_flow_info_freer(void *node); #endif diff --git a/examples/nf_router/nf_router.c b/examples/nf_router/nf_router.c index 51a40d8f9..f8089c8eb 100644 --- a/examples/nf_router/nf_router.c +++ b/examples/nf_router/nf_router.c @@ -38,22 +38,22 @@ * nf_router.c - route packets based on the provided config. ********************************************************************/ -#include -#include -#include +#include +#include #include #include -#include -#include +#include +#include #include -#include #include +#include +#include +#include #include -#include #include -#include #include +#include #include "onvm_nflib.h" #include "onvm_pkt_helper.h" @@ -62,7 +62,7 @@ /* router information */ uint8_t nf_count; -char * cfg_filename; +char *cfg_filename; struct forward_nf *fwd_nf; struct forward_nf { @@ -76,7 +76,6 @@ struct onvm_nf_info *nf_info; /* number of package between each print */ static uint32_t print_delay = 1000000; - /* * Print a usage message */ @@ -99,26 +98,26 @@ parse_app_args(int argc, char *argv[], const char *progname) { while ((c = getopt(argc, argv, "f:p:")) != -1) { switch (c) { - case 'f': - cfg_filename = strdup(optarg); - break; - case 'p': - print_delay = strtoul(optarg, NULL, 10); - break; - case '?': - usage(progname); - if (optopt == 'd') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (optopt == 'p') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (isprint(optopt)) - RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); - else - RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); - return -1; - default: - usage(progname); - return -1; + case 'f': + cfg_filename = strdup(optarg); + break; + case 'p': + print_delay = strtoul(optarg, NULL, 10); + break; + case '?': + usage(progname); + if (optopt == 'd') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (optopt == 'p') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (isprint(optopt)) + RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); + else + RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); + return -1; + default: + usage(progname); + return -1; } } @@ -126,17 +125,17 @@ parse_app_args(int argc, char *argv[], const char *progname) { } /* - * This function parses the forward config. It takes the filename - * and fills up the forward nf array. This includes the ip and dest + * This function parses the forward config. It takes the filename + * and fills up the forward nf array. This includes the ip and dest * address of the onvm_nf */ static int parse_router_config(void) { int ret, temp, i; char ip[32]; - FILE * cfg; + FILE *cfg; - cfg = fopen(cfg_filename, "r"); + cfg = fopen(cfg_filename, "r"); if (cfg == NULL) { rte_exit(EXIT_FAILURE, "Error openning server \'%s\' config\n", cfg_filename); } @@ -169,17 +168,16 @@ parse_router_config(void) { } fclose(cfg); - printf("\nDest config (%d):\n",nf_count); + printf("\nDest config (%d):\n", nf_count); for (i = 0; i < nf_count; i++) { - printf("%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 " ", - fwd_nf[i].ip & 0xFF, (fwd_nf[i].ip >> 8) & 0xFF, (fwd_nf[i].ip >> 16) & 0xFF, (fwd_nf[i].ip >> 24) & 0xFF); + printf("%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 " ", fwd_nf[i].ip & 0xFF, (fwd_nf[i].ip >> 8) & 0xFF, + (fwd_nf[i].ip >> 16) & 0xFF, (fwd_nf[i].ip >> 24) & 0xFF); printf(" %d\n", fwd_nf[i].dest); } return ret; } - /* * This function displays stats. It uses ANSI terminal codes to clear * screen when called. It is called from a single non-master @@ -187,11 +185,11 @@ parse_router_config(void) { * than one lcore enabled. */ static void -do_stats_display(struct rte_mbuf* pkt) { - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; +do_stats_display(struct rte_mbuf *pkt) { + const char clr[] = {27, '[', '2', 'J', '\0'}; + const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'}; static uint64_t pkt_process = 0; - struct ipv4_hdr* ip; + struct ipv4_hdr *ip; pkt_process += print_delay; @@ -202,7 +200,7 @@ do_stats_display(struct rte_mbuf* pkt) { printf("-----\n"); printf("Port : %d\n", pkt->port); printf("Size : %d\n", pkt->pkt_len); - printf("N° : %"PRIu64"\n", pkt_process); + printf("N° : %" PRIu64 "\n", pkt_process); printf("\n\n"); ip = onvm_pkt_ipv4_hdr(pkt); @@ -218,7 +216,7 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( static uint32_t counter = 0; struct ether_hdr *eth_hdr; struct arp_hdr *in_arp_hdr; - struct ipv4_hdr* ip; + struct ipv4_hdr *ip; int i; ip = onvm_pkt_ipv4_hdr(pkt); @@ -260,8 +258,8 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( return 0; } - -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; diff --git a/examples/scaling_example/scaling.c b/examples/scaling_example/scaling.c index be45b65f0..44ff7528d 100644 --- a/examples/scaling_example/scaling.c +++ b/examples/scaling_example/scaling.c @@ -38,36 +38,36 @@ * scaling.c - Example usage of the provided scaling functionality. ********************************************************************/ -#include -#include -#include +#include +#include #include +#include #include -#include -#include +#include +#include #include -#include #include -#include +#include +#include #include -#include -#include -#include #include -#include #include #include +#include #include +#include +#include +#include +#include "onvm_flow_table.h" #include "onvm_nflib.h" #include "onvm_pkt_helper.h" -#include "onvm_flow_table.h" #define NF_TAG "scaling" #define PKTMBUF_POOL_NAME "MProc_pktmbuf_pool" -#define PKT_READ_SIZE ((uint16_t)32) +#define PKT_READ_SIZE ((uint16_t)32) #define LOCAL_EXPERIMENTAL_ETHER 0x88B5 #define DEFAULT_PKT_NUM 128 #define MAX_PKT_NUM NF_QUEUE_RINGSIZE @@ -82,7 +82,8 @@ static uint8_t d_addr_bytes[ETHER_ADDR_LEN]; static uint16_t packet_size = ETHER_HDR_LEN; static uint32_t packet_number = DEFAULT_PKT_NUM; -void nf_setup(struct onvm_nf_info *nf_info); +void +nf_setup(struct onvm_nf_info *nf_info); /* * Print a usage message @@ -107,30 +108,31 @@ parse_app_args(int argc, char *argv[], const char *progname) { while ((c = getopt(argc, argv, "d:n:p:a")) != -1) { switch (c) { - case 'a': - use_direct_rings = 1; - break; - case 'd': - destination = strtoul(optarg, NULL, 10); - dst_flag = 1; - break; - case 'n': - num_children = strtoul(optarg, NULL, 10); - if (num_children < DEFAULT_NUM_CHILDREN) { - printf("The number of children should be more or equal than %d\n", DEFAULT_NUM_CHILDREN); + case 'a': + use_direct_rings = 1; + break; + case 'd': + destination = strtoul(optarg, NULL, 10); + dst_flag = 1; + break; + case 'n': + num_children = strtoul(optarg, NULL, 10); + if (num_children < DEFAULT_NUM_CHILDREN) { + printf("The number of children should be more or equal than %d\n", + DEFAULT_NUM_CHILDREN); + return -1; + } + break; + case '?': + usage(progname); + if (isprint(optopt)) + RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); + else + RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); + return -1; + default: + usage(progname); return -1; - } - break; - case '?': - usage(progname); - if (isprint(optopt)) - RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); - else - RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); - return -1; - default: - usage(progname); - return -1; } } @@ -146,7 +148,8 @@ parse_app_args(int argc, char *argv[], const char *progname) { * Basic packet handler, just forwards all packets */ static int -packet_handler_fwd(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__((unused)) struct onvm_nf_info *nf_info) { +packet_handler_fwd(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, + __attribute__((unused)) struct onvm_nf_info *nf_info) { (void)pkt; meta->destination = *(uint16_t *)nf_info->data; meta->action = ONVM_NF_ACTION_TONF; @@ -158,7 +161,8 @@ packet_handler_fwd(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute * Child packet handler showcasing that children can also spawn NFs on their own */ static int -packet_handler_child(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__((unused)) struct onvm_nf_info *nf_info) { +packet_handler_child(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, + __attribute__((unused)) struct onvm_nf_info *nf_info) { (void)pkt; /* As this is already a child, 1 NF has been spawned */ static int spawned_nfs = 1; @@ -169,7 +173,7 @@ packet_handler_child(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribu while (spawned_nfs < num_children) { struct onvm_nf_scale_info *scale_info = onvm_nflib_get_empty_scaling_config(nf_info); uint16_t *state_data = rte_malloc("nf_state_data", sizeof(uint16_t), 0); - *state_data = nf_info->service_id; + *state_data = nf_info->service_id; /* Sets service id of child */ scale_info->service_id = destination; /* Run the setup function to generate packets */ @@ -181,7 +185,8 @@ packet_handler_child(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribu /* Spawn the child */ if (onvm_nflib_scale(scale_info) == 0) - RTE_LOG(INFO, APP, "Spawning child SID %u; with packet_handler_fwd packet function\n", scale_info->service_id); + RTE_LOG(INFO, APP, "Spawning child SID %u; with packet_handler_fwd packet function\n", + scale_info->service_id); else rte_exit(EXIT_FAILURE, "Can't spawn child\n"); spawned_nfs++; @@ -200,7 +205,7 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( struct onvm_nf_scale_info *scale_info; void *data; - /* Testing NF scaling, Spawns one child */ + /* Testing NF scaling, Spawns one child */ if (spawned_child == 0) { spawned_child = 1; @@ -214,7 +219,8 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( /* Spawn the child */ if (onvm_nflib_scale(scale_info) == 0) - RTE_LOG(INFO, APP, "Spawning child SID %u; with packet_handler_child packet function\n", scale_info->service_id); + RTE_LOG(INFO, APP, "Spawning child SID %u; with packet_handler_child packet function\n", + scale_info->service_id); else rte_exit(EXIT_FAILURE, "Can't initialize the first child!\n"); } @@ -225,7 +231,6 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( return 0; } - static void handle_signal(int sig) { if (sig == SIGINT || sig == SIGTERM) @@ -235,7 +240,7 @@ handle_signal(int sig) { static void run_advanced_rings(struct onvm_nf_info *nf_info) { void *pkts[PKT_READ_SIZE]; - struct onvm_pkt_meta* meta; + struct onvm_pkt_meta *meta; uint16_t i, j, nb_pkts; void *pktsTX[PKT_READ_SIZE]; int tx_batch_size; @@ -261,7 +266,8 @@ run_advanced_rings(struct onvm_nf_info *nf_info) { /* Testing NF scaling */ if (spawned_nfs == 0) { - /* As this is advanced rings if we want the children to inherit the same function we need to set it first */ + /* As this is advanced rings if we want the children to inherit the same function we need to set it + * first */ nf->nf_advanced_rings_function = &run_advanced_rings; struct onvm_nf_scale_info *scale_info; @@ -272,7 +278,8 @@ run_advanced_rings(struct onvm_nf_info *nf_info) { *(uint16_t *)data = destination; /* Get the filled in scale struct by inheriting parent properties */ scale_info = onvm_nflib_inherit_parent_config(nf_info, data); - RTE_LOG(INFO, APP, "Tring to spawn child SID %u; running advanced_rings\n", scale_info->service_id); + RTE_LOG(INFO, APP, "Tring to spawn child SID %u; running advanced_rings\n", + scale_info->service_id); if (onvm_nflib_scale(scale_info) == 0) RTE_LOG(INFO, APP, "Spawning child SID %u\n", scale_info->service_id); else @@ -281,7 +288,6 @@ run_advanced_rings(struct onvm_nf_info *nf_info) { } } - while (keep_running && rx_ring && tx_ring && nf) { tx_batch_size = 0; /* Dequeue all packets in ring up to max possible. */ @@ -292,8 +298,8 @@ run_advanced_rings(struct onvm_nf_info *nf_info) { } /* Process all the packets */ for (i = 0; i < nb_pkts; i++) { - meta = onvm_get_pkt_meta((struct rte_mbuf*)pkts[i]); - packet_handler_fwd((struct rte_mbuf*)pkts[i], meta, nf_info); + meta = onvm_get_pkt_meta((struct rte_mbuf *)pkts[i]); + packet_handler_fwd((struct rte_mbuf *)pkts[i], meta, nf_info); pktsTX[tx_batch_size++] = pkts[i]; } @@ -309,14 +315,13 @@ run_advanced_rings(struct onvm_nf_info *nf_info) { /* Waiting for spawned NFs to exit */ for (i = 0; i < MAX_NFS; i++) { struct onvm_nf *nf_cur = onvm_nflib_get_nf(i); - while(nf_cur && nf_cur->parent == nf->instance_id && nf_cur->info != NULL) { + while (nf_cur && nf_cur->parent == nf->instance_id && nf_cur->info != NULL) { sleep(1); } } onvm_nflib_stop(nf_info); } - /* * Generates fake packets or loads them from a pcap file */ @@ -332,14 +337,14 @@ nf_setup(__attribute__((unused)) struct onvm_nf_info *nf_info) { } for (i = 0; i < packet_number; ++i) { - struct onvm_pkt_meta* pmeta; + struct onvm_pkt_meta *pmeta; struct ether_hdr *ehdr; int j; struct rte_mbuf *pkt = rte_pktmbuf_alloc(pktmbuf_pool); /* set up ether header and set new packet size */ - ehdr = (struct ether_hdr *) rte_pktmbuf_append(pkt, packet_size); + ehdr = (struct ether_hdr *)rte_pktmbuf_append(pkt, packet_size); /* Using manager mac addr for source*/ rte_eth_macaddr_get(0, &ehdr->s_addr); @@ -358,7 +363,8 @@ nf_setup(__attribute__((unused)) struct onvm_nf_info *nf_info) { } } -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; struct onvm_nf_info *nf_info; @@ -379,7 +385,7 @@ int main(int argc, char *argv[]) { onvm_nflib_set_setup_function(nf_info, &nf_setup); nf_info->data = (void *)rte_malloc("nf_specific_data", sizeof(uint16_t), 0); - *(uint16_t*)nf_info->data = nf_info->service_id; + *(uint16_t *)nf_info->data = nf_info->service_id; if (use_direct_rings) { printf("\nRUNNING ADVANCED RINGS EXPERIMENT\n"); diff --git a/examples/simple_forward/forward.c b/examples/simple_forward/forward.c index fce24b8b2..b69d34fa4 100644 --- a/examples/simple_forward/forward.c +++ b/examples/simple_forward/forward.c @@ -38,20 +38,20 @@ * forward.c - an example using onvm. Forwards packets to a DST NF. ********************************************************************/ -#include -#include -#include +#include +#include #include #include -#include -#include +#include +#include #include -#include #include +#include +#include #include -#include #include +#include #include "onvm_nflib.h" #include "onvm_pkt_helper.h" @@ -64,7 +64,6 @@ struct onvm_nf_info *nf_info; /* number of package between each print */ static uint32_t print_delay = 1000000; - static uint32_t destination; /* @@ -89,27 +88,27 @@ parse_app_args(int argc, char *argv[], const char *progname) { while ((c = getopt(argc, argv, "d:p:")) != -1) { switch (c) { - case 'd': - destination = strtoul(optarg, NULL, 10); - dst_flag = 1; - break; - case 'p': - print_delay = strtoul(optarg, NULL, 10); - break; - case '?': - usage(progname); - if (optopt == 'd') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (optopt == 'p') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (isprint(optopt)) - RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); - else - RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); - return -1; - default: - usage(progname); - return -1; + case 'd': + destination = strtoul(optarg, NULL, 10); + dst_flag = 1; + break; + case 'p': + print_delay = strtoul(optarg, NULL, 10); + break; + case '?': + usage(progname); + if (optopt == 'd') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (optopt == 'p') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (isprint(optopt)) + RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); + else + RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); + return -1; + default: + usage(progname); + return -1; } } @@ -128,11 +127,11 @@ parse_app_args(int argc, char *argv[], const char *progname) { * than one lcore enabled. */ static void -do_stats_display(struct rte_mbuf* pkt) { - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; +do_stats_display(struct rte_mbuf *pkt) { + const char clr[] = {27, '[', '2', 'J', '\0'}; + const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'}; static uint64_t pkt_process = 0; - struct ipv4_hdr* ip; + struct ipv4_hdr *ip; pkt_process += print_delay; @@ -143,7 +142,7 @@ do_stats_display(struct rte_mbuf* pkt) { printf("-----\n"); printf("Port : %d\n", pkt->port); printf("Size : %d\n", pkt->pkt_len); - printf("N° : %"PRIu64"\n", pkt_process); + printf("N° : %" PRIu64 "\n", pkt_process); printf("\n\n"); ip = onvm_pkt_ipv4_hdr(pkt); @@ -167,8 +166,8 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( return 0; } - -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; diff --git a/examples/speed_tester/speed_tester.c b/examples/speed_tester/speed_tester.c index 808ebf29e..a62899327 100644 --- a/examples/speed_tester/speed_tester.c +++ b/examples/speed_tester/speed_tester.c @@ -38,39 +38,39 @@ * speed_tester.c - create pkts and loop through NFs. ********************************************************************/ -#include -#include -#include +#include +#include #include +#include #include -#include -#include +#include +#include #include -#include #include -#include +#include +#include #include -#include -#include -#include #include -#include #include #include +#include +#include +#include +#include #ifdef LIBPCAP #include #endif +#include "onvm_flow_table.h" #include "onvm_nflib.h" #include "onvm_pkt_helper.h" -#include "onvm_flow_table.h" #define NF_TAG "speed" #define PKTMBUF_POOL_NAME "MProc_pktmbuf_pool" -#define PKT_READ_SIZE ((uint16_t)32) +#define PKT_READ_SIZE ((uint16_t)32) #define SPEED_TESTER_BIT 7 #define LATENCY_BIT 6 #define LOCAL_EXPERIMENTAL_ETHER 0x88B5 @@ -108,7 +108,8 @@ static uint64_t total_latency = 0; */ char *pcap_filename = NULL; -void nf_setup(struct onvm_nf_info *nf_info); +void +nf_setup(struct onvm_nf_info *nf_info); /* * Print a usage message @@ -116,19 +117,29 @@ void nf_setup(struct onvm_nf_info *nf_info); static void usage(const char *progname) { printf("Usage:\n"); - printf("%s [EAL args] -- [NF_LIB args] -- -d [-p ] " - "[-a] [-s ] [-m ] [-o ] " - "[-c ] [-l]\n", progname); + printf( + "%s [EAL args] -- [NF_LIB args] -- -d [-p ] " + "[-a] [-s ] [-m ] [-o ] " + "[-c ] [-l]\n", + progname); printf("%s -F [EAL args] -- [NF_LIB args] -- [NF args]\n\n", progname); printf("Flags:\n"); printf(" - `-d DST`: Destination Service ID to foward to\n"); printf(" - `-a`: Use advanced rings interface instead of default `packet_handler`\n"); printf(" - `-p PRINT_DELAY`: Number of packets between each print, e.g. `-p 1` prints every packets.\n"); - printf(" - `-s PACKET_SIZE`: Size of packet, e.g. `-s 32` allocates 32 bytes for the data segment of `rte_mbuf`.\n"); - printf(" - `-m DEST_MAC`: User specified destination MAC address, e.g. `-m aa:bb:cc:dd:ee:ff` sets the destination address within the ethernet header that is located at the start of the packet data.\n"); + printf( + " - `-s PACKET_SIZE`: Size of packet, e.g. `-s 32` allocates 32 bytes for the data segment of " + "`rte_mbuf`.\n"); + printf( + " - `-m DEST_MAC`: User specified destination MAC address, e.g. `-m aa:bb:cc:dd:ee:ff` sets the " + "destination address within the ethernet header that is located at the start of the packet data.\n"); printf(" - `-o PCAP_FILENAME` : The filename of the pcap file to replay\n"); - printf(" - `-l LATENCY` : Enable latency measurement. This should only be enabled on one Speed Tester NF. Packets must be routed back to the same speed tester NF.\n"); - printf(" - `-c PACKET_NUMBER` : Use user specified number of packets in the batch. If not specified then this defaults to 128.\n"); + printf( + " - `-l LATENCY` : Enable latency measurement. This should only be enabled on one Speed Tester NF. Packets " + "must be routed back to the same speed tester NF.\n"); + printf( + " - `-c PACKET_NUMBER` : Use user specified number of packets in the batch. If not specified then this " + "defaults to 128.\n"); } /* @@ -141,78 +152,73 @@ parse_app_args(int argc, char *argv[], const char *progname) { while ((c = getopt(argc, argv, "d:p:as:m:o:c:l")) != -1) { switch (c) { - case 'a': - use_direct_rings = 1; - break; - case 'd': - destination = strtoul(optarg, NULL, 10); - dst_flag = 1; - break; - case 'p': - print_delay = strtoul(optarg, NULL, 10); - break; - case 's': - packet_size = strtoul(optarg, NULL, 10); - break; - case 'm': - count = sscanf(optarg, - "%x:%x:%x:%x:%x:%x", - &values[0], - &values[1], - &values[2], - &values[3], - &values[4], - &values[5]); - if (count == ETHER_ADDR_LEN) { - for (i = 0; i < ETHER_ADDR_LEN; ++i) { - d_addr_bytes[i] = (uint8_t) values[i]; + case 'a': + use_direct_rings = 1; + break; + case 'd': + destination = strtoul(optarg, NULL, 10); + dst_flag = 1; + break; + case 'p': + print_delay = strtoul(optarg, NULL, 10); + break; + case 's': + packet_size = strtoul(optarg, NULL, 10); + break; + case 'm': + count = sscanf(optarg, "%x:%x:%x:%x:%x:%x", &values[0], &values[1], &values[2], + &values[3], &values[4], &values[5]); + if (count == ETHER_ADDR_LEN) { + for (i = 0; i < ETHER_ADDR_LEN; ++i) { + d_addr_bytes[i] = (uint8_t)values[i]; + } + } else { + usage(progname); + return -1; } - } else { - usage(progname); - return -1; - } - break; - case 'o': + break; + case 'o': #ifdef LIBPCAP - pcap_filename = strdup(optarg); - break; + pcap_filename = strdup(optarg); + break; #else - rte_exit(EXIT_FAILURE, "To enable pcap replay follow the README " - "instructins\n"); - break; + rte_exit(EXIT_FAILURE, + "To enable pcap replay follow the README " + "instructins\n"); + break; #endif - case 'c': - use_custom_pkt_count = 1; - packet_number = strtoul(optarg, NULL, 10); - if (packet_number > MAX_PKT_NUM) { - RTE_LOG(INFO, APP, "Illegal packet number(1 ~ %u) %u!\n", - MAX_PKT_NUM, packet_number); + case 'c': + use_custom_pkt_count = 1; + packet_number = strtoul(optarg, NULL, 10); + if (packet_number > MAX_PKT_NUM) { + RTE_LOG(INFO, APP, "Illegal packet number(1 ~ %u) %u!\n", MAX_PKT_NUM, + packet_number); + return -1; + } + break; + case 'l': + measure_latency = 1; + break; + case '?': + usage(progname); + if (optopt == 'd') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (optopt == 'p') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (optopt == 's') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (optopt == 'm') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (optopt == 'c') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (isprint(optopt)) + RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); + else + RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); + return -1; + default: + usage(progname); return -1; - } - break; - case 'l': - measure_latency = 1; - break; - case '?': - usage(progname); - if (optopt == 'd') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (optopt == 'p') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (optopt == 's') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (optopt == 'm') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (optopt == 'c') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (isprint(optopt)) - RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); - else - RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); - return -1; - default: - usage(progname); - return -1; } } @@ -231,12 +237,12 @@ parse_app_args(int argc, char *argv[], const char *progname) { * than one lcore enabled. */ static void -do_stats_display(struct rte_mbuf* pkt) { +do_stats_display(struct rte_mbuf *pkt) { static uint64_t last_cycles; static uint64_t cur_pkts = 0; static uint64_t last_pkts = 0; - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; + const char clr[] = {27, '[', '2', 'J', '\0'}; + const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'}; (void)pkt; uint64_t cur_cycles = rte_get_tsc_cycles(); @@ -245,12 +251,12 @@ do_stats_display(struct rte_mbuf* pkt) { /* Clear screen and move to top left */ printf("%s%s", clr, topLeft); - printf("Total packets: %9"PRIu64" \n", cur_pkts); - printf("TX pkts per second: %9"PRIu64" \n", (cur_pkts - last_pkts) - * rte_get_timer_hz() / (cur_cycles - last_cycles)); + printf("Total packets: %9" PRIu64 " \n", cur_pkts); + printf("TX pkts per second: %9" PRIu64 " \n", + (cur_pkts - last_pkts) * rte_get_timer_hz() / (cur_cycles - last_cycles)); if (measure_latency && latency_packets > 0) - printf("Avg latency nanoseconds: %6"PRIu64" \n", total_latency/(latency_packets) - * 1000000000 / rte_get_timer_hz()); + printf("Avg latency nanoseconds: %6" PRIu64 " \n", + total_latency / (latency_packets)*1000000000 / rte_get_timer_hz()); printf("Initial packets created: %u\n", packet_number); total_latency = 0; @@ -276,7 +282,7 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( meta->action = ONVM_NF_ACTION_TONF; if (measure_latency && ONVM_CHECK_BIT(meta->flags, LATENCY_BIT)) { uint64_t curtime = rte_get_tsc_cycles(); - uint64_t* oldtime = (uint64_t *)(rte_pktmbuf_mtod(pkt, uint8_t *) + packet_size); + uint64_t *oldtime = (uint64_t *)(rte_pktmbuf_mtod(pkt, uint8_t *) + packet_size); if (*oldtime != 0) { total_latency += curtime - *oldtime; latency_packets++; @@ -290,18 +296,16 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__(( return 0; } - static void handle_signal(int sig) { if (sig == SIGINT || sig == SIGTERM) keep_running = 0; } - static void run_advanced_rings(struct onvm_nf_info *nf_info) { void *pkts[PKT_READ_SIZE]; - struct onvm_pkt_meta* meta; + struct onvm_pkt_meta *meta; uint16_t i, j, nb_pkts; void *pktsTX[PKT_READ_SIZE]; int tx_batch_size; @@ -335,8 +339,8 @@ run_advanced_rings(struct onvm_nf_info *nf_info) { } /* Process all the packets */ for (i = 0; i < nb_pkts; i++) { - meta = onvm_get_pkt_meta((struct rte_mbuf*)pkts[i]); - packet_handler((struct rte_mbuf*)pkts[i], meta, nf_info); + meta = onvm_get_pkt_meta((struct rte_mbuf *)pkts[i]); + packet_handler((struct rte_mbuf *)pkts[i], meta, nf_info); pktsTX[tx_batch_size++] = pkts[i]; } @@ -352,7 +356,6 @@ run_advanced_rings(struct onvm_nf_info *nf_info) { onvm_nflib_stop(nf_info); } - /* * Generates fake packets or loads them from a pcap file */ @@ -368,7 +371,7 @@ nf_setup(struct onvm_nf_info *nf_info) { } #ifdef LIBPCAP - struct rte_mbuf* pkt; + struct rte_mbuf *pkt; pcap_t *pcap; const u_char *packet; struct pcap_pkthdr header; @@ -383,11 +386,11 @@ nf_setup(struct onvm_nf_info *nf_info) { rte_exit(EXIT_FAILURE, "Cannot open pcap file\n"); } - packet_number = (packet_number? packet_number : MAX_PKT_NUM); + packet_number = (packet_number ? packet_number : MAX_PKT_NUM); i = 0; while (((packet = pcap_next(pcap, &header)) != NULL) && (i++ < packet_number)) { - struct onvm_pkt_meta* pmeta; + struct onvm_pkt_meta *pmeta; struct onvm_ft_ipv4_5tuple key; pkt = rte_pktmbuf_alloc(pktmbuf_pool); @@ -398,7 +401,7 @@ nf_setup(struct onvm_nf_info *nf_info) { pkt->data_len = header.caplen; /* Copy the packet into the rte_mbuf data section */ - rte_memcpy(rte_pktmbuf_mtod(pkt, char*), packet, header.caplen); + rte_memcpy(rte_pktmbuf_mtod(pkt, char *), packet, header.caplen); pmeta = onvm_get_pkt_meta(pkt); pmeta->destination = destination; @@ -419,7 +422,7 @@ nf_setup(struct onvm_nf_info *nf_info) { struct rte_mbuf *pkts[packet_number]; for (i = 0; i < packet_number; ++i) { - struct onvm_pkt_meta* pmeta; + struct onvm_pkt_meta *pmeta; struct ether_hdr *ehdr; int j; @@ -430,7 +433,7 @@ nf_setup(struct onvm_nf_info *nf_info) { } /*set up ether header and set new packet size*/ - ehdr = (struct ether_hdr *) rte_pktmbuf_append(pkt, packet_size); + ehdr = (struct ether_hdr *)rte_pktmbuf_append(pkt, packet_size); /*using manager mac addr for source *using input string for dest addr @@ -448,9 +451,10 @@ nf_setup(struct onvm_nf_info *nf_info) { pkt->hash.rss = i; pkt->port = 0; - if (measure_latency && (packet_number < DEFAULT_LAT_PKT_NUM || i % (packet_number/DEFAULT_LAT_PKT_NUM) == 0)) { + if (measure_latency && + (packet_number < DEFAULT_LAT_PKT_NUM || i % (packet_number / DEFAULT_LAT_PKT_NUM) == 0)) { pmeta->flags |= ONVM_SET_BIT(0, LATENCY_BIT); - uint64_t* ts = (uint64_t *) rte_pktmbuf_append(pkt, sizeof(uint64_t)); + uint64_t *ts = (uint64_t *)rte_pktmbuf_append(pkt, sizeof(uint64_t)); *ts = 0; } pkts[i] = pkt; @@ -461,7 +465,8 @@ nf_setup(struct onvm_nf_info *nf_info) { #endif } -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; diff --git a/examples/test_flow_dir/test_flow_dir.c b/examples/test_flow_dir/test_flow_dir.c index a66e21f52..7c6636770 100644 --- a/examples/test_flow_dir/test_flow_dir.c +++ b/examples/test_flow_dir/test_flow_dir.c @@ -38,30 +38,30 @@ * test_flow_dir.c - an example using onvm_flow_dir_* APIs. ********************************************************************/ -#include -#include -#include +#include +#include +#include #include #include -#include -#include +#include +#include #include -#include #include -#include +#include +#include #include -#include #include #include -#include +#include #include +#include +#include "onvm_flow_dir.h" +#include "onvm_flow_table.h" #include "onvm_nflib.h" #include "onvm_pkt_helper.h" -#include "onvm_flow_table.h" #include "onvm_sc_common.h" -#include "onvm_flow_dir.h" #include "onvm_sc_mgr.h" #define NF_TAG "test_flow_dir" @@ -96,26 +96,26 @@ parse_app_args(int argc, char *argv[], const char *progname) { while ((c = getopt(argc, argv, "d:p:")) != -1) { switch (c) { - case 'd': - destination = strtoul(optarg, NULL, 10); - break; - case 'p': - print_delay = strtoul(optarg, NULL, 10); - break; - case '?': - usage(progname); - if (optopt == 'd') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (optopt == 'p') - RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); - else if (isprint(optopt)) - RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); - else - RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); - return -1; - default: - usage(progname); - return -1; + case 'd': + destination = strtoul(optarg, NULL, 10); + break; + case 'p': + print_delay = strtoul(optarg, NULL, 10); + break; + case '?': + usage(progname); + if (optopt == 'd') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (optopt == 'p') + RTE_LOG(INFO, APP, "Option -%c requires an argument.\n", optopt); + else if (isprint(optopt)) + RTE_LOG(INFO, APP, "Unknown option `-%c'.\n", optopt); + else + RTE_LOG(INFO, APP, "Unknown option character `\\x%x'.\n", optopt); + return -1; + default: + usage(progname); + return -1; } } return optind; @@ -128,11 +128,11 @@ parse_app_args(int argc, char *argv[], const char *progname) { * than one lcore enabled. */ static void -do_stats_display(struct rte_mbuf* pkt) { - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; +do_stats_display(struct rte_mbuf *pkt) { + const char clr[] = {27, '[', '2', 'J', '\0'}; + const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'}; static uint64_t pkt_process = 0; - struct ipv4_hdr* ip; + struct ipv4_hdr *ip; pkt_process += print_delay; @@ -143,7 +143,7 @@ do_stats_display(struct rte_mbuf* pkt) { printf("-----\n"); printf("Port : %d\n", pkt->port); printf("Size : %d\n", pkt->pkt_len); - printf("N° : %"PRIu64"\n", pkt_process); + printf("N° : %" PRIu64 "\n", pkt_process); printf("\n\n"); ip = onvm_pkt_ipv4_hdr(pkt); @@ -157,33 +157,34 @@ do_stats_display(struct rte_mbuf* pkt) { static int packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__((unused)) struct onvm_nf_info *nf_info) { static uint32_t counter = 0; - struct onvm_flow_entry *flow_entry = NULL; - int ret; + struct onvm_flow_entry *flow_entry = NULL; + int ret; - if (++counter == print_delay) { + if (++counter == print_delay) { do_stats_display(pkt); counter = 0; } - ret = onvm_flow_dir_get_pkt(pkt, &flow_entry); - if (ret >= 0) { - meta->action = ONVM_NF_ACTION_NEXT; - } else { - ret = onvm_flow_dir_add_pkt(pkt, &flow_entry); - if (ret < 0) { - meta->action = ONVM_NF_ACTION_DROP; - meta->destination = 0; - return 0; - } - memset(flow_entry, 0, sizeof(struct onvm_flow_entry)); - flow_entry->sc = onvm_sc_create(); - onvm_sc_append_entry(flow_entry->sc, ONVM_NF_ACTION_TONF, destination); - //onvm_sc_print(flow_entry->sc); - } - return 0; + ret = onvm_flow_dir_get_pkt(pkt, &flow_entry); + if (ret >= 0) { + meta->action = ONVM_NF_ACTION_NEXT; + } else { + ret = onvm_flow_dir_add_pkt(pkt, &flow_entry); + if (ret < 0) { + meta->action = ONVM_NF_ACTION_DROP; + meta->destination = 0; + return 0; + } + memset(flow_entry, 0, sizeof(struct onvm_flow_entry)); + flow_entry->sc = onvm_sc_create(); + onvm_sc_append_entry(flow_entry->sc, ONVM_NF_ACTION_TONF, destination); + // onvm_sc_print(flow_entry->sc); + } + return 0; } -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) { int arg_offset; const char *progname = argv[0]; @@ -192,16 +193,16 @@ int main(int argc, char *argv[]) { return -1; argc -= arg_offset; argv += arg_offset; - destination = nf_info->service_id + 1; + destination = nf_info->service_id + 1; if (parse_app_args(argc, argv, progname) < 0) rte_exit(EXIT_FAILURE, "Invalid command-line arguments\n"); - /* Map the sdn_ft table */ - onvm_flow_dir_nf_init(); + /* Map the sdn_ft table */ + onvm_flow_dir_nf_init(); - onvm_nflib_run(nf_info, &packet_handler); + onvm_nflib_run(nf_info, &packet_handler); printf("If we reach here, program is ending\n"); - return 0; + return 0; } diff --git a/onvm/onvm_mgr/main.c b/onvm/onvm_mgr/main.c index fcee4e5c9..0410ed995 100644 --- a/onvm/onvm_mgr/main.c +++ b/onvm/onvm_mgr/main.c @@ -39,7 +39,6 @@ * ********************************************************************/ - /****************************************************************************** main.c @@ -48,14 +47,12 @@ ******************************************************************************/ - #include #include "onvm_mgr.h" -#include "onvm_stats.h" -#include "onvm_pkt.h" #include "onvm_nf.h" - +#include "onvm_pkt.h" +#include "onvm_stats.h" /****************************Internal Declarations****************************/ @@ -68,7 +65,8 @@ static uint8_t main_keep_running = 1; // race the stats display to be able to print, so keep this varable separate static uint8_t worker_keep_running = 1; -static void handle_signal(int sig); +static void +handle_signal(int sig); /*******************************Worker threads********************************/ @@ -95,7 +93,7 @@ master_thread_main(void) { onvm_stats_init(verbosity_level); /* Loop forever: sleep always returns 0 or <= param */ - while ( main_keep_running && sleep(sleeptime) <= sleeptime) { + while (main_keep_running && sleep(sleeptime) <= sleeptime) { onvm_nf_check_status(); if (stats_destination != ONVM_STATS_NONE) onvm_stats_display_all(sleeptime, verbosity_level); @@ -118,27 +116,25 @@ master_thread_main(void) { if (nfs[i].info == NULL) { continue; } - RTE_LOG(INFO, APP, "Core %d: Notifying NF %"PRIu16" to shut down\n", rte_lcore_id(), i); + RTE_LOG(INFO, APP, "Core %d: Notifying NF %" PRIu16 " to shut down\n", rte_lcore_id(), i); onvm_nf_send_msg(i, MSG_STOP, NULL); } /* Wait to process all exits */ - for (shutdown_iter_count = 0; - shutdown_iter_count < MAX_SHUTDOWN_ITERS && num_nfs > 0; - shutdown_iter_count++) { + for (shutdown_iter_count = 0; shutdown_iter_count < MAX_SHUTDOWN_ITERS && num_nfs > 0; shutdown_iter_count++) { onvm_nf_check_status(); - RTE_LOG(INFO, APP, "Core %d: Waiting for %"PRIu16" NFs to exit\n", rte_lcore_id(), num_nfs); + RTE_LOG(INFO, APP, "Core %d: Waiting for %" PRIu16 " NFs to exit\n", rte_lcore_id(), num_nfs); sleep(sleeptime); } if (num_nfs > 0) { - RTE_LOG(INFO, APP, "Core %d: Up to %"PRIu16" NFs may still be running and must be killed manually\n", rte_lcore_id(), num_nfs); + RTE_LOG(INFO, APP, "Core %d: Up to %" PRIu16 " NFs may still be running and must be killed manually\n", + rte_lcore_id(), num_nfs); } RTE_LOG(INFO, APP, "Core %d: Master thread done\n", rte_lcore_id()); } - /* * Function to receive packets from the NIC * and distribute them to the default service @@ -147,19 +143,14 @@ static int rx_thread_main(void *arg) { uint16_t i, rx_count; struct rte_mbuf *pkts[PACKET_READ_SIZE]; - struct queue_mgr *rx_mgr = (struct queue_mgr*)arg; + struct queue_mgr *rx_mgr = (struct queue_mgr *)arg; - RTE_LOG(INFO, - APP, - "Core %d: Running RX thread for RX queue %d\n", - rte_lcore_id(), - rx_mgr->id); + RTE_LOG(INFO, APP, "Core %d: Running RX thread for RX queue %d\n", rte_lcore_id(), rx_mgr->id); for (; worker_keep_running;) { /* Read ports */ for (i = 0; i < ports->num_ports; i++) { - rx_count = rte_eth_rx_burst(ports->id[i], rx_mgr->id, \ - pkts, PACKET_READ_SIZE); + rx_count = rte_eth_rx_burst(ports->id[i], rx_mgr->id, pkts, PACKET_READ_SIZE); ports->rx_stats.rx[ports->id[i]] += rx_count; /* Now process the NIC packets read */ @@ -179,7 +170,6 @@ rx_thread_main(void *arg) { return 0; } - static int tx_thread_main(void *arg) { struct onvm_nf *nf; @@ -188,18 +178,11 @@ tx_thread_main(void *arg) { struct queue_mgr *tx_mgr = (struct queue_mgr *)arg; if (tx_mgr->tx_thread_info->first_nf == tx_mgr->tx_thread_info->last_nf - 1) { - RTE_LOG(INFO, - APP, - "Core %d: Running TX thread for NF %d\n", - rte_lcore_id(), + RTE_LOG(INFO, APP, "Core %d: Running TX thread for NF %d\n", rte_lcore_id(), tx_mgr->tx_thread_info->first_nf); } else if (tx_mgr->tx_thread_info->first_nf < tx_mgr->tx_thread_info->last_nf) { - RTE_LOG(INFO, - APP, - "Core %d: Running TX thread for NFs %d to %d\n", - rte_lcore_id(), - tx_mgr->tx_thread_info->first_nf, - tx_mgr->tx_thread_info->last_nf-1); + RTE_LOG(INFO, APP, "Core %d: Running TX thread for NFs %d to %d\n", rte_lcore_id(), + tx_mgr->tx_thread_info->first_nf, tx_mgr->tx_thread_info->last_nf - 1); } for (; worker_keep_running;) { @@ -209,8 +192,8 @@ tx_thread_main(void *arg) { if (!onvm_nf_is_valid(nf)) continue; - /* Dequeue all packets in ring up to max possible. */ - tx_count = rte_ring_dequeue_burst(nf->tx_q, (void **) pkts, PACKET_READ_SIZE, NULL); + /* Dequeue all packets in ring up to max possible. */ + tx_count = rte_ring_dequeue_burst(nf->tx_q, (void **)pkts, PACKET_READ_SIZE, NULL); /* Now process the Client packets read */ if (likely(tx_count > 0)) { @@ -237,10 +220,8 @@ handle_signal(int sig) { } } - /*******************************Main function*********************************/ - int main(int argc, char *argv[]) { unsigned cur_lcore, rx_lcores, tx_lcores; @@ -251,20 +232,21 @@ main(int argc, char *argv[]) { /* Reserve ID 0 for internal manager things */ next_instance_id = 1; - if (init(argc, argv) < 0 ) + if (init(argc, argv) < 0) return -1; RTE_LOG(INFO, APP, "Finished Process Init.\n"); /* clear statistics */ onvm_stats_clear_all_nfs(); - /* Reserve n cores for: ONVM_NUM_MGR_AUX_THREADS for auxiliary(f.e. stats), ONVM_NUM_RX_THREADS for Rx, and all remaining for Tx */ + /* Reserve n cores for: ONVM_NUM_MGR_AUX_THREADS for auxiliary(f.e. stats), ONVM_NUM_RX_THREADS for Rx, and all + * remaining for Tx */ cur_lcore = rte_lcore_id(); rx_lcores = ONVM_NUM_RX_THREADS; tx_lcores = rte_lcore_count() - rx_lcores - ONVM_NUM_MGR_AUX_THREADS; /* Offset cur_lcore to start assigning TX cores */ - cur_lcore += (rx_lcores-1); + cur_lcore += (rx_lcores - 1); RTE_LOG(INFO, APP, "%d cores available in total\n", rte_lcore_count()); RTE_LOG(INFO, APP, "%d cores available for handling manager RX queues\n", rx_lcores); @@ -280,7 +262,7 @@ main(int argc, char *argv[]) { * We want to distribute the number of running NFs across available * TX threads */ - nfs_per_tx = ceil((float)MAX_NFS/tx_lcores); + nfs_per_tx = ceil((float)MAX_NFS / tx_lcores); // We start the system with 0 NFs active num_nfs = 0; @@ -297,13 +279,10 @@ main(int argc, char *argv[]) { tx_mgr->tx_thread_info->port_tx_bufs = calloc(RTE_MAX_ETHPORTS, sizeof(struct packet_buf)); tx_mgr->nf_rx_bufs = calloc(MAX_NFS, sizeof(struct packet_buf)); tx_mgr->tx_thread_info->first_nf = RTE_MIN(i * nfs_per_tx + 1, (unsigned)MAX_NFS); - tx_mgr->tx_thread_info->last_nf = RTE_MIN((i+1) * nfs_per_tx + 1, (unsigned)MAX_NFS); + tx_mgr->tx_thread_info->last_nf = RTE_MIN((i + 1) * nfs_per_tx + 1, (unsigned)MAX_NFS); cur_lcore = rte_get_next_lcore(cur_lcore, 1, 1); - if (rte_eal_remote_launch(tx_thread_main, (void*)tx_mgr, cur_lcore) == -EBUSY) { - RTE_LOG(ERR, - APP, - "Core %d is already busy, can't use for nf %d TX\n", - cur_lcore, + if (rte_eal_remote_launch(tx_thread_main, (void *)tx_mgr, cur_lcore) == -EBUSY) { + RTE_LOG(ERR, APP, "Core %d is already busy, can't use for nf %d TX\n", cur_lcore, tx_mgr->tx_thread_info->first_nf); return -1; } @@ -318,10 +297,7 @@ main(int argc, char *argv[]) { rx_mgr->nf_rx_bufs = calloc(MAX_NFS, sizeof(struct packet_buf)); cur_lcore = rte_get_next_lcore(cur_lcore, 1, 1); if (rte_eal_remote_launch(rx_thread_main, (void *)rx_mgr, cur_lcore) == -EBUSY) { - RTE_LOG(ERR, - APP, - "Core %d is already busy, can't use for RX queue id %d\n", - cur_lcore, + RTE_LOG(ERR, APP, "Core %d is already busy, can't use for RX queue id %d\n", cur_lcore, rx_mgr->id); return -1; } diff --git a/onvm/onvm_mgr/onvm_args.c b/onvm/onvm_mgr/onvm_args.c index 0e3547372..9c1002b00 100644 --- a/onvm/onvm_mgr/onvm_args.c +++ b/onvm/onvm_mgr/onvm_args.c @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_args.c @@ -48,14 +47,11 @@ ******************************************************************************/ - #include "onvm_mgr/onvm_args.h" #include "onvm_mgr/onvm_stats.h" - /******************************Global variables*******************************/ - /* global var for number of currently active NFs - extern in header init.h */ uint16_t num_nfs; @@ -77,22 +73,17 @@ uint8_t global_verbosity_level = 1; /* global var for program name */ static const char *progname; - /***********************Internal Functions prototypes*************************/ - static void usage(void); - static int parse_portmask(uint8_t max_ports, const char *portmask); - static int parse_default_service(const char *services); - static int parse_num_services(const char *services); @@ -110,21 +101,16 @@ parse_verbosity_level(const char *verbosity_level); /*********************************Interfaces**********************************/ - int parse_app_args(uint8_t max_ports, int argc, char *argv[]) { int option_index, opt; char **argvopt = argv; static struct option lgopts[] = { - {"port-mask", required_argument, NULL, 'p'}, - {"num-services", required_argument, NULL, 'r'}, - {"nf-cores", required_argument, NULL, 'n'}, - {"default-service", required_argument, NULL, 'd'}, - {"stats-out", no_argument, NULL, 's'}, - {"stats-sleep-time", no_argument, NULL, 'z'}, - {"verbocity-level", no_argument, NULL, 'v'} - }; + {"port-mask", required_argument, NULL, 'p'}, {"num-services", required_argument, NULL, 'r'}, + {"nf-cores", required_argument, NULL, 'n'}, {"default-service", required_argument, NULL, 'd'}, + {"stats-out", no_argument, NULL, 's'}, {"stats-sleep-time", no_argument, NULL, 'z'}, + {"verbocity-level", no_argument, NULL, 'v'}}; progname = argv[0]; @@ -163,13 +149,13 @@ parse_app_args(uint8_t max_ports, int argc, char *argv[]) { onvm_stats_set_output(stats_destination); break; case 'z': - if(parse_stats_sleep_time(optarg) != 0){ + if (parse_stats_sleep_time(optarg) != 0) { usage(); return -1; } break; case 'v': - if(parse_verbosity_level(optarg) != 0){ + if (parse_verbosity_level(optarg) != 0) { usage(); return -1; } @@ -184,10 +170,8 @@ parse_app_args(uint8_t max_ports, int argc, char *argv[]) { return 0; } - /*****************************Internal functions******************************/ - static void usage(void) { printf( @@ -201,7 +185,6 @@ usage(void) { progname); } - static int parse_portmask(uint8_t max_ports, const char *portmask) { char *end = NULL; @@ -224,10 +207,12 @@ parse_portmask(uint8_t max_ports, const char *portmask) { while (pm != 0) { if (pm & 0x01) { /* bit is set in mask, use port */ if (count >= max_ports) - printf("WARNING: requested port %u not present" - " - ignoring\n", (unsigned)count); + printf( + "WARNING: requested port %u not present" + " - ignoring\n", + (unsigned)count); else - ports->id[ports->num_ports++] = count; + ports->id[ports->num_ports++] = count; } pm = (pm >> 1); count++; @@ -236,7 +221,6 @@ parse_portmask(uint8_t max_ports, const char *portmask) { return 0; } - static int parse_default_service(const char *services) { char *end = NULL; @@ -250,7 +234,6 @@ parse_default_service(const char *services) { return 0; } - static int parse_num_services(const char *services) { char *end = NULL; @@ -290,8 +273,10 @@ parse_nf_cores(const char *nf_coremask) { while (pm != 0) { if (pm & 0x01) { /* bit is set in mask, use port */ if (count >= max_cores) { - printf("WARNING: requested core %u out of cpu bounds" - " - ignoring\n", (unsigned)count); + printf( + "WARNING: requested core %u out of cpu bounds" + " - ignoring\n", + (unsigned)count); } else { cores[count].enabled = 1; cores[count].nf_count = 0; @@ -321,11 +306,11 @@ parse_nf_cores(const char *nf_coremask) { static int parse_stats_sleep_time(const char *sleeptime) { - char* end = NULL; + char *end = NULL; unsigned long temp; temp = strtoul(sleeptime, &end, 10); - if(end == NULL || *end != '\0' || temp == 0) + if (end == NULL || *end != '\0' || temp == 0) return -1; global_stats_sleep_time = (uint16_t)temp; @@ -347,14 +332,14 @@ parse_stats_output(const char *stats_output) { return -1; } } - + static int -parse_verbosity_level(const char *verbosity_level){ - char* end = NULL; +parse_verbosity_level(const char *verbosity_level) { + char *end = NULL; unsigned long temp; temp = strtoul(verbosity_level, &end, 10); - if(end == NULL || *end != '\0' || temp == 0) + if (end == NULL || *end != '\0' || temp == 0) return -1; global_verbosity_level = (uint16_t)temp; diff --git a/onvm/onvm_mgr/onvm_args.h b/onvm/onvm_mgr/onvm_args.h index 12db94009..a2ea21e11 100644 --- a/onvm/onvm_mgr/onvm_args.h +++ b/onvm/onvm_mgr/onvm_args.h @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_args.h @@ -48,7 +47,6 @@ ******************************************************************************/ - #ifndef _ONVM_ARGS_H_ #define _ONVM_ARGS_H_ @@ -59,6 +57,7 @@ #define DEFAULT_SERVICE_ID 1 -int parse_app_args(uint8_t max_ports, int argc, char *argv[]); +int +parse_app_args(uint8_t max_ports, int argc, char *argv[]); #endif // _ONVM_ARGS_H_ diff --git a/onvm/onvm_mgr/onvm_init.c b/onvm/onvm_mgr/onvm_init.c index 9e5fa53d2..c7f525db3 100644 --- a/onvm/onvm_mgr/onvm_init.c +++ b/onvm/onvm_mgr/onvm_init.c @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_init.c @@ -48,13 +47,10 @@ ******************************************************************************/ - #include "onvm_mgr/onvm_init.h" - /********************************Global variables*****************************/ - struct onvm_nf *nfs = NULL; struct port_info *ports = NULL; struct core_status *cores = NULL; @@ -68,17 +64,22 @@ uint16_t *nf_per_service_count; struct onvm_service_chain *default_chain; struct onvm_service_chain **default_sc_p; - /*************************Internal Functions Prototypes***********************/ -static int init_mbuf_pools(void); -static int init_nf_info_pool(void); -static int init_nf_msg_pool(void); -static int init_port(uint8_t port_num); -static int init_shm_rings(void); -static int init_info_queue(void); -static void check_all_ports_link_status(uint8_t port_num, uint32_t port_mask); - +static int +init_mbuf_pools(void); +static int +init_nf_info_pool(void); +static int +init_nf_msg_pool(void); +static int +init_port(uint8_t port_num); +static int +init_shm_rings(void); +static int +init_info_queue(void); +static void +check_all_ports_link_status(uint8_t port_num, uint32_t port_mask); /*****************Internal Configuration Structs and Constants*****************/ @@ -102,30 +103,26 @@ static void check_all_ports_link_status(uint8_t port_num, uint32_t port_mask); #define TX_WTHRESH 0 /* Default values of TX write-back threshold reg. */ static const struct rte_eth_conf port_conf = { - .rxmode = { - .mq_mode = ETH_MQ_RX_RSS, - .max_rx_pkt_len = ETHER_MAX_LEN, - .split_hdr_size = 0, - .offloads = DEV_RX_OFFLOAD_CHECKSUM, + .rxmode = + { + .mq_mode = ETH_MQ_RX_RSS, + .max_rx_pkt_len = ETHER_MAX_LEN, + .split_hdr_size = 0, + .offloads = DEV_RX_OFFLOAD_CHECKSUM, }, - .rx_adv_conf = { - .rss_conf = { - .rss_key = rss_symmetric_key, - .rss_hf = ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP | ETH_RSS_L2_PAYLOAD, + .rx_adv_conf = + { + .rss_conf = + { + .rss_key = rss_symmetric_key, .rss_hf = ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP | ETH_RSS_L2_PAYLOAD, }, }, - .txmode = { - .mq_mode = ETH_MQ_TX_NONE, - .offloads = (DEV_TX_OFFLOAD_IPV4_CKSUM | - DEV_TX_OFFLOAD_UDP_CKSUM | - DEV_TX_OFFLOAD_TCP_CKSUM) - }, + .txmode = {.mq_mode = ETH_MQ_TX_NONE, + .offloads = (DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM | DEV_TX_OFFLOAD_TCP_CKSUM)}, }; - /*********************************Interfaces**********************************/ - int init(int argc, char *argv[]) { int retval; @@ -152,38 +149,37 @@ init(int argc, char *argv[]) { total_ports = rte_eth_dev_count_avail(); /* set up array for NF tx data */ - mz_nf = rte_memzone_reserve(MZ_NF_INFO, sizeof(*nfs) * MAX_NFS, - rte_socket_id(), NO_FLAGS); + mz_nf = rte_memzone_reserve(MZ_NF_INFO, sizeof(*nfs) * MAX_NFS, rte_socket_id(), NO_FLAGS); if (mz_nf == NULL) rte_exit(EXIT_FAILURE, "Cannot reserve memory zone for nf information\n"); memset(mz_nf->addr, 0, sizeof(*nfs) * MAX_NFS); nfs = mz_nf->addr; /* set up ports info */ - mz_port = rte_memzone_reserve(MZ_PORT_INFO, sizeof(*ports), - rte_socket_id(), NO_FLAGS); + mz_port = rte_memzone_reserve(MZ_PORT_INFO, sizeof(*ports), rte_socket_id(), NO_FLAGS); if (mz_port == NULL) rte_exit(EXIT_FAILURE, "Cannot reserve memory zone for port information\n"); ports = mz_port->addr; - + /* set up core status */ mz_cores = rte_memzone_reserve(MZ_CORES_STATUS, sizeof(*cores) * onvm_threading_get_num_cores(), - rte_socket_id(), NO_FLAGS); + rte_socket_id(), NO_FLAGS); if (mz_cores == NULL) rte_exit(EXIT_FAILURE, "Cannot reserve memory zone for core information\n"); memset(mz_cores->addr, 0, sizeof(*cores) * 64); cores = mz_cores->addr; /* set up array for NF tx data */ - mz_services = rte_memzone_reserve(MZ_SERVICES_INFO, sizeof(uint16_t *) * num_services, rte_socket_id(), NO_FLAGS); + mz_services = + rte_memzone_reserve(MZ_SERVICES_INFO, sizeof(uint16_t *) * num_services, rte_socket_id(), NO_FLAGS); if (mz_services == NULL) rte_exit(EXIT_FAILURE, "Cannot reserve memory zone for services information\n"); services = mz_services->addr; for (i = 0; i < num_services; i++) { - services[i] = rte_calloc("one service NFs", - MAX_NFS_PER_SERVICE, sizeof(uint16_t), 0); + services[i] = rte_calloc("one service NFs", MAX_NFS_PER_SERVICE, sizeof(uint16_t), 0); } - mz_nf_per_service = rte_memzone_reserve(MZ_NF_PER_SERVICE_INFO, sizeof(uint16_t) * num_services, rte_socket_id(), NO_FLAGS); + mz_nf_per_service = + rte_memzone_reserve(MZ_NF_PER_SERVICE_INFO, sizeof(uint16_t) * num_services, rte_socket_id(), NO_FLAGS); if (mz_nf_per_service == NULL) { rte_exit(EXIT_FAILURE, "Cannot reserve memory zone for NF per service information.\n"); } @@ -219,7 +215,7 @@ init(int argc, char *argv[]) { if (retval != 0) rte_exit(EXIT_FAILURE, "Cannot initialise port %u\n", port_id); char event_msg_buf[22]; - sprintf(event_msg_buf, "Port %d initialized", port_id); + snprintf(event_msg_buf, sizeof(event_msg_buf), "Port %d initialized", port_id); onvm_stats_add_event(event_msg_buf, NULL); } @@ -241,8 +237,7 @@ init(int argc, char *argv[]) { printf("Default service chain: send to sdn NF\n"); /* set up service chain pointer shared to NFs*/ - mz_scp = rte_memzone_reserve(MZ_SCP_INFO, sizeof(struct onvm_service_chain *), - rte_socket_id(), NO_FLAGS); + mz_scp = rte_memzone_reserve(MZ_SCP_INFO, sizeof(struct onvm_service_chain *), rte_socket_id(), NO_FLAGS); if (mz_scp == NULL) rte_exit(EXIT_FAILURE, "Cannot reserve memory zone for service chain pointer\n"); memset(mz_scp->addr, 0, sizeof(struct onvm_service_chain *)); @@ -255,10 +250,8 @@ init(int argc, char *argv[]) { return 0; } - /*****************************Internal functions******************************/ - /** * Initialise the mbuf pool for packet reception for the NIC, and any other * buffer pools needed by the app - currently none. @@ -267,12 +260,10 @@ static int init_mbuf_pools(void) { /* don't pass single-producer/single-consumer flags to mbuf create as it * seems faster to use a cache instead */ - printf("Creating mbuf pool '%s' [%u mbufs] ...\n", - PKTMBUF_POOL_NAME, NUM_MBUFS); - pktmbuf_pool = rte_mempool_create(PKTMBUF_POOL_NAME, NUM_MBUFS, - MBUF_SIZE, MBUF_CACHE_SIZE, - sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, - NULL, rte_pktmbuf_init, NULL, rte_socket_id(), NO_FLAGS); + printf("Creating mbuf pool '%s' [%u mbufs] ...\n", PKTMBUF_POOL_NAME, NUM_MBUFS); + pktmbuf_pool = rte_mempool_create(PKTMBUF_POOL_NAME, NUM_MBUFS, MBUF_SIZE, MBUF_CACHE_SIZE, + sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, + rte_pktmbuf_init, NULL, rte_socket_id(), NO_FLAGS); return (pktmbuf_pool == NULL); /* 0 on success */ } @@ -281,14 +272,12 @@ init_mbuf_pools(void) { * Set up a mempool to store nf_msg structs */ static int -init_nf_msg_pool(void) -{ +init_nf_msg_pool(void) { /* don't pass single-producer/single-consumer flags to mbuf * create as it seems faster to use a cache instead */ printf("Creating mbuf pool '%s' ...\n", _NF_MSG_POOL_NAME); - nf_msg_pool = rte_mempool_create(_NF_MSG_POOL_NAME, MAX_NFS * NF_MSG_QUEUE_SIZE, - NF_INFO_SIZE, NF_MSG_CACHE_SIZE, - 0, NULL, NULL, NULL, NULL, rte_socket_id(), NO_FLAGS); + nf_msg_pool = rte_mempool_create(_NF_MSG_POOL_NAME, MAX_NFS * NF_MSG_QUEUE_SIZE, NF_INFO_SIZE, + NF_MSG_CACHE_SIZE, 0, NULL, NULL, NULL, NULL, rte_socket_id(), NO_FLAGS); return (nf_msg_pool == NULL); /* 0 on success */ } @@ -297,14 +286,12 @@ init_nf_msg_pool(void) * Set up a mempool to store nf_info structs */ static int -init_nf_info_pool(void) -{ +init_nf_info_pool(void) { /* don't pass single-producer/single-consumer flags to mbuf * create as it seems faster to use a cache instead */ printf("Creating mbuf pool '%s' ...\n", _NF_MEMPOOL_NAME); - nf_info_pool = rte_mempool_create(_NF_MEMPOOL_NAME, MAX_NFS, - NF_INFO_SIZE, 0, - 0, NULL, NULL, NULL, NULL, rte_socket_id(), NO_FLAGS); + nf_info_pool = rte_mempool_create(_NF_MEMPOOL_NAME, MAX_NFS, NF_INFO_SIZE, 0, 0, NULL, NULL, NULL, NULL, + rte_socket_id(), NO_FLAGS); return (nf_info_pool == NULL); /* 0 on success */ } @@ -343,52 +330,46 @@ init_port(uint8_t port_num) { rte_eth_dev_info_get(port_num, &dev_info); if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) local_port_conf.txmode.offloads |= DEV_TX_OFFLOAD_MBUF_FAST_FREE; - local_port_conf.rx_adv_conf.rss_conf.rss_hf &= - dev_info.flow_type_rss_offloads; - if (local_port_conf.rx_adv_conf.rss_conf.rss_hf != - port_conf.rx_adv_conf.rss_conf.rss_hf) { - printf("Port %u modified RSS hash function based on hardware support," - "requested:%#"PRIx64" configured:%#"PRIx64"\n", - port_num, - port_conf.rx_adv_conf.rss_conf.rss_hf, - local_port_conf.rx_adv_conf.rss_conf.rss_hf); + local_port_conf.rx_adv_conf.rss_conf.rss_hf &= dev_info.flow_type_rss_offloads; + if (local_port_conf.rx_adv_conf.rss_conf.rss_hf != port_conf.rx_adv_conf.rss_conf.rss_hf) { + printf( + "Port %u modified RSS hash function based on hardware support," + "requested:%#" PRIx64 " configured:%#" PRIx64 "\n", + port_num, port_conf.rx_adv_conf.rss_conf.rss_hf, local_port_conf.rx_adv_conf.rss_conf.rss_hf); } - if ((retval = rte_eth_dev_configure(port_num, rx_rings, tx_rings, - &local_port_conf)) != 0) + if ((retval = rte_eth_dev_configure(port_num, rx_rings, tx_rings, &local_port_conf)) != 0) return retval; - /* Adjust rx,tx ring sizes if not allowed by ethernet device + /* Adjust rx,tx ring sizes if not allowed by ethernet device * TODO if this is ajusted store the new values for future reference */ - retval = rte_eth_dev_adjust_nb_rx_tx_desc( - port_num, &rx_ring_size, &tx_ring_size); + retval = rte_eth_dev_adjust_nb_rx_tx_desc(port_num, &rx_ring_size, &tx_ring_size); if (retval < 0) { - rte_panic("Cannot adjust number of descriptors for port %u (%d)\n", - port_num, retval); + rte_panic("Cannot adjust number of descriptors for port %u (%d)\n", port_num, retval); } rxq_conf = dev_info.default_rxconf; rxq_conf.offloads = local_port_conf.rxmode.offloads; for (q = 0; q < rx_rings; q++) { - retval = rte_eth_rx_queue_setup(port_num, q, rx_ring_size, - rte_eth_dev_socket_id(port_num), - &rxq_conf, pktmbuf_pool); - if (retval < 0) return retval; + retval = rte_eth_rx_queue_setup(port_num, q, rx_ring_size, rte_eth_dev_socket_id(port_num), &rxq_conf, + pktmbuf_pool); + if (retval < 0) + return retval; } txq_conf = dev_info.default_txconf; txq_conf.offloads = port_conf.txmode.offloads; for (q = 0; q < tx_rings; q++) { - retval = rte_eth_tx_queue_setup(port_num, q, tx_ring_size, - rte_eth_dev_socket_id(port_num), - &txq_conf); - if (retval < 0) return retval; + retval = rte_eth_tx_queue_setup(port_num, q, tx_ring_size, rte_eth_dev_socket_id(port_num), &txq_conf); + if (retval < 0) + return retval; } rte_eth_promiscuous_enable(port_num); retval = rte_eth_dev_start(port_num); - if (retval < 0) return retval; + if (retval < 0) + return retval; printf("done: \n"); @@ -404,9 +385,9 @@ static int init_shm_rings(void) { unsigned i; unsigned socket_id; - const char * rq_name; - const char * tq_name; - const char * msg_q_name; + const char *rq_name; + const char *tq_name; + const char *msg_q_name; const unsigned ringsize = NF_QUEUE_RINGSIZE; const unsigned msgringsize = NF_MSG_QUEUE_SIZE; @@ -420,15 +401,12 @@ init_shm_rings(void) { tq_name = get_tx_queue_name(i); msg_q_name = get_msg_queue_name(i); nfs[i].instance_id = i; - nfs[i].rx_q = rte_ring_create(rq_name, - ringsize, socket_id, - RING_F_SC_DEQ); /* multi prod, single cons */ - nfs[i].tx_q = rte_ring_create(tq_name, - ringsize, socket_id, - RING_F_SC_DEQ); /* multi prod, single cons */ - nfs[i].msg_q = rte_ring_create(msg_q_name, - msgringsize, socket_id, - RING_F_SC_DEQ); /* multi prod, single cons */ + nfs[i].rx_q = + rte_ring_create(rq_name, ringsize, socket_id, RING_F_SC_DEQ); /* multi prod, single cons */ + nfs[i].tx_q = + rte_ring_create(tq_name, ringsize, socket_id, RING_F_SC_DEQ); /* multi prod, single cons */ + nfs[i].msg_q = + rte_ring_create(msg_q_name, msgringsize, socket_id, RING_F_SC_DEQ); /* multi prod, single cons */ if (nfs[i].rx_q == NULL) rte_exit(EXIT_FAILURE, "Cannot create rx ring queue for NF %u\n", i); @@ -446,13 +424,9 @@ init_shm_rings(void) { * Allocate a rte_ring for newly created NFs */ static int -init_info_queue(void) -{ - incoming_msg_queue = rte_ring_create( - _MGR_MSG_QUEUE_NAME, - MAX_NFS, - rte_socket_id(), - RING_F_SC_DEQ); // MP enqueue (default), SC dequeue +init_info_queue(void) { + incoming_msg_queue = rte_ring_create(_MGR_MSG_QUEUE_NAME, MAX_NFS, rte_socket_id(), + RING_F_SC_DEQ); // MP enqueue (default), SC dequeue if (incoming_msg_queue == NULL) rte_exit(EXIT_FAILURE, "Cannot create incoming msg queue\n"); @@ -464,7 +438,7 @@ init_info_queue(void) static void check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) { #define CHECK_INTERVAL 100 /* 100ms */ -#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ +#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ uint8_t portid, count, all_ports_up, print_flag = 0; struct rte_eth_link link; @@ -480,14 +454,14 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) { /* print link status if flag set */ if (print_flag == 1) { if (link.link_status) - printf("Port %d Link Up - speed %u " - "Mbps - %s\n", ports->id[portid], - (unsigned)link.link_speed, - (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? - ("full-duplex") : ("half-duplex\n")); + printf( + "Port %d Link Up - speed %u " + "Mbps - %s\n", + ports->id[portid], (unsigned)link.link_speed, + (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? ("full-duplex") + : ("half-duplex\n")); else - printf("Port %d Link Down\n", - (uint8_t)ports->id[portid]); + printf("Port %d Link Down\n", (uint8_t)ports->id[portid]); continue; } /* clear all_ports_up flag if any link down */ diff --git a/onvm/onvm_mgr/onvm_init.h b/onvm/onvm_mgr/onvm_init.h index 24062b9ab..5b5378f56 100644 --- a/onvm/onvm_mgr/onvm_init.h +++ b/onvm/onvm_mgr/onvm_init.h @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_init.h @@ -49,40 +48,35 @@ ******************************************************************************/ - #ifndef _ONVM_INIT_H_ #define _ONVM_INIT_H_ - /********************************DPDK library*********************************/ #include -#include -#include -#include #include #include +#include +#include +#include #ifdef RTE_LIBRTE_PDUMP #include #endif - /*****************************Internal library********************************/ - +#include "onvm_common.h" +#include "onvm_flow_dir.h" +#include "onvm_flow_table.h" +#include "onvm_includes.h" #include "onvm_mgr/onvm_args.h" #include "onvm_mgr/onvm_stats.h" -#include "onvm_includes.h" -#include "onvm_common.h" -#include "onvm_sc_mgr.h" #include "onvm_sc_common.h" -#include "onvm_flow_table.h" -#include "onvm_flow_dir.h" +#include "onvm_sc_mgr.h" #include "onvm_threading.h" /***********************************Macros************************************/ - #define MBUF_CACHE_SIZE 512 #define MBUF_OVERHEAD (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) #define RX_MBUF_DATA_SIZE 2048 @@ -103,10 +97,8 @@ /* Number of auxiliary threads in manager, 1 reserved for stats */ #define ONVM_NUM_MGR_AUX_THREADS 1 - /*************************External global variables***************************/ - /* NF to Manager data flow */ extern struct rte_ring *incoming_msg_queue; @@ -139,6 +131,7 @@ extern uint8_t global_verbosity_level; * Output : an error code * */ -int init(int argc, char *argv[]); +int +init(int argc, char *argv[]); #endif // _ONVM_INIT_H_ diff --git a/onvm/onvm_mgr/onvm_mgr.h b/onvm/onvm_mgr/onvm_mgr.h index fb6d8c78c..3cc54345a 100644 --- a/onvm/onvm_mgr/onvm_mgr.h +++ b/onvm/onvm_mgr/onvm_mgr.h @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_mgr.h @@ -49,50 +48,39 @@ ******************************************************************************/ - #ifndef _ONVM_MGR_H_ #define _ONVM_MGR_H_ - /******************************Standard C library*****************************/ - +#include #include #include -#include - /********************************DPDK library*********************************/ - #include -#include -#include #include - +#include +#include /******************************Internal headers*******************************/ - +#include "onvm_flow_dir.h" +#include "onvm_flow_table.h" +#include "onvm_includes.h" #include "onvm_mgr/onvm_args.h" #include "onvm_mgr/onvm_init.h" -#include "onvm_includes.h" -#include "onvm_sc_mgr.h" -#include "onvm_flow_table.h" -#include "onvm_flow_dir.h" #include "onvm_pkt_common.h" - +#include "onvm_sc_mgr.h" /***********************************Macros************************************/ - #define TO_PORT 0 #define TO_NF 1 - /***************************Shared global variables***************************/ - /* ID to be assigned to the next NF that starts */ extern uint16_t next_instance_id; diff --git a/onvm/onvm_mgr/onvm_nf.c b/onvm/onvm_mgr/onvm_nf.c index 00b3e36bb..f3f14d2f9 100644 --- a/onvm/onvm_mgr/onvm_nf.c +++ b/onvm/onvm_mgr/onvm_nf.c @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_nf.c @@ -47,16 +46,14 @@ ******************************************************************************/ - -#include "onvm_mgr.h" #include "onvm_nf.h" +#include "onvm_mgr.h" #include "onvm_stats.h" uint16_t next_instance_id = 0; /************************Internal functions prototypes************************/ - /* * Function starting a NF. * @@ -67,7 +64,6 @@ uint16_t next_instance_id = 0; inline static int onvm_nf_start(struct onvm_nf_info *nf_info); - /* * Function to mark a NF as ready. * @@ -78,7 +74,6 @@ onvm_nf_start(struct onvm_nf_info *nf_info); inline static int onvm_nf_ready(struct onvm_nf_info *nf_info); - /* * Function stopping a NF. * @@ -89,10 +84,8 @@ onvm_nf_ready(struct onvm_nf_info *nf_info); inline static int onvm_nf_stop(struct onvm_nf_info *nf_info); - /********************************Interfaces***********************************/ - uint16_t onvm_nf_next_instance_id(void) { struct onvm_nf *nf; @@ -108,7 +101,6 @@ onvm_nf_next_instance_id(void) { return instance_id; } - void onvm_nf_check_status(void) { int i; @@ -117,47 +109,47 @@ onvm_nf_check_status(void) { struct onvm_nf_info *nf; int num_msgs = rte_ring_count(incoming_msg_queue); - if (num_msgs == 0) return; + if (num_msgs == 0) + return; if (rte_ring_dequeue_bulk(incoming_msg_queue, msgs, num_msgs, NULL) == 0) return; for (i = 0; i < num_msgs; i++) { - msg = (struct onvm_nf_msg*) msgs[i]; + msg = (struct onvm_nf_msg *)msgs[i]; switch (msg->msg_type) { - case MSG_NF_STARTING: - nf = (struct onvm_nf_info*)msg->msg_data; - if (onvm_nf_start(nf) == 0) { - onvm_stats_add_event("NF Starting", nf); - } - break; - case MSG_NF_READY: - nf = (struct onvm_nf_info*)msg->msg_data; - if (onvm_nf_ready(nf) == 0) { - onvm_stats_add_event("NF Ready", nf); - } - break; - case MSG_NF_STOPPING: - nf = (struct onvm_nf_info*)msg->msg_data; - if (onvm_nf_stop(nf) == 0) { - onvm_stats_add_event("NF Stopping", nf); - num_nfs--; - } - break; + case MSG_NF_STARTING: + nf = (struct onvm_nf_info *)msg->msg_data; + if (onvm_nf_start(nf) == 0) { + onvm_stats_add_event("NF Starting", nf); + } + break; + case MSG_NF_READY: + nf = (struct onvm_nf_info *)msg->msg_data; + if (onvm_nf_ready(nf) == 0) { + onvm_stats_add_event("NF Ready", nf); + } + break; + case MSG_NF_STOPPING: + nf = (struct onvm_nf_info *)msg->msg_data; + if (onvm_nf_stop(nf) == 0) { + onvm_stats_add_event("NF Stopping", nf); + num_nfs--; + } + break; } - rte_mempool_put(nf_msg_pool, (void*)msg); + rte_mempool_put(nf_msg_pool, (void *)msg); } } - int onvm_nf_send_msg(uint16_t dest, uint8_t msg_type, void *msg_data) { int ret; struct onvm_nf_msg *msg; - ret = rte_mempool_get(nf_msg_pool, (void**)(&msg)); + ret = rte_mempool_get(nf_msg_pool, (void **)(&msg)); if (ret != 0) { RTE_LOG(INFO, APP, "Oh the huge manatee! Unable to allocate msg from pool :(\n"); return ret; @@ -166,12 +158,11 @@ onvm_nf_send_msg(uint16_t dest, uint8_t msg_type, void *msg_data) { msg->msg_type = msg_type; msg->msg_data = msg_data; - return rte_ring_sp_enqueue(nfs[dest].msg_q, (void*)msg); + return rte_ring_sp_enqueue(nfs[dest].msg_q, (void *)msg); } /******************************Internal functions*****************************/ - inline static int onvm_nf_start(struct onvm_nf_info *nf_info) { int ret; @@ -179,14 +170,12 @@ onvm_nf_start(struct onvm_nf_info *nf_info) { // take code from init_shm_rings in init.c // flush rx/tx queue at the this index to start clean? - if(nf_info == NULL || nf_info->status != NF_WAITING_FOR_ID) + if (nf_info == NULL || nf_info->status != NF_WAITING_FOR_ID) return 1; // if NF passed its own id on the command line, don't assign here // assume user is smart enough to avoid duplicates - uint16_t nf_id = nf_info->instance_id == (uint16_t)NF_NO_ID - ? onvm_nf_next_instance_id() - : nf_info->instance_id; + uint16_t nf_id = nf_info->instance_id == (uint16_t)NF_NO_ID ? onvm_nf_next_instance_id() : nf_info->instance_id; if (nf_id >= MAX_NFS) { // There are no more available IDs for this NF @@ -230,11 +219,11 @@ onvm_nf_start(struct onvm_nf_info *nf_info) { return 0; } - inline static int onvm_nf_ready(struct onvm_nf_info *info) { // Ensure we've already called nf_start for this NF - if (info->status != NF_STARTING) return -1; + if (info->status != NF_STARTING) + return -1; // Register this NF running within its service info->status = NF_RUNNING; @@ -244,7 +233,6 @@ onvm_nf_ready(struct onvm_nf_info *info) { return 0; } - inline static int onvm_nf_stop(struct onvm_nf_info *nf_info) { uint16_t nf_id; @@ -252,7 +240,7 @@ onvm_nf_stop(struct onvm_nf_info *nf_info) { int mapIndex; struct rte_mempool *nf_info_mp; - if(nf_info == NULL || nf_info->status != NF_RUNNING) + if (nf_info == NULL || nf_info->status != NF_RUNNING) return 1; nf_info->status = NF_STOPPED; @@ -295,7 +283,7 @@ onvm_nf_stop(struct onvm_nf_info *nf_info) { if (nf_info_mp == NULL) return 1; - rte_mempool_put(nf_info_mp, (void*)nf_info); + rte_mempool_put(nf_info_mp, (void *)nf_info); return 0; } diff --git a/onvm/onvm_mgr/onvm_nf.h b/onvm/onvm_mgr/onvm_nf.h index f8c22d26c..83cbb52f9 100644 --- a/onvm/onvm_mgr/onvm_nf.h +++ b/onvm/onvm_mgr/onvm_nf.h @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_nf.h @@ -48,7 +47,6 @@ ******************************************************************************/ - #ifndef _ONVM_NF_H_ #define _ONVM_NF_H_ @@ -56,20 +54,17 @@ extern uint16_t next_instance_id; - /********************************Interfaces***********************************/ - /* * Interface giving the smallest unsigned integer unused for a NF instance. * - * Output : the unsigned integer + * Output : the unsigned integer * */ uint16_t onvm_nf_next_instance_id(void); - /* * Interface looking through all registered NFs if one needs to start or stop. * @@ -77,7 +72,6 @@ onvm_nf_next_instance_id(void); void onvm_nf_check_status(void); - /* * Interface to send a message to a certain NF. * @@ -90,5 +84,4 @@ onvm_nf_check_status(void); int onvm_nf_send_msg(uint16_t dest, uint8_t msg_type, void *msg_data); - #endif // _ONVM_NF_H_ diff --git a/onvm/onvm_mgr/onvm_pkt.c b/onvm/onvm_mgr/onvm_pkt.c index 75d28b6e5..bd8803a44 100644 --- a/onvm/onvm_mgr/onvm_pkt.c +++ b/onvm/onvm_mgr/onvm_pkt.c @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_pkt.c @@ -47,14 +46,13 @@ ******************************************************************************/ - #include "onvm_mgr.h" -#include "onvm_pkt.h" + #include "onvm_nf.h" +#include "onvm_pkt.h" /**********************************Interfaces*********************************/ - void onvm_pkt_process_rx_batch(struct queue_mgr *rx_mgr, struct rte_mbuf *pkts[], uint16_t rx_count) { uint16_t i; @@ -67,7 +65,7 @@ onvm_pkt_process_rx_batch(struct queue_mgr *rx_mgr, struct rte_mbuf *pkts[], uin return; for (i = 0; i < rx_count; i++) { - meta = (struct onvm_pkt_meta*) &(((struct rte_mbuf*)pkts[i])->udata64); + meta = (struct onvm_pkt_meta *)&(((struct rte_mbuf *)pkts[i])->udata64); meta->src = 0; meta->chain_index = 0; ret = onvm_flow_dir_get_pkt(pkts[i], &flow_entry); @@ -92,10 +90,9 @@ onvm_pkt_process_rx_batch(struct queue_mgr *rx_mgr, struct rte_mbuf *pkts[], uin onvm_pkt_flush_all_nfs(rx_mgr, NULL); } - void onvm_pkt_flush_all_ports(struct queue_mgr *tx_mgr) { - uint16_t i; + uint16_t i; if (tx_mgr == NULL) return; @@ -104,7 +101,6 @@ onvm_pkt_flush_all_ports(struct queue_mgr *tx_mgr) { onvm_pkt_flush_port_queue(tx_mgr, ports->id[i]); } - void onvm_pkt_drop_batch(struct rte_mbuf **pkts, uint16_t size) { uint16_t i; @@ -115,4 +111,3 @@ onvm_pkt_drop_batch(struct rte_mbuf **pkts, uint16_t size) { for (i = 0; i < size; i++) rte_pktmbuf_free(pkts[i]); } - diff --git a/onvm/onvm_mgr/onvm_pkt.h b/onvm/onvm_mgr/onvm_pkt.h index 1f20cdab2..59cb651bc 100644 --- a/onvm/onvm_mgr/onvm_pkt.h +++ b/onvm/onvm_mgr/onvm_pkt.h @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_pkt.h @@ -49,14 +48,11 @@ ******************************************************************************/ - #ifndef _ONVM_PKT_H_ #define _ONVM_PKT_H_ - /*********************************Interfaces**********************************/ - /* * Interface to process packets in a given RX queue. * @@ -77,7 +73,6 @@ onvm_pkt_process_rx_batch(struct queue_mgr *rx_mgr, struct rte_mbuf *pkts[], uin void onvm_pkt_flush_all_ports(struct queue_mgr *tx_mgr); - /* * Interface to drop a batch of packets. * @@ -88,5 +83,4 @@ onvm_pkt_flush_all_ports(struct queue_mgr *tx_mgr); void onvm_pkt_drop_batch(struct rte_mbuf **pkts, uint16_t size); - #endif // _ONVM_PKT_H_ diff --git a/onvm/onvm_mgr/onvm_stats.c b/onvm/onvm_mgr/onvm_stats.c index 36f07837a..5b1d92af0 100644 --- a/onvm/onvm_mgr/onvm_stats.c +++ b/onvm/onvm_mgr/onvm_stats.c @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_stats.c @@ -47,17 +46,16 @@ ******************************************************************************/ -#include -#include #include +#include +#include #include "onvm_mgr.h" -#include "onvm_stats.h" #include "onvm_nf.h" +#include "onvm_stats.h" /************************Internal Functions Prototypes************************/ - /* * Function displaying statistics for all ports * @@ -67,7 +65,6 @@ static void onvm_stats_display_ports(unsigned difftime, uint8_t verbosity_level); - /* * Function displaying statistics for all NFs * @@ -75,7 +72,6 @@ onvm_stats_display_ports(unsigned difftime, uint8_t verbosity_level); static void onvm_stats_display_nfs(unsigned difftime, uint8_t verbosity_level); - /* * Function clearing the terminal and moving back the cursor to the top left. * @@ -83,7 +79,6 @@ onvm_stats_display_nfs(unsigned difftime, uint8_t verbosity_level); static void onvm_stats_clear_terminal(void); - /* * Function giving the MAC address of a port in string format. * @@ -118,7 +113,6 @@ static FILE *stats_out; static FILE *json_stats_out; static FILE *json_events_out; - /****************************Global variables***************************************/ /* Holds current timestamp, might want to make this not global */ @@ -130,7 +124,10 @@ void onvm_stats_init(uint8_t verbocity_level) { if (verbocity_level == ONVM_RAW_STATS_DUMP) { printf("#YYYY-MM-DD HH:MM:SS,nic_rx_pkts,nic_rx_pps,nic_tx_pkts,nic_tx_pps\n"); - printf("#YYYY-MM-DD HH:MM:SS,instance_id,service_id,rx,tx,rx_pps,tx_pps,rx_drop,tx_drop,rx_drop_rate,tx_drop_rate,act_out,act_tonf,act_drop,act_next,act_buffer,act_returned\n"); + printf( + "#YYYY-MM-DD " + "HH:MM:SS,instance_id,service_id,rx,tx,rx_pps,tx_pps,rx_drop,tx_drop,rx_drop_rate,tx_drop_rate,act_" + "out,act_tonf,act_drop,act_next,act_buffer,act_returned\n"); } } @@ -180,10 +177,10 @@ onvm_stats_cleanup(void) { void onvm_stats_display_all(unsigned difftime, uint8_t verbosity_level) { time_t time_raw_format; - struct tm * ptr_time; - time ( &time_raw_format ); - ptr_time = localtime ( &time_raw_format ); - if(strftime(buffer, 20, "%F %T", ptr_time) == 0){ + struct tm *ptr_time; + time(&time_raw_format); + ptr_time = localtime(&time_raw_format); + if (strftime(buffer, 20, "%F %T", ptr_time) == 0) { perror("Couldn't prepare formatted string"); } @@ -206,7 +203,6 @@ onvm_stats_display_all(unsigned difftime, uint8_t verbosity_level) { onvm_stats_flush(); } - void onvm_stats_clear_all_nfs(void) { unsigned i; @@ -232,14 +228,14 @@ onvm_stats_add_event(const char *msg, struct onvm_nf_info *nf_info) { } char event_time_buf[20]; time_t time_raw_format; - struct tm * ptr_time; - time ( &time_raw_format ); - ptr_time = localtime ( &time_raw_format ); + struct tm *ptr_time; + time(&time_raw_format); + ptr_time = localtime(&time_raw_format); if (strftime(event_time_buf, 20, "%F %T", ptr_time) == 0) { perror("Couldn't prepare formatted string"); } - cJSON* new_event = cJSON_CreateObject(); - cJSON* source = cJSON_CreateObject(); + cJSON *new_event = cJSON_CreateObject(); + cJSON *source = cJSON_CreateObject(); cJSON_AddStringToObject(new_event, "timestamp", event_time_buf); cJSON_AddStringToObject(new_event, "message", msg); if (nf_info == NULL) { @@ -254,10 +250,8 @@ onvm_stats_add_event(const char *msg, struct onvm_nf_info *nf_info) { cJSON_AddItemToArray(onvm_json_events_arr, new_event); } - /****************************Internal functions*******************************/ - static void onvm_stats_display_ports(unsigned difftime, uint8_t verbosity_level) { unsigned i = 0; @@ -265,7 +259,7 @@ onvm_stats_display_ports(unsigned difftime, uint8_t verbosity_level) { uint64_t nic_tx_pkts = 0; uint64_t nic_rx_pps = 0; uint64_t nic_tx_pps = 0; - char* port_label = NULL; + char *port_label = NULL; /* Arrays to store last TX/RX count to calculate rate */ static uint64_t tx_last[RTE_MAX_ETHPORTS]; static uint64_t rx_last[RTE_MAX_ETHPORTS]; @@ -273,12 +267,12 @@ onvm_stats_display_ports(unsigned difftime, uint8_t verbosity_level) { PORT_MSG[0] = PORT_MSG[1] = "PORTS\n-----\n"; PORT_MSG[2] = ""; - fprintf(stats_out, "%s", PORT_MSG[verbosity_level-1]); + fprintf(stats_out, "%s", PORT_MSG[verbosity_level - 1]); if (verbosity_level != ONVM_RAW_STATS_DUMP) { for (i = 0; i < ports->num_ports; i++) fprintf(stats_out, "Port %u: '%s'\t", (unsigned)ports->id[i], - onvm_stats_print_MAC(ports->id[i])); + onvm_stats_print_MAC(ports->id[i])); fprintf(stats_out, "\n\n"); } for (i = 0; i < ports->num_ports; i++) { @@ -289,31 +283,22 @@ onvm_stats_display_ports(unsigned difftime, uint8_t verbosity_level) { nic_tx_pps = (nic_tx_pkts - tx_last[i]) / difftime; if (verbosity_level == ONVM_RAW_STATS_DUMP) { - fprintf(stats_out, "%s,%u,%"PRIu64",%"PRIu64",%"PRIu64"%"PRIu64"\n", - buffer, - (unsigned)ports->id[i], - nic_rx_pkts, - nic_rx_pps, - nic_tx_pkts, - nic_tx_pps); + fprintf(stats_out, "%s,%u,%" PRIu64 ",%" PRIu64 ",%" PRIu64 "%" PRIu64 "\n", buffer, + (unsigned)ports->id[i], nic_rx_pkts, nic_rx_pps, nic_tx_pkts, nic_tx_pps); } else { - fprintf(stats_out, "Port %u - rx: %9"PRIu64" (%9"PRIu64" pps)\t" - "tx: %9"PRIu64" (%9"PRIu64" pps)\n", - (unsigned)ports->id[i], - nic_rx_pkts, - nic_rx_pps, - nic_tx_pkts, - nic_tx_pps); + fprintf(stats_out, "Port %u - rx: %9" PRIu64 " (%9" PRIu64 + " pps)\t" + "tx: %9" PRIu64 " (%9" PRIu64 " pps)\n", + (unsigned)ports->id[i], nic_rx_pkts, nic_rx_pps, nic_tx_pkts, nic_tx_pps); } /* Only print this information out if we haven't already printed it to the console above */ if (stats_out != stdout && stats_out != stderr) { ONVM_SNPRINTF(port_label, 8, "Port %d", i); - cJSON_AddItemToObject(onvm_json_port_stats_obj, - port_label, - onvm_json_port_stats[i] = cJSON_CreateObject()); + cJSON_AddItemToObject(onvm_json_port_stats_obj, port_label, + onvm_json_port_stats[i] = cJSON_CreateObject()); cJSON_AddStringToObject(onvm_json_port_stats[i], "Label", port_label); cJSON_AddNumberToObject(onvm_json_port_stats[i], "RX", nic_rx_pps); cJSON_AddNumberToObject(onvm_json_port_stats[i], "TX", nic_tx_pps); @@ -327,10 +312,9 @@ onvm_stats_display_ports(unsigned difftime, uint8_t verbosity_level) { } } - static void onvm_stats_display_nfs(unsigned difftime, uint8_t verbosity_level) { - char* nf_label = NULL; + char *nf_label = NULL; unsigned i = 0; /* Arrays to store last TX/RX count for NFs to calculate rate */ static uint64_t nf_tx_last[MAX_NFS]; @@ -340,9 +324,14 @@ onvm_stats_display_nfs(unsigned difftime, uint8_t verbosity_level) { static uint64_t nf_rx_drop_last[MAX_NFS]; static const char *NF_MSG[3]; - NF_MSG[0] = "\nNF IID / SID rx_pps / tx_pps rx_drop / tx_drop out / tonf / drop\n-----------------------------------------------------------------------------------------------\n"; - NF_MSG[1] = "\nNF IID / SID rx_pps / tx_pps rx / tx out / tonf / drop\n" - " drop_pps / drop_pps rx_drop / tx_drop next / buf / ret\n---------------------------------------------------------------------------------------------------\n"; + NF_MSG[0] = + "\nNF IID / SID rx_pps / tx_pps rx_drop / tx_drop out / tonf / " + "drop\n-----------------------------------------------------------------------------------------------\n"; + NF_MSG[1] = + "\nNF IID / SID rx_pps / tx_pps rx / tx out / tonf / drop\n" + " drop_pps / drop_pps rx_drop / tx_drop next / buf / " + "ret\n---------------------------------------------------------------------------------------------------" + "\n"; NF_MSG[2] = ""; /* For same service id TX/RX stats */ @@ -367,7 +356,7 @@ onvm_stats_display_nfs(unsigned difftime, uint8_t verbosity_level) { rx_for_service[i] = 0; tx_for_service[i] = 0; rx_drop_for_service[i] = 0; - tx_drop_for_service[i] = 0;; + tx_drop_for_service[i] = 0; rx_pps_for_service[i] = 0; tx_pps_for_service[i] = 0; rx_drop_rate_for_service[i] = 0; @@ -380,7 +369,7 @@ onvm_stats_display_nfs(unsigned difftime, uint8_t verbosity_level) { act_returned_for_service[i] = 0; } - fprintf(stats_out, "%s", NF_MSG[verbosity_level-1]); + fprintf(stats_out, "%s", NF_MSG[verbosity_level - 1]); for (i = 0; i < MAX_NFS; i++) { if (!onvm_nf_is_valid(&nfs[i])) continue; @@ -394,10 +383,10 @@ onvm_stats_display_nfs(unsigned difftime, uint8_t verbosity_level) { const uint64_t act_next = nfs[i].stats.act_next; const uint64_t act_buffer = nfs[i].stats.tx_buffer; const uint64_t act_returned = nfs[i].stats.tx_returned; - const uint64_t rx_pps = (rx - nf_rx_last[i])/difftime; - const uint64_t tx_pps = (tx - nf_tx_last[i])/difftime; - const uint64_t tx_drop_rate = (tx_drop - nf_tx_drop_last[i])/difftime; - const uint64_t rx_drop_rate = (rx_drop - nf_rx_drop_last[i])/difftime; + const uint64_t rx_pps = (rx - nf_rx_last[i]) / difftime; + const uint64_t tx_pps = (tx - nf_tx_last[i]) / difftime; + const uint64_t tx_drop_rate = (tx_drop - nf_tx_drop_last[i]) / difftime; + const uint64_t rx_drop_rate = (rx_drop - nf_rx_drop_last[i]) / difftime; /* Save stats for NFs with same service id */ if (print_total_stats) { @@ -418,43 +407,42 @@ onvm_stats_display_nfs(unsigned difftime, uint8_t verbosity_level) { } if (verbosity_level == ONVM_RAW_STATS_DUMP) { - fprintf(stats_out, "%s,%u,%u,%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64"\n", - buffer, nfs[i].info->instance_id, nfs[i].info->service_id, - rx, tx, rx_pps, tx_pps, rx_drop, tx_drop, rx_drop_rate, tx_drop_rate, - act_out, act_tonf, act_drop, act_next, act_buffer, act_returned); + fprintf(stats_out, "%s,%u,%u,%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 + ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 + ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 "\n", + buffer, nfs[i].info->instance_id, nfs[i].info->service_id, rx, tx, rx_pps, tx_pps, + rx_drop, tx_drop, rx_drop_rate, tx_drop_rate, act_out, act_tonf, act_drop, act_next, + act_buffer, act_returned); } else if (verbosity_level == 2) { - fprintf(stats_out, "NF %2u / %-2u - %9"PRIu64" / %-9"PRIu64" %11"PRIu64" / %-11"PRIu64" %11"PRIu64" / %-11"PRIu64" / %-11"PRIu64"\n" - " %9"PRIu64" / %-9"PRIu64" %11"PRIu64" / %-11"PRIu64" %11"PRIu64" / %-11"PRIu64" / %-11"PRIu64"\n", - nfs[i].info->instance_id, nfs[i].info->service_id, - rx_pps, tx_pps, rx, tx, act_out, act_tonf, act_drop, - rx_drop_rate, tx_drop_rate, rx_drop, tx_drop, act_next, act_buffer, act_returned); + fprintf(stats_out, "NF %2u / %-2u - %9" PRIu64 " / %-9" PRIu64 " %11" PRIu64 " / %-11" PRIu64 + " %11" PRIu64 " / %-11" PRIu64 " / %-11" PRIu64 + "\n" + " %9" PRIu64 " / %-9" PRIu64 " %11" PRIu64 " / %-11" PRIu64 + " %11" PRIu64 " / %-11" PRIu64 " / %-11" PRIu64 "\n", + nfs[i].info->instance_id, nfs[i].info->service_id, rx_pps, tx_pps, rx, tx, act_out, + act_tonf, act_drop, rx_drop_rate, tx_drop_rate, rx_drop, tx_drop, act_next, act_buffer, + act_returned); } else { - fprintf(stats_out, "NF %2u / %-2u - %9"PRIu64" / %-9"PRIu64" %9"PRIu64" / %-9"PRIu64" %11"PRIu64" / %-11"PRIu64" / %-11"PRIu64" \n", - nfs[i].info->instance_id, nfs[i].info->service_id, - rx_pps, tx_pps, rx_drop, tx_drop, act_out, act_tonf, act_drop); + fprintf(stats_out, "NF %2u / %-2u - %9" PRIu64 " / %-9" PRIu64 " %9" PRIu64 " / %-9" PRIu64 + " %11" PRIu64 " / %-11" PRIu64 " / %-11" PRIu64 " \n", + nfs[i].info->instance_id, nfs[i].info->service_id, rx_pps, tx_pps, rx_drop, tx_drop, + act_out, act_tonf, act_drop); } /* Only print this information out if we haven't already printed it to the console above */ if (stats_out != stdout && stats_out != stderr) { ONVM_SNPRINTF(nf_label, 6, "NF %d", i); - cJSON_AddItemToObject(onvm_json_nf_stats_obj, - nf_label, - onvm_json_nf_stats[i] = cJSON_CreateObject()); - - cJSON_AddStringToObject(onvm_json_nf_stats[i], - "Label", nf_label); - cJSON_AddNumberToObject(onvm_json_nf_stats[i], - "RX", rx_pps); - cJSON_AddNumberToObject(onvm_json_nf_stats[i], - "TX", tx_pps); - cJSON_AddNumberToObject(onvm_json_nf_stats[i], - "TX_Drop_Rate", tx_drop_rate); - cJSON_AddNumberToObject(onvm_json_nf_stats[i], - "RX_Drop_Rate", rx_drop_rate); - cJSON_AddNumberToObject(onvm_json_nf_stats[i], - "service_id", (int16_t)nfs[i].info->service_id); - cJSON_AddNumberToObject(onvm_json_nf_stats[i], - "instance_id", (int16_t)nfs[i].info->instance_id); + cJSON_AddItemToObject(onvm_json_nf_stats_obj, nf_label, + onvm_json_nf_stats[i] = cJSON_CreateObject()); + + cJSON_AddStringToObject(onvm_json_nf_stats[i], "Label", nf_label); + cJSON_AddNumberToObject(onvm_json_nf_stats[i], "RX", rx_pps); + cJSON_AddNumberToObject(onvm_json_nf_stats[i], "TX", tx_pps); + cJSON_AddNumberToObject(onvm_json_nf_stats[i], "TX_Drop_Rate", tx_drop_rate); + cJSON_AddNumberToObject(onvm_json_nf_stats[i], "RX_Drop_Rate", rx_drop_rate); + cJSON_AddNumberToObject(onvm_json_nf_stats[i], "service_id", (int16_t)nfs[i].info->service_id); + cJSON_AddNumberToObject(onvm_json_nf_stats[i], "instance_id", + (int16_t)nfs[i].info->instance_id); free(nf_label); nf_label = NULL; @@ -474,38 +462,43 @@ onvm_stats_display_nfs(unsigned difftime, uint8_t verbosity_level) { fprintf(stats_out, "-----------------\n"); for (i = 0; i < MAX_SERVICES; i++) { uint16_t nfs_for_service = nf_per_service_count[i]; - const char *nf_count = nfs_for_service==1 ? "NF " : "NFs"; + const char *nf_count = nfs_for_service == 1 ? "NF " : "NFs"; if (nfs_for_service == 0) continue; if (verbosity_level == 2) { - fprintf(stats_out, "SID %-2u %2u%s - %9"PRIu64" / %-9"PRIu64" %11"PRIu64" / %-11"PRIu64" %11"PRIu64" / %-11"PRIu64" / %-11"PRIu64"\n" - " %9"PRIu64" / %-9"PRIu64" %11"PRIu64" / %-11"PRIu64" %11"PRIu64" / %-11"PRIu64" / %-11"PRIu64"\n", - i, nfs_for_service, nf_count, - rx_pps_for_service[i], tx_pps_for_service[i], rx_for_service[i], tx_for_service[i], act_out_for_service[i], act_tonf_for_service[i], act_drop_for_service[i], - rx_drop_rate_for_service[i], tx_drop_rate_for_service[i], rx_drop_for_service[i], tx_drop_for_service[i], act_next_for_service[i], act_buffer_for_service[i], act_returned_for_service[i]); + fprintf( + stats_out, "SID %-2u %2u%s - %9" PRIu64 " / %-9" PRIu64 " %11" PRIu64 + " / %-11" PRIu64 " %11" PRIu64 " / %-11" PRIu64 " / %-11" PRIu64 + "\n" + " %9" PRIu64 " / %-9" PRIu64 " %11" PRIu64 + " / %-11" PRIu64 " %11" PRIu64 " / %-11" PRIu64 " / %-11" PRIu64 "\n", + i, nfs_for_service, nf_count, rx_pps_for_service[i], tx_pps_for_service[i], + rx_for_service[i], tx_for_service[i], act_out_for_service[i], + act_tonf_for_service[i], act_drop_for_service[i], rx_drop_rate_for_service[i], + tx_drop_rate_for_service[i], rx_drop_for_service[i], tx_drop_for_service[i], + act_next_for_service[i], act_buffer_for_service[i], act_returned_for_service[i]); } else { - fprintf(stats_out, "SID %-2u %2u%s - %9"PRIu64" / %-9"PRIu64" %9"PRIu64" / %-9"PRIu64" %11"PRIu64" / %-11"PRIu64" / %-11"PRIu64" \n", - i, nfs_for_service, nf_count, - rx_pps_for_service[i], tx_pps_for_service[i], rx_drop_for_service[i], tx_drop_for_service[i], - act_out_for_service[i], act_tonf_for_service[i], act_drop_for_service[i]); + fprintf(stats_out, + "SID %-2u %2u%s - %9" PRIu64 " / %-9" PRIu64 " %9" PRIu64 " / %-9" PRIu64 + " %11" PRIu64 " / %-11" PRIu64 " / %-11" PRIu64 " \n", + i, nfs_for_service, nf_count, rx_pps_for_service[i], tx_pps_for_service[i], + rx_drop_for_service[i], tx_drop_for_service[i], act_out_for_service[i], + act_tonf_for_service[i], act_drop_for_service[i]); } } } } - /***************************Helper functions**********************************/ - static void onvm_stats_clear_terminal(void) { - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; + const char clr[] = {27, '[', '2', 'J', '\0'}; + const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'}; fprintf(stats_out, "%s%s", clr, topLeft); } - static const char * onvm_stats_print_MAC(uint8_t port) { static const char err_address[] = "00:00:00:00:00:00"; @@ -517,17 +510,13 @@ onvm_stats_print_MAC(uint8_t port) { if (unlikely(addresses[port][0] == '\0')) { struct ether_addr mac; rte_eth_macaddr_get(port, &mac); - snprintf(addresses[port], sizeof(addresses[port]), - "%02x:%02x:%02x:%02x:%02x:%02x\n", - mac.addr_bytes[0], mac.addr_bytes[1], - mac.addr_bytes[2], mac.addr_bytes[3], - mac.addr_bytes[4], mac.addr_bytes[5]); + snprintf(addresses[port], sizeof(addresses[port]), "%02x:%02x:%02x:%02x:%02x:%02x\n", mac.addr_bytes[0], + mac.addr_bytes[1], mac.addr_bytes[2], mac.addr_bytes[3], mac.addr_bytes[4], mac.addr_bytes[5]); } return addresses[port]; } - static void onvm_stats_flush(void) { if (stats_out == stdout || stats_out == stderr) { @@ -539,7 +528,6 @@ onvm_stats_flush(void) { fflush(json_events_out); } - static void onvm_stats_truncate(void) { if (stats_out == stdout || stats_out == stderr) { @@ -556,7 +544,6 @@ onvm_stats_truncate(void) { } } - static void onvm_json_reset_objects(void) { time_t current_time; @@ -570,10 +557,8 @@ onvm_json_reset_objects(void) { current_time = time(0); - cJSON_AddStringToObject(onvm_json_root, ONVM_JSON_TIMESTAMP_KEY, - ctime(¤t_time)); + cJSON_AddStringToObject(onvm_json_root, ONVM_JSON_TIMESTAMP_KEY, ctime(¤t_time)); cJSON_AddItemToObject(onvm_json_root, ONVM_JSON_PORT_STATS_KEY, onvm_json_port_stats_obj = cJSON_CreateObject()); - cJSON_AddItemToObject(onvm_json_root, ONVM_JSON_NF_STATS_KEY, - onvm_json_nf_stats_obj = cJSON_CreateObject()); + cJSON_AddItemToObject(onvm_json_root, ONVM_JSON_NF_STATS_KEY, onvm_json_nf_stats_obj = cJSON_CreateObject()); } diff --git a/onvm/onvm_mgr/onvm_stats.h b/onvm/onvm_mgr/onvm_stats.h index aea946951..9d6334248 100644 --- a/onvm/onvm_mgr/onvm_stats.h +++ b/onvm/onvm_mgr/onvm_stats.h @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_stats.h @@ -47,13 +46,12 @@ ******************************************************************************/ - #ifndef _ONVM_STATS_H_ #define _ONVM_STATS_H_ -#include "cJSON.h" -#include #include +#include +#include "cJSON.h" #define ONVM_STR_STATS_STDOUT "stdout" #define ONVM_STR_STATS_STDERR "stderr" @@ -69,23 +67,17 @@ #define ONVM_JSON_NF_STATS_KEY "onvm_nf_stats" #define ONVM_JSON_TIMESTAMP_KEY "last_updated" -#define ONVM_SNPRINTF(str_, sz_, fmt_, ...) \ - do { \ - (str_) = (char *)malloc(sizeof(char) * (sz_)); \ - if (!(str_)) \ - rte_exit(-1, "ERROR! [%s,%d]: unable to malloc str.\n", \ - __FUNCTION__, __LINE__); \ - snprintf((str_), (sz_), (fmt_), __VA_ARGS__); \ +#define ONVM_SNPRINTF(str_, sz_, fmt_, ...) \ + do { \ + (str_) = (char*)malloc(sizeof(char) * (sz_)); \ + if (!(str_)) \ + rte_exit(-1, "ERROR! [%s,%d]: unable to malloc str.\n", __FUNCTION__, __LINE__); \ + snprintf((str_), (sz_), (fmt_), __VA_ARGS__); \ } while (0) #define ONVM_RAW_STATS_DUMP 3 -typedef enum { - ONVM_STATS_NONE = 0, - ONVM_STATS_STDOUT, - ONVM_STATS_STDERR, - ONVM_STATS_WEB -} ONVM_STATS_OUTPUT; +typedef enum { ONVM_STATS_NONE = 0, ONVM_STATS_STDOUT, ONVM_STATS_STDERR, ONVM_STATS_WEB } ONVM_STATS_OUTPUT; cJSON* onvm_json_root; cJSON* onvm_json_port_stats_obj; @@ -96,7 +88,6 @@ cJSON* onvm_json_events_arr; /*********************************Interfaces**********************************/ - /* * Function for initializing stats * @@ -106,7 +97,6 @@ cJSON* onvm_json_events_arr; void onvm_stats_init(uint8_t verbosity_level); - /* * Interface called by the manager to tell the stats module where to print * You should only call this once @@ -116,13 +106,15 @@ onvm_stats_init(uint8_t verbosity_level); * browser. If STATS_STDOUT or STATS_STDOUT is specified, then stats will be * output the respective stream. */ -void onvm_stats_set_output(ONVM_STATS_OUTPUT output); +void +onvm_stats_set_output(ONVM_STATS_OUTPUT output); /* * Interface to close out file descriptions and clean up memory * To be called when the stats loop is done */ -void onvm_stats_cleanup(void); +void +onvm_stats_cleanup(void); /* * Interface called by the ONVM Manager to display all statistics @@ -131,8 +123,8 @@ void onvm_stats_cleanup(void); * Input : time passed since last display (to compute packet rate) * */ -void onvm_stats_display_all(unsigned difftime, uint8_t verbosity_level); - +void +onvm_stats_display_all(unsigned difftime, uint8_t verbosity_level); /* * Interface called by the ONVM Manager to clear all NFs statistics @@ -143,8 +135,8 @@ void onvm_stats_display_all(unsigned difftime, uint8_t verbosity_level); * incur a visible slowdown. * */ -void onvm_stats_clear_all_nfs(void); - +void +onvm_stats_clear_all_nfs(void); /* * Interface called by the ONVM Manager to clear one NF's statistics. @@ -152,12 +144,13 @@ void onvm_stats_clear_all_nfs(void); * Input : the NF id * */ -void onvm_stats_clear_nf(uint16_t id); +void +onvm_stats_clear_nf(uint16_t id); /* * Interface called by manager when a new event should be created. */ - void onvm_stats_add_event(const char *msg, struct onvm_nf_info *nf); - +void +onvm_stats_add_event(const char* msg, struct onvm_nf_info* nf); #endif // _ONVM_STATS_H_ diff --git a/onvm/onvm_nflib/onvm_common.h b/onvm/onvm_nflib/onvm_common.h index 45b7b577e..981754f3b 100644 --- a/onvm/onvm_nflib/onvm_common.h +++ b/onvm/onvm_nflib/onvm_common.h @@ -44,51 +44,53 @@ #include -#include #include +#include -#include "onvm_msg_common.h" #include "onvm_config_common.h" +#include "onvm_msg_common.h" -#define ONVM_MAX_CHAIN_LENGTH 4 // the maximum chain length -#define MAX_NFS 128 // total number of NFs allowed -#define MAX_SERVICES 32 // total number of unique services allowed -#define MAX_NFS_PER_SERVICE 32 // max number of NFs per service. +#define ONVM_MAX_CHAIN_LENGTH 4 // the maximum chain length +#define MAX_NFS 128 // total number of NFs allowed +#define MAX_SERVICES 32 // total number of unique services allowed +#define MAX_NFS_PER_SERVICE 32 // max number of NFs per service. -#define NUM_MBUFS 32767 // total number of mbufs (2^15 - 1) -#define NF_QUEUE_RINGSIZE 16384 //size of queue for NFs +#define NUM_MBUFS 32767 // total number of mbufs (2^15 - 1) +#define NF_QUEUE_RINGSIZE 16384 // size of queue for NFs #define PACKET_READ_SIZE ((uint16_t)32) -#define ONVM_NF_ACTION_DROP 0 // drop packet -#define ONVM_NF_ACTION_NEXT 1 // to whatever the next action is configured by the SDN controller in the flow table -#define ONVM_NF_ACTION_TONF 2 // send to the NF specified in the argument field (assume it is on the same host) -#define ONVM_NF_ACTION_OUT 3 // send the packet out the NIC port set in the argument field +#define ONVM_NF_ACTION_DROP 0 // drop packet +#define ONVM_NF_ACTION_NEXT 1 // to whatever the next action is configured by the SDN controller in the flow table +#define ONVM_NF_ACTION_TONF 2 // send to the NF specified in the argument field (assume it is on the same host) +#define ONVM_NF_ACTION_OUT 3 // send the packet out the NIC port set in the argument field /* Used in setting bit flags for core options */ #define MANUAL_CORE_ASSIGNMENT_BIT 0 #define SHARE_CORE_BIT 1 -//extern uint8_t rss_symmetric_key[40]; +// extern uint8_t rss_symmetric_key[40]; -//flag operations that should be used on onvm_pkt_meta +// flag operations that should be used on onvm_pkt_meta #define ONVM_CHECK_BIT(flags, n) !!((flags) & (1 << (n))) #define ONVM_SET_BIT(flags, n) ((flags) | (1 << (n))) #define ONVM_CLEAR_BIT(flags, n) ((flags) & (0 << (n))) struct onvm_pkt_meta { - uint8_t action; /* Action to be performed */ + uint8_t action; /* Action to be performed */ uint16_t destination; /* where to go next */ - uint16_t src; /* who processed the packet last */ - uint8_t chain_index; /*index of the current step in the service chain*/ - uint8_t flags; /* bits for custom NF data. Use with caution to prevent collisions from different NFs. */ + uint16_t src; /* who processed the packet last */ + uint8_t chain_index; /*index of the current step in the service chain*/ + uint8_t flags; /* bits for custom NF data. Use with caution to prevent collisions from different NFs. */ }; -static inline struct onvm_pkt_meta* onvm_get_pkt_meta(struct rte_mbuf* pkt) { - return (struct onvm_pkt_meta*)&pkt->udata64; +static inline struct onvm_pkt_meta * +onvm_get_pkt_meta(struct rte_mbuf *pkt) { + return (struct onvm_pkt_meta *)&pkt->udata64; } -static inline uint8_t onvm_get_pkt_chain_index(struct rte_mbuf* pkt) { +static inline uint8_t +onvm_get_pkt_chain_index(struct rte_mbuf *pkt) { struct onvm_pkt_meta* pkt_meta = (struct onvm_pkt_meta*) &pkt->udata64; return pkt_meta->chain_index; } @@ -106,10 +108,10 @@ static inline uint8_t onvm_get_pkt_chain_index(struct rte_mbuf* pkt) { */ /*******************************Data Structures*******************************/ -/* +/* * Packets may be transported by a tx thread or by an NF. - * This data structure encapsulates data specific to - * tx threads. + * This data structure encapsulates data specific to + * tx threads. */ struct tx_thread_info { unsigned first_nf; @@ -132,7 +134,7 @@ struct packet_buf { * */ struct queue_mgr { unsigned id; - enum {NF, MGR} mgr_type_t; + enum { NF, MGR } mgr_type_t; union { struct tx_thread_info *tx_thread_info; struct packet_buf *to_tx_buf; @@ -140,11 +142,11 @@ struct queue_mgr { struct packet_buf *nf_rx_bufs; }; -struct rx_stats{ +struct rx_stats { uint64_t rx[RTE_MAX_ETHPORTS]; }; -struct tx_stats{ +struct tx_stats { uint64_t tx[RTE_MAX_ETHPORTS]; uint64_t tx_drop[RTE_MAX_ETHPORTS]; }; @@ -165,13 +167,14 @@ struct core_status { struct onvm_nf_info; /* Function prototype for NF packet handlers */ -typedef int(*pkt_handler_func)(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, __attribute__ ((unused)) struct onvm_nf_info *nf_info); +typedef int (*pkt_handler_func)(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, + __attribute__((unused)) struct onvm_nf_info *nf_info); /* Function prototype for NF callback handlers */ -typedef int(*callback_handler_func)(__attribute__ ((unused)) struct onvm_nf_info *nf_info); +typedef int (*callback_handler_func)(__attribute__((unused)) struct onvm_nf_info *nf_info); /* Function prototype for NFs running advanced rings */ -typedef void(*advanced_rings_func)(struct onvm_nf_info *nf_info); +typedef void (*advanced_rings_func)(struct onvm_nf_info *nf_info); /* Function prototype for NFs that want extra initalization/setup before running */ -typedef void(*setup_func)(struct onvm_nf_info *nf_info); +typedef void (*setup_func)(struct onvm_nf_info *nf_info); /* Information needed to initialize a new NF child thread */ struct onvm_nf_scale_info { @@ -232,7 +235,6 @@ struct onvm_nf { volatile uint64_t act_next; volatile uint64_t act_buffer; } stats; - }; /* @@ -281,23 +283,22 @@ struct onvm_service_chain { #define _NF_MSG_POOL_NAME "NF_MSG_MEMPOOL" /* common names for NF states */ -#define NF_WAITING_FOR_ID 0 // First step in startup process, doesn't have ID confirmed by manager yet -#define NF_STARTING 1 // When a NF is in the startup process and already has an id -#define NF_RUNNING 2 // Running normally -#define NF_PAUSED 3 // NF is not receiving packets, but may in the future -#define NF_STOPPED 4 // NF has stopped and in the shutdown process -#define NF_ID_CONFLICT 5 // NF is trying to declare an ID already in use -#define NF_NO_IDS 6 // There are no available IDs for this NF -#define NF_SERVICE_MAX 7 // Service ID has exceeded the maximum amount -#define NF_SERVICE_COUNT_MAX 8 // Maximum amount of NF's per service spawned -#define NF_NO_CORES 9 // There are no cores available or specified core can't be used -#define NF_NO_DEDICATED_CORES 10 // There is no space for a dedicated core -#define NF_CORE_OUT_OF_RANGE 11 // The manually selected core is out of range -#define NF_CORE_BUSY 12 // The manually selected core is busy +#define NF_WAITING_FOR_ID 0 // First step in startup process, doesn't have ID confirmed by manager yet +#define NF_STARTING 1 // When a NF is in the startup process and already has an id +#define NF_RUNNING 2 // Running normally +#define NF_PAUSED 3 // NF is not receiving packets, but may in the future +#define NF_STOPPED 4 // NF has stopped and in the shutdown process +#define NF_ID_CONFLICT 5 // NF is trying to declare an ID already in use +#define NF_NO_IDS 6 // There are no available IDs for this NF +#define NF_SERVICE_MAX 7 // Service ID has exceeded the maximum amount +#define NF_SERVICE_COUNT_MAX 8 // Maximum amount of NF's per service spawned +#define NF_NO_CORES 9 // There are no cores available or specified core can't be used +#define NF_NO_DEDICATED_CORES 10 // There is no space for a dedicated core +#define NF_CORE_OUT_OF_RANGE 11 // The manually selected core is out of range +#define NF_CORE_BUSY 12 // The manually selected core is busy #define NF_NO_ID -1 -#define ONVM_NF_HANDLE_TX 1 // should be true if NFs primarily pass packets to each other - +#define ONVM_NF_HANDLE_TX 1 // should be true if NFs primarily pass packets to each other /* * Given the rx queue name template above, get the queue name diff --git a/onvm/onvm_nflib/onvm_config_common.c b/onvm/onvm_nflib/onvm_config_common.c index 251eaedca..436f6f008 100644 --- a/onvm/onvm_nflib/onvm_config_common.c +++ b/onvm/onvm_nflib/onvm_config_common.c @@ -43,13 +43,13 @@ #include #include -#include "onvm_config_common.h" #include "cJSON.h" +#include "onvm_config_common.h" #define IS_NULL_OR_EMPTY_STRING(s) ((s) == NULL || strncmp(s, "", 1) == 0 ? 1 : 0) cJSON* -onvm_config_parse_file(const char* filename){ +onvm_config_parse_file(const char* filename) { if (IS_NULL_OR_EMPTY_STRING(filename)) { return NULL; } @@ -109,7 +109,7 @@ onvm_config_extract_corelist(cJSON* dpdk_config, int* size, int** list) { return -1; } - for(i = 0; i < *size; ++i){ + for (i = 0; i < *size; ++i) { *list[i] = cJSON_GetArrayItem(json_arr, i)->valueint; } @@ -168,12 +168,14 @@ onvm_config_extract_output_location(cJSON* onvm_config, char** output_loc) { return -1; } - local_output_loc = (char *) malloc(sizeof(char) * strlen(cJSON_GetObjectItem(onvm_config, "output")->valuestring)); + local_output_loc = + (char*)malloc(sizeof(char) * strlen(cJSON_GetObjectItem(onvm_config, "output")->valuestring)); if (local_output_loc == NULL) { return -1; } - strncpy(local_output_loc, cJSON_GetObjectItem(onvm_config, "output")->valuestring, strlen(cJSON_GetObjectItem(onvm_config, "output")->valuestring)); + strncpy(local_output_loc, cJSON_GetObjectItem(onvm_config, "output")->valuestring, + strlen(cJSON_GetObjectItem(onvm_config, "output")->valuestring)); *output_loc = local_output_loc; return 0; @@ -277,13 +279,13 @@ onvm_config_create_nf_arg_list(cJSON* config, int* argc, char** argv[]) { /* Add all the argcs toggether, accounting for the program name */ new_argc = 1 + dpdk_argc + onvm_argc; - new_argv = (char **) malloc(sizeof(char*) * new_argc); + new_argv = (char**)malloc(sizeof(char*) * new_argc); if (new_argv == NULL) { printf("Unable to allocate space for new argv\n"); return -1; } - new_argv[0] = (char *) malloc(strlen((*argv)[0])); + new_argv[0] = (char*)malloc(strlen((*argv)[0])); if (new_argv[0] == NULL) { return -1; } @@ -296,7 +298,7 @@ onvm_config_create_nf_arg_list(cJSON* config, int* argc, char** argv[]) { /* Copy the DPDK args to new_argv */ for (i = 0; i < dpdk_argc; ++i) { - new_argv[i+offset] = dpdk_argv[i]; + new_argv[i + offset] = dpdk_argv[i]; } /* DPDK args have been filled in, so offset by that */ @@ -304,27 +306,28 @@ onvm_config_create_nf_arg_list(cJSON* config, int* argc, char** argv[]) { /* Copy ONVM args to new_argv- need to use the offset so that the loop still starts at 0 */ for (i = 0; i < onvm_argc; ++i) { - new_argv[i+offset] = onvm_argv[i]; + new_argv[i + offset] = onvm_argv[i]; } /* Find the dashes in the argv from the original command-line entry */ for (i = 0; i < *argc; ++i) { if (strncmp((*argv)[i], FLAG_DASH, strlen(FLAG_DASH)) == 0) { if (onvm_old_argv_index == 0) { - onvm_old_argv_index = i+1; + onvm_old_argv_index = i + 1; } else { - nf_old_argv_index = i+1; + nf_old_argv_index = i + 1; } } } /* Find the dashes in the newly constructed argv */ for (i = 0; i < new_argc; ++i) { - if (strncmp(new_argv[i], FLAG_DASH, strlen(FLAG_DASH)) == 0 && strlen(new_argv[i]) == strlen(FLAG_DASH)) { + if (strncmp(new_argv[i], FLAG_DASH, strlen(FLAG_DASH)) == 0 && + strlen(new_argv[i]) == strlen(FLAG_DASH)) { if (onvm_new_argv_index == 0) { - onvm_new_argv_index = i+1; + onvm_new_argv_index = i + 1; } else { - nf_new_argv_index = i+1; + nf_new_argv_index = i + 1; } } } @@ -339,23 +342,21 @@ onvm_config_create_nf_arg_list(cJSON* config, int* argc, char** argv[]) { } /* Check the old argv for DPDK values and memcpy the old value to the new_argv array */ - for (i = 1; i < onvm_new_argv_index-1; ++i) { - for (j = 3; j < onvm_old_argv_index-1; ++j) { + for (i = 1; i < onvm_new_argv_index - 1; ++i) { + for (j = 3; j < onvm_old_argv_index - 1; ++j) { if (strncmp((*argv)[j], new_argv[i], strlen(new_argv[i])) == 0 && j % 2 == 1) { - memcpy(new_argv[i+1], (*argv)[j+1], strlen((*argv)[j+1])); + memcpy(new_argv[i + 1], (*argv)[j + 1], strlen((*argv)[j + 1])); } } - } /* Check the old argv for ONVM values and memcpy the old value to the new_argv array */ for (i = onvm_new_argv_index; i < nf_new_argv_index; ++i) { for (j = onvm_old_argv_index; j < nf_old_argv_index; ++j) { if (strncmp((*argv)[j], new_argv[i], strlen(new_argv[i])) == 0 && j % 2 == 0) { - memcpy(new_argv[i+1], (*argv)[j+1], strlen((*argv)[j+1])); + memcpy(new_argv[i + 1], (*argv)[j + 1], strlen((*argv)[j + 1])); } } - } /* Need to clear out the old args so that the NF won't double count them- it should only see NF-specific args */ @@ -371,12 +372,12 @@ onvm_config_create_nf_arg_list(cJSON* config, int* argc, char** argv[]) { int onvm_config_create_onvm_args(cJSON* onvm_config, int* onvm_argc, char** onvm_argv[]) { - char* service_id_string = NULL; - char* instance_id_string = NULL; - int service_id = 0; - int instance_id = 0; + char* service_id_string = NULL; + char* instance_id_string = NULL; + int service_id = 0; + int instance_id = 0; - /* An NF has 2 required ONVM args */ + /* An NF has 2 required ONVM args */ *onvm_argc = 2; if (onvm_config == NULL || onvm_argc == NULL || onvm_argv == NULL) { @@ -393,14 +394,14 @@ onvm_config_create_onvm_args(cJSON* onvm_config, int* onvm_argc, char** onvm_arg *onvm_argc += 2; } - *onvm_argv = (char **) malloc(sizeof(char*) * (*onvm_argc)); + *onvm_argv = (char**)malloc(sizeof(char*) * (*onvm_argc)); if (*onvm_argv == NULL) { printf("Unable to allocate space for onvm_argv\n"); return -1; } /* Allows for MAX_SERVICE_ID_SIZE number of characters in the number */ - service_id_string = (char *) malloc(sizeof(char) * MAX_SERVICE_ID_SIZE); + service_id_string = (char*)malloc(sizeof(char) * MAX_SERVICE_ID_SIZE); if (service_id_string == NULL) { printf("Unable to allocate space for onvm_service_id_string\n"); return -1; @@ -414,11 +415,11 @@ onvm_config_create_onvm_args(cJSON* onvm_config, int* onvm_argc, char** onvm_arg strncpy((*onvm_argv)[0], FLAG_R, strlen(FLAG_R)); - sprintf(service_id_string, "%d", service_id); + snprintf(service_id_string, sizeof(char) * MAX_SERVICE_ID_SIZE, "%d", service_id); (*onvm_argv)[1] = service_id_string; if (*onvm_argc > 2) { - instance_id_string = (char *) malloc(sizeof(char) * MAX_SERVICE_ID_SIZE); + instance_id_string = (char*)malloc(sizeof(char) * MAX_SERVICE_ID_SIZE); if (instance_id_string == NULL) { printf("Unable to allocate space for onvm_instance_id_string\n"); return -1; @@ -430,7 +431,7 @@ onvm_config_create_onvm_args(cJSON* onvm_config, int* onvm_argc, char** onvm_arg return -1; } strncpy((*onvm_argv)[2], FLAG_N, strlen(FLAG_N)); - sprintf(instance_id_string, "%d", instance_id); + snprintf(instance_id_string, sizeof(char) * MAX_SERVICE_ID_SIZE, "%d", instance_id); (*onvm_argv)[3] = instance_id_string; } @@ -443,6 +444,7 @@ onvm_config_create_dpdk_args(cJSON* dpdk_config, int* dpdk_argc, char** dpdk_arg int mem_channels = 0; char* mem_channels_string = NULL; size_t* arg_size = NULL; + size_t mem_channels_string_size; int i = 0; if (dpdk_config == NULL || dpdk_argc == NULL || dpdk_argv == NULL) { @@ -454,37 +456,39 @@ onvm_config_create_dpdk_args(cJSON* dpdk_config, int* dpdk_argc, char** dpdk_arg /* DPKD requires 6 args */ *dpdk_argc = 6; - *dpdk_argv = (char **) malloc(sizeof(char*) * (*dpdk_argc)); + *dpdk_argv = (char**)malloc(sizeof(char*) * (*dpdk_argc)); if (*dpdk_argv == NULL) { printf("Unable to allocate space for dpdk_argv\n"); return -1; } - arg_size = (size_t *) malloc(sizeof(size_t) * (*dpdk_argc)); + arg_size = (size_t*)malloc(sizeof(size_t) * (*dpdk_argc)); if (arg_size == NULL) { return -1; } - core_string = (char *) malloc(sizeof(char) * strlen(cJSON_GetObjectItem(dpdk_config, "corelist")->valuestring)); + core_string = (char*)malloc(sizeof(char) * strlen(cJSON_GetObjectItem(dpdk_config, "corelist")->valuestring)); if (core_string == NULL) { printf("Unable to allocate space for core string\n"); return -1; } - core_string = strncpy(core_string, cJSON_GetObjectItem(dpdk_config, "corelist")->valuestring, strlen(cJSON_GetObjectItem(dpdk_config, "corelist")->valuestring)); + core_string = strncpy(core_string, cJSON_GetObjectItem(dpdk_config, "corelist")->valuestring, + strlen(cJSON_GetObjectItem(dpdk_config, "corelist")->valuestring)); if (onvm_config_extract_memory_channels(dpdk_config, &mem_channels) < 0) { printf("Unable to extract memory channels\n"); return -1; } - mem_channels_string = (char *) malloc(sizeof(char) * 3); + mem_channels_string_size = sizeof(char) * 3; + mem_channels_string = (char*)malloc(mem_channels_string_size); if (mem_channels_string == NULL) { printf("Unable to allocate space for memory channels string\n"); return -1; } - sprintf(mem_channels_string, "%d", mem_channels); + snprintf(mem_channels_string, mem_channels_string_size, "%d", mem_channels); arg_size[0] = strlen(FLAG_L); arg_size[1] = strlen(core_string); @@ -494,7 +498,7 @@ onvm_config_create_dpdk_args(cJSON* dpdk_config, int* dpdk_argc, char** dpdk_arg arg_size[5] = strlen(FLAG_DASH); for (i = 0; i < *dpdk_argc; ++i) { - (*dpdk_argv)[i] = (char *) malloc(arg_size[i]); + (*dpdk_argv)[i] = (char*)malloc(arg_size[i]); if ((*dpdk_argv)[i] == NULL) { return -1; diff --git a/onvm/onvm_nflib/onvm_config_common.h b/onvm/onvm_nflib/onvm_config_common.h index 48bf922ea..3bd60dd3c 100644 --- a/onvm/onvm_nflib/onvm_config_common.h +++ b/onvm/onvm_nflib/onvm_config_common.h @@ -55,7 +55,6 @@ /*****************************API************************************/ - /** * Parses a config file into a cJSON struct. * This struct contains all information stored within the config file diff --git a/onvm/onvm_nflib/onvm_flow_dir.c b/onvm/onvm_nflib/onvm_flow_dir.c index f5eba6daf..75780eb66 100644 --- a/onvm/onvm_nflib/onvm_flow_dir.c +++ b/onvm/onvm_nflib/onvm_flow_dir.c @@ -38,16 +38,16 @@ * onvm_flow_dir.c - flow director APIs ********************************************************************/ -#include -#include -#include +#include "onvm_flow_dir.h" +#include +#include #include #include -#include -#include +#include +#include +#include #include "onvm_common.h" #include "onvm_flow_table.h" -#include "onvm_flow_dir.h" #define NO_FLAGS 0 #define SDN_FT_ENTRIES 1024 @@ -56,16 +56,14 @@ struct onvm_ft *sdn_ft; struct onvm_ft **sdn_ft_p; int -onvm_flow_dir_init(void) -{ - const struct rte_memzone *mz_ftp; +onvm_flow_dir_init(void) { + const struct rte_memzone *mz_ftp; - sdn_ft = onvm_ft_create(SDN_FT_ENTRIES, sizeof(struct onvm_flow_entry)); - if(sdn_ft == NULL) { + sdn_ft = onvm_ft_create(SDN_FT_ENTRIES, sizeof(struct onvm_flow_entry)); + if (sdn_ft == NULL) { rte_exit(EXIT_FAILURE, "Unable to create flow table\n"); } - mz_ftp = rte_memzone_reserve(MZ_FTP_INFO, sizeof(struct onvm_ft *), - rte_socket_id(), NO_FLAGS); + mz_ftp = rte_memzone_reserve(MZ_FTP_INFO, sizeof(struct onvm_ft *), rte_socket_id(), NO_FLAGS); if (mz_ftp == NULL) { rte_exit(EXIT_FAILURE, "Canot reserve memory zone for flow table pointer\n"); } @@ -73,13 +71,12 @@ onvm_flow_dir_init(void) sdn_ft_p = mz_ftp->addr; *sdn_ft_p = sdn_ft; - return 0; + return 0; } int -onvm_flow_dir_nf_init(void) -{ - const struct rte_memzone *mz_ftp; +onvm_flow_dir_nf_init(void) { + const struct rte_memzone *mz_ftp; struct onvm_ft **ftp; mz_ftp = rte_memzone_lookup(MZ_FTP_INFO); @@ -88,75 +85,75 @@ onvm_flow_dir_nf_init(void) ftp = mz_ftp->addr; sdn_ft = *ftp; - return 0; + return 0; } int -onvm_flow_dir_get_pkt( struct rte_mbuf *pkt, struct onvm_flow_entry **flow_entry){ - int ret; - ret = onvm_ft_lookup_pkt(sdn_ft, pkt, (char **)flow_entry); +onvm_flow_dir_get_pkt(struct rte_mbuf *pkt, struct onvm_flow_entry **flow_entry) { + int ret; + ret = onvm_ft_lookup_pkt(sdn_ft, pkt, (char **)flow_entry); - return ret; + return ret; } int -onvm_flow_dir_add_pkt(struct rte_mbuf *pkt, struct onvm_flow_entry **flow_entry){ - int ret; - ret = onvm_ft_add_pkt(sdn_ft, pkt, (char**)flow_entry); +onvm_flow_dir_add_pkt(struct rte_mbuf *pkt, struct onvm_flow_entry **flow_entry) { + int ret; + ret = onvm_ft_add_pkt(sdn_ft, pkt, (char **)flow_entry); - return ret; + return ret; } int -onvm_flow_dir_del_pkt(struct rte_mbuf* pkt){ - int ret; - struct onvm_flow_entry *flow_entry; - int ref_cnt; +onvm_flow_dir_del_pkt(struct rte_mbuf *pkt) { + int ret; + struct onvm_flow_entry *flow_entry; + int ref_cnt; ret = onvm_flow_dir_get_pkt(pkt, &flow_entry); - if (ret >= 0) { - ref_cnt = flow_entry->sc->ref_cnt--; - if (ref_cnt <= 0) { - ret = onvm_flow_dir_del_and_free_pkt(pkt); - } - } - - return ret; + if (ret >= 0) { + ref_cnt = flow_entry->sc->ref_cnt--; + if (ref_cnt <= 0) { + ret = onvm_flow_dir_del_and_free_pkt(pkt); + } + } + + return ret; } int -onvm_flow_dir_del_and_free_pkt(struct rte_mbuf *pkt){ - int ret; - struct onvm_flow_entry *flow_entry; - - ret = onvm_flow_dir_get_pkt(pkt, &flow_entry); - if (ret >= 0) { - rte_free(flow_entry->sc); - rte_free(flow_entry->key); - ret = onvm_ft_remove_pkt(sdn_ft, pkt); - } - - return ret; +onvm_flow_dir_del_and_free_pkt(struct rte_mbuf *pkt) { + int ret; + struct onvm_flow_entry *flow_entry; + + ret = onvm_flow_dir_get_pkt(pkt, &flow_entry); + if (ret >= 0) { + rte_free(flow_entry->sc); + rte_free(flow_entry->key); + ret = onvm_ft_remove_pkt(sdn_ft, pkt); + } + + return ret; } int -onvm_flow_dir_get_key(struct onvm_ft_ipv4_5tuple *key, struct onvm_flow_entry **flow_entry){ - int ret; +onvm_flow_dir_get_key(struct onvm_ft_ipv4_5tuple *key, struct onvm_flow_entry **flow_entry) { + int ret; ret = onvm_ft_lookup_key(sdn_ft, key, (char **)flow_entry); return ret; } int -onvm_flow_dir_add_key(struct onvm_ft_ipv4_5tuple *key, struct onvm_flow_entry **flow_entry){ +onvm_flow_dir_add_key(struct onvm_ft_ipv4_5tuple *key, struct onvm_flow_entry **flow_entry) { int ret; - ret = onvm_ft_add_key(sdn_ft, key, (char**)flow_entry); + ret = onvm_ft_add_key(sdn_ft, key, (char **)flow_entry); return ret; } int -onvm_flow_dir_del_key(struct onvm_ft_ipv4_5tuple *key){ +onvm_flow_dir_del_key(struct onvm_ft_ipv4_5tuple *key) { int ret; struct onvm_flow_entry *flow_entry; int ref_cnt; @@ -173,7 +170,7 @@ onvm_flow_dir_del_key(struct onvm_ft_ipv4_5tuple *key){ } int -onvm_flow_dir_del_and_free_key(struct onvm_ft_ipv4_5tuple *key){ +onvm_flow_dir_del_and_free_key(struct onvm_ft_ipv4_5tuple *key) { int ret; struct onvm_flow_entry *flow_entry; diff --git a/onvm/onvm_nflib/onvm_flow_dir.h b/onvm/onvm_nflib/onvm_flow_dir.h index 3e7deada9..9a8963354 100644 --- a/onvm/onvm_nflib/onvm_flow_dir.h +++ b/onvm/onvm_nflib/onvm_flow_dir.h @@ -44,12 +44,12 @@ #include "onvm_common.h" #include "onvm_flow_table.h" -extern struct onvm_ft *sdn_ft; -extern struct onvm_ft **sdn_ft_p; +extern struct onvm_ft* sdn_ft; +extern struct onvm_ft** sdn_ft_p; struct onvm_flow_entry { - struct onvm_ft_ipv4_5tuple *key; - struct onvm_service_chain *sc; + struct onvm_ft_ipv4_5tuple* key; + struct onvm_service_chain* sc; uint64_t ref_cnt; uint16_t idle_timeout; uint16_t hard_timeout; @@ -62,16 +62,27 @@ struct onvm_flow_entry { * 0 on success. *flow_entry points to this packet flow's flow entry * -ENOENT if flow has not been added to table. *flow_entry points to flow entry */ -int onvm_flow_dir_init(void); -int onvm_flow_dir_nf_init(void); -int onvm_flow_dir_get_pkt(struct rte_mbuf* pkt, struct onvm_flow_entry **flow_entry); -int onvm_flow_dir_add_pkt(struct rte_mbuf* pkt, struct onvm_flow_entry **flow_entry); -/* delete the flow dir entry, but do not free the service chain (useful if a service chain is pointed to by several different flows */ -int onvm_flow_dir_del_pkt(struct rte_mbuf* pkt); +int +onvm_flow_dir_init(void); +int +onvm_flow_dir_nf_init(void); +int +onvm_flow_dir_get_pkt(struct rte_mbuf* pkt, struct onvm_flow_entry** flow_entry); +int +onvm_flow_dir_add_pkt(struct rte_mbuf* pkt, struct onvm_flow_entry** flow_entry); +/* delete the flow dir entry, but do not free the service chain (useful if a service chain is pointed to by several + * different flows */ +int +onvm_flow_dir_del_pkt(struct rte_mbuf* pkt); /* Delete the flow dir entry and free the service chain */ -int onvm_flow_dir_del_and_free_pkt(struct rte_mbuf* pkt); -int onvm_flow_dir_get_key(struct onvm_ft_ipv4_5tuple* key, struct onvm_flow_entry **flow_entry); -int onvm_flow_dir_add_key(struct onvm_ft_ipv4_5tuple* key, struct onvm_flow_entry **flow_entry); -int onvm_flow_dir_del_key(struct onvm_ft_ipv4_5tuple* key); -int onvm_flow_dir_del_and_free_key(struct onvm_ft_ipv4_5tuple* key); -#endif // _ONVM_FLOW_DIR_H_ +int +onvm_flow_dir_del_and_free_pkt(struct rte_mbuf* pkt); +int +onvm_flow_dir_get_key(struct onvm_ft_ipv4_5tuple* key, struct onvm_flow_entry** flow_entry); +int +onvm_flow_dir_add_key(struct onvm_ft_ipv4_5tuple* key, struct onvm_flow_entry** flow_entry); +int +onvm_flow_dir_del_key(struct onvm_ft_ipv4_5tuple* key); +int +onvm_flow_dir_del_and_free_key(struct onvm_ft_ipv4_5tuple* key); +#endif // _ONVM_FLOW_DIR_H_ diff --git a/onvm/onvm_nflib/onvm_flow_table.c b/onvm/onvm_nflib/onvm_flow_table.c index a95b0e01b..23966f90a 100644 --- a/onvm/onvm_nflib/onvm_flow_table.c +++ b/onvm/onvm_nflib/onvm_flow_table.c @@ -38,31 +38,26 @@ * onvm_flow_table.c - a generic flow table ********************************************************************/ +#include #include #include #include -#include #include #include "onvm_flow_table.h" -uint8_t rss_symmetric_key[40] = { 0x6d, 0x5a, 0x6d, 0x5a, - 0x6d, 0x5a, 0x6d, 0x5a, - 0x6d, 0x5a, 0x6d, 0x5a, - 0x6d, 0x5a, 0x6d, 0x5a, - 0x6d, 0x5a, 0x6d, 0x5a, - 0x6d, 0x5a, 0x6d, 0x5a, - 0x6d, 0x5a, 0x6d, 0x5a, - 0x6d, 0x5a, 0x6d, 0x5a, - 0x6d, 0x5a, 0x6d, 0x5a, - 0x6d, 0x5a, 0x6d, 0x5a,}; +uint8_t rss_symmetric_key[40] = { + 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, + 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, + 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, +}; /* Create a new flow table made of an rte_hash table and a fixed size * data array for storing values. Only supports IPv4 5-tuple lookups. */ -struct onvm_ft* +struct onvm_ft * onvm_ft_create(int cnt, int entry_size) { - struct rte_hash* hash; - struct onvm_ft* ft; + struct rte_hash *hash; + struct onvm_ft *ft; struct rte_hash_parameters ipv4_hash_params = { .name = NULL, .entries = cnt, @@ -75,12 +70,12 @@ onvm_ft_create(int cnt, int entry_size) { /* create ipv4 hash table. use core number and cycle counter to get a unique name. */ ipv4_hash_params.name = s; ipv4_hash_params.socket_id = rte_socket_id(); - snprintf(s, sizeof(s), "onvm_ft_%d-%"PRIu64, rte_lcore_id(), rte_get_tsc_cycles()); + snprintf(s, sizeof(s), "onvm_ft_%d-%" PRIu64, rte_lcore_id(), rte_get_tsc_cycles()); hash = rte_hash_create(&ipv4_hash_params); if (hash == NULL) { return NULL; } - ft = (struct onvm_ft*)rte_calloc("table", 1, sizeof(struct onvm_ft), 0); + ft = (struct onvm_ft *)rte_calloc("table", 1, sizeof(struct onvm_ft), 0); if (ft == NULL) { rte_hash_free(hash); return NULL; @@ -106,7 +101,7 @@ onvm_ft_create(int cnt, int entry_size) { -ENOSPC if there is no space in the hash for this key. */ int -onvm_ft_add_pkt(struct onvm_ft* table, struct rte_mbuf *pkt, char** data) { +onvm_ft_add_pkt(struct onvm_ft *table, struct rte_mbuf *pkt, char **data) { int32_t tbl_index; struct onvm_ft_ipv4_5tuple key; int err; @@ -117,7 +112,7 @@ onvm_ft_add_pkt(struct onvm_ft* table, struct rte_mbuf *pkt, char** data) { } tbl_index = rte_hash_add_key_with_hash(table->hash, (const void *)&key, pkt->hash.rss); if (tbl_index >= 0) { - *data = &table->data[tbl_index*table->entry_size]; + *data = &table->data[tbl_index * table->entry_size]; } return tbl_index; } @@ -129,7 +124,7 @@ onvm_ft_add_pkt(struct onvm_ft* table, struct rte_mbuf *pkt, char** data) { -EINVAL if the parameters are invalid. */ int -onvm_ft_lookup_pkt(struct onvm_ft* table, struct rte_mbuf *pkt, char** data) { +onvm_ft_lookup_pkt(struct onvm_ft *table, struct rte_mbuf *pkt, char **data) { int32_t tbl_index; struct onvm_ft_ipv4_5tuple key; int ret; @@ -147,7 +142,8 @@ onvm_ft_lookup_pkt(struct onvm_ft* table, struct rte_mbuf *pkt, char** data) { /* Removes an entry from the flow table Returns: - A positive value that can be used by the caller as an offset into an array of user data. This value is unique for this key, and is the same value that was returned when the key was added. + A positive value that can be used by the caller as an offset into an array of user data. This value is unique for + this key, and is the same value that was returned when the key was added. -ENOENT if the key is not found. -EINVAL if the parameters are invalid. */ @@ -164,33 +160,33 @@ onvm_ft_remove_pkt(struct onvm_ft *table, struct rte_mbuf *pkt) { } int -onvm_ft_add_key(struct onvm_ft* table, struct onvm_ft_ipv4_5tuple *key, char** data) { +onvm_ft_add_key(struct onvm_ft *table, struct onvm_ft_ipv4_5tuple *key, char **data) { int32_t tbl_index; - uint32_t softrss; + uint32_t softrss; - softrss = onvm_softrss(key); + softrss = onvm_softrss(key); tbl_index = rte_hash_add_key_with_hash(table->hash, (const void *)key, softrss); if (tbl_index >= 0) { - *data = onvm_ft_get_data(table, tbl_index); + *data = onvm_ft_get_data(table, tbl_index); } return tbl_index; } int -onvm_ft_lookup_key(struct onvm_ft* table, struct onvm_ft_ipv4_5tuple *key, char** data) { +onvm_ft_lookup_key(struct onvm_ft *table, struct onvm_ft_ipv4_5tuple *key, char **data) { int32_t tbl_index; - uint32_t softrss; + uint32_t softrss; - softrss = onvm_softrss(key); + softrss = onvm_softrss(key); tbl_index = rte_hash_lookup_with_hash(table->hash, (const void *)key, softrss); - if (tbl_index >= 0) { + if (tbl_index >= 0) { *data = onvm_ft_get_data(table, tbl_index); } - return tbl_index; + return tbl_index; } int32_t @@ -205,7 +201,8 @@ onvm_ft_remove_key(struct onvm_ft *table, struct onvm_ft_ipv4_5tuple *key) { Parameters: key: Output containing the key where current iterator was pointing at data: Output containing the data associated with key. Returns NULL if data was not stored. - next: Pointer to iterator. Should be 0 to start iterating the hash table. Iterator is incremented after each call of this function. + next: Pointer to iterator. Should be 0 to start iterating the hash table. Iterator is incremented after each call + of this function. Returns: Position where key was stored, if successful. -EINVAL if the parameters are invalid. diff --git a/onvm/onvm_nflib/onvm_flow_table.h b/onvm/onvm_nflib/onvm_flow_table.h index 761c9f740..8658fa06c 100644 --- a/onvm/onvm_nflib/onvm_flow_table.h +++ b/onvm/onvm_nflib/onvm_flow_table.h @@ -41,29 +41,29 @@ #ifndef _ONVM_FLOW_TABLE_H_ #define _ONVM_FLOW_TABLE_H_ -#include -#include #include #include +#include #include -#include #include -#include "onvm_pkt_helper.h" +#include +#include #include "onvm_common.h" +#include "onvm_pkt_helper.h" extern uint8_t rss_symmetric_key[40]; #ifdef RTE_MACHINE_CPUFLAG_SSE4_2 #include -#define DEFAULT_HASH_FUNC rte_hash_crc +#define DEFAULT_HASH_FUNC rte_hash_crc #else #include -#define DEFAULT_HASH_FUNC rte_jhash +#define DEFAULT_HASH_FUNC rte_jhash #endif struct onvm_ft { - struct rte_hash* hash; - char* data; + struct rte_hash *hash; + char *data; int cnt; int entry_size; }; @@ -73,7 +73,7 @@ struct onvm_ft_ipv4_5tuple { uint32_t dst_addr; uint16_t src_port; uint16_t dst_port; - uint8_t proto; + uint8_t proto; }; /* from l2_forward example, but modified to include port. This should @@ -81,8 +81,8 @@ struct onvm_ft_ipv4_5tuple { * the struct in 4byte chunks. */ union ipv4_5tuple_host { struct { - uint8_t pad0; - uint8_t proto; + uint8_t pad0; + uint8_t proto; uint16_t virt_port; uint32_t ip_src; uint32_t ip_dst; @@ -92,7 +92,7 @@ union ipv4_5tuple_host { __m128i xmm; }; -struct onvm_ft* +struct onvm_ft * onvm_ft_create(int cnt, int entry_size); int @@ -105,10 +105,10 @@ int32_t onvm_ft_remove_pkt(struct onvm_ft *table, struct rte_mbuf *pkt); int -onvm_ft_add_key(struct onvm_ft* table, struct onvm_ft_ipv4_5tuple *key, char** data); +onvm_ft_add_key(struct onvm_ft *table, struct onvm_ft_ipv4_5tuple *key, char **data); int -onvm_ft_lookup_key(struct onvm_ft* table, struct onvm_ft_ipv4_5tuple *key, char** data); +onvm_ft_lookup_key(struct onvm_ft *table, struct onvm_ft_ipv4_5tuple *key, char **data); int32_t onvm_ft_remove_key(struct onvm_ft *table, struct onvm_ft_ipv4_5tuple *key); @@ -126,18 +126,16 @@ onvm_ft_free(struct onvm_ft *table); static inline void _onvm_ft_print_key(struct onvm_ft_ipv4_5tuple *key) { - printf("IP: %" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8, - key->src_addr & 0xFF, (key->src_addr >> 8) & 0xFF, - (key->src_addr >> 16) & 0xFF, (key->src_addr >> 24) & 0xFF); - printf("-%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 " ", - key->dst_addr & 0xFF, (key->dst_addr >> 8) & 0xFF, - (key->dst_addr >> 16) & 0xFF, (key->dst_addr >> 24) & 0xFF); + printf("IP: %" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8, key->src_addr & 0xFF, (key->src_addr >> 8) & 0xFF, + (key->src_addr >> 16) & 0xFF, (key->src_addr >> 24) & 0xFF); + printf("-%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 " ", key->dst_addr & 0xFF, (key->dst_addr >> 8) & 0xFF, + (key->dst_addr >> 16) & 0xFF, (key->dst_addr >> 24) & 0xFF); printf("Port: %d %d Proto: %d\n", key->src_port, key->dst_port, key->proto); } -static inline char* -onvm_ft_get_data(struct onvm_ft* table, int32_t index) { - return &table->data[index*table->entry_size]; +static inline char * +onvm_ft_get_data(struct onvm_ft *table, int32_t index) { + return &table->data[index * table->entry_size]; } static inline int @@ -151,7 +149,7 @@ onvm_ft_fill_key(struct onvm_ft_ipv4_5tuple *key, struct rte_mbuf *pkt) { } ipv4_hdr = onvm_pkt_ipv4_hdr(pkt); memset(key, 0, sizeof(struct onvm_ft_ipv4_5tuple)); - key->proto = ipv4_hdr->next_proto_id; + key->proto = ipv4_hdr->next_proto_id; key->src_addr = ipv4_hdr->src_addr; key->dst_addr = ipv4_hdr->dst_addr; if (key->proto == IP_PROTOCOL_TCP) { @@ -162,7 +160,7 @@ onvm_ft_fill_key(struct onvm_ft_ipv4_5tuple *key, struct rte_mbuf *pkt) { udp_hdr = onvm_pkt_udp_hdr(pkt); key->src_port = udp_hdr->src_port; key->dst_port = udp_hdr->dst_port; - } else { + } else { key->src_port = 0; key->dst_port = 0; } @@ -175,26 +173,24 @@ onvm_ft_fill_key_symmetric(struct onvm_ft_ipv4_5tuple *key, struct rte_mbuf *pkt return -EPROTONOSUPPORT; } - if (key->dst_addr > key->src_addr) { + if (key->dst_addr > key->src_addr) { uint32_t temp = key->dst_addr; key->dst_addr = key->src_addr; key->src_addr = temp; - } + } - if (key->dst_port > key->src_port) { + if (key->dst_port > key->src_port) { uint16_t temp = key->dst_port; key->dst_port = key->src_port; key->src_port = temp; - } + } - return 0; + return 0; } /* Hash a flow key to get an int. From L3 fwd example */ static inline uint32_t -onvm_ft_ipv4_hash_crc(const void *data, __rte_unused uint32_t data_len, - uint32_t init_val) -{ +onvm_ft_ipv4_hash_crc(const void *data, __rte_unused uint32_t data_len, uint32_t init_val) { const union ipv4_5tuple_host *k; uint32_t t; const uint32_t *p; @@ -208,7 +204,7 @@ onvm_ft_ipv4_hash_crc(const void *data, __rte_unused uint32_t data_len, init_val = rte_hash_crc_4byte(k->ip_src, init_val); init_val = rte_hash_crc_4byte(k->ip_dst, init_val); init_val = rte_hash_crc_4byte(*p, init_val); -#else /* RTE_MACHINE_CPUFLAG_SSE4_2 */ +#else /* RTE_MACHINE_CPUFLAG_SSE4_2 */ init_val = rte_jhash_1word(t, init_val); init_val = rte_jhash_1word(k->ip_src, init_val); init_val = rte_jhash_1word(k->ip_dst, init_val); @@ -219,23 +215,21 @@ onvm_ft_ipv4_hash_crc(const void *data, __rte_unused uint32_t data_len, /*software caculate RSS*/ static inline uint32_t -onvm_softrss(struct onvm_ft_ipv4_5tuple *key) -{ - union rte_thash_tuple tuple; - uint8_t rss_key_be[RTE_DIM(rss_symmetric_key)]; - uint32_t rss_l3l4; +onvm_softrss(struct onvm_ft_ipv4_5tuple *key) { + union rte_thash_tuple tuple; + uint8_t rss_key_be[RTE_DIM(rss_symmetric_key)]; + uint32_t rss_l3l4; - rte_convert_rss_key((uint32_t *)rss_symmetric_key, (uint32_t *)rss_key_be, - RTE_DIM(rss_symmetric_key)); + rte_convert_rss_key((uint32_t *)rss_symmetric_key, (uint32_t *)rss_key_be, RTE_DIM(rss_symmetric_key)); - tuple.v4.src_addr = rte_be_to_cpu_32(key->src_addr); - tuple.v4.dst_addr = rte_be_to_cpu_32(key->dst_addr); - tuple.v4.sport = rte_be_to_cpu_16(key->src_port); - tuple.v4.dport = rte_be_to_cpu_16(key->dst_port); + tuple.v4.src_addr = rte_be_to_cpu_32(key->src_addr); + tuple.v4.dst_addr = rte_be_to_cpu_32(key->dst_addr); + tuple.v4.sport = rte_be_to_cpu_16(key->src_port); + tuple.v4.dport = rte_be_to_cpu_16(key->dst_port); - rss_l3l4 = rte_softrss_be((uint32_t *)&tuple, RTE_THASH_V4_L4_LEN, rss_key_be); + rss_l3l4 = rte_softrss_be((uint32_t *)&tuple, RTE_THASH_V4_L4_LEN, rss_key_be); - return rss_l3l4; + return rss_l3l4; } #endif // _ONVM_FLOW_TABLE_H_ diff --git a/onvm/onvm_nflib/onvm_includes.h b/onvm/onvm_nflib/onvm_includes.h index d2fc15638..c03353707 100644 --- a/onvm/onvm_nflib/onvm_includes.h +++ b/onvm/onvm_nflib/onvm_includes.h @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_includes.h @@ -49,53 +48,46 @@ ******************************************************************************/ - #ifndef _ONVM_INCLUDES_H_ #define _ONVM_INCLUDES_H_ - /******************************Standard C library*****************************/ - +#include +#include +#include +#include #include #include -#include -#include #include -#include -#include #include -#include - +#include /********************************DPDK library*********************************/ - +#include +#include #include -#include -#include -#include +#include #include +#include +#include +#include #include -#include #include -#include -#include -#include #include -#include -#include #include -#include -#include +#include +#include +#include #include -#include +#include +#include #include - +#include /******************************Internal headers*******************************/ - #include "onvm_common.h" #endif // _ONVM_INCLUDES_H_ diff --git a/onvm/onvm_nflib/onvm_msg_common.h b/onvm/onvm_nflib/onvm_msg_common.h index 6f6226642..c3c4a8c8f 100644 --- a/onvm/onvm_nflib/onvm_msg_common.h +++ b/onvm/onvm_nflib/onvm_msg_common.h @@ -54,7 +54,7 @@ struct onvm_nf_msg { uint8_t msg_type; /* Constant saying what type of message is */ - void *msg_data; /* These should be rte_malloc'd so they're stored in hugepages */ + void *msg_data; /* These should be rte_malloc'd so they're stored in hugepages */ }; #endif diff --git a/onvm/onvm_nflib/onvm_nflib.c b/onvm/onvm_nflib/onvm_nflib.c index 7c3aec830..4b067f277 100644 --- a/onvm/onvm_nflib/onvm_nflib.c +++ b/onvm/onvm_nflib/onvm_nflib.c @@ -48,10 +48,8 @@ ******************************************************************************/ - /***************************Standard C library********************************/ - #include #include @@ -60,15 +58,12 @@ /*****************************Internal headers********************************/ - -#include "onvm_nflib.h" #include "onvm_includes.h" +#include "onvm_nflib.h" #include "onvm_sc_common.h" - /**********************************Macros*************************************/ - // Possible NF packet consuming modes #define NF_MODE_UNKNOWN 0 #define NF_MODE_SINGLE 1 @@ -76,7 +71,6 @@ #define ONVM_NO_CALLBACK NULL - /******************************Global Variables*******************************/ // Shared data for host port information @@ -109,7 +103,6 @@ struct onvm_service_chain *default_chain; /***********************Internal Functions Prototypes*************************/ - /* * Function that initialize a NF info data structure. * @@ -123,14 +116,13 @@ onvm_nflib_info_init(const char *tag); /* * Function that initialize a nf tx info data structure. * - * Input : onvm_nf_info struct pointer + * Input : onvm_nf_info struct pointer * Output : the data structure initialized * */ -static void +static void onvm_nflib_nf_tx_mgr_init(struct onvm_nf *nf); - /* * Function printing an explanation of command line instruction for a NF. * @@ -140,7 +132,6 @@ onvm_nflib_nf_tx_mgr_init(struct onvm_nf *nf); static void onvm_nflib_usage(const char *progname); - /* * Function that parses the global arguments common to all NFs. * @@ -152,7 +143,6 @@ onvm_nflib_usage(const char *progname); static int onvm_nflib_parse_args(int argc, char *argv[], struct onvm_nf_info *nf_info); - /* * Signal handler to catch SIGINT. * @@ -195,7 +185,7 @@ static int onvm_nflib_is_scale_info_valid(struct onvm_nf_scale_info *scale_info); /* - * Initialize dpdk as a secondary proc + * Initialize dpdk as a secondary proc * * Input: arc, argv args */ @@ -227,11 +217,10 @@ onvm_nflib_thread_main_loop(void *arg); /************************************API**************************************/ - static int onvm_nflib_dpdk_init(int argc, char *argv[]) { int retval_eal = 0; - if ((retval_eal = rte_eal_init(argc, argv)) < 0) + if ((retval_eal = rte_eal_init(argc, argv)) < 0) return -1; return retval_eal; } @@ -308,8 +297,8 @@ onvm_nflib_start_nf(struct onvm_nf_info *nf_info) { struct onvm_nf_msg *startup_msg; /* Put this NF's info struct onto queue for manager to process startup */ - if (rte_mempool_get(nf_msg_pool, (void**)(&startup_msg)) != 0) { - rte_mempool_put(nf_info_mp, nf_info); // give back memory + if (rte_mempool_get(nf_msg_pool, (void **)(&startup_msg)) != 0) { + rte_mempool_put(nf_info_mp, nf_info); // give back memory rte_exit(EXIT_FAILURE, "Cannot create startup msg"); } @@ -317,14 +306,14 @@ onvm_nflib_start_nf(struct onvm_nf_info *nf_info) { startup_msg->msg_type = MSG_NF_STARTING; startup_msg->msg_data = nf_info; if (rte_ring_enqueue(mgr_msg_queue, startup_msg) < 0) { - rte_mempool_put(nf_info_mp, nf_info); // give back mermory + rte_mempool_put(nf_info_mp, nf_info); // give back mermory rte_mempool_put(nf_msg_pool, startup_msg); rte_exit(EXIT_FAILURE, "Cannot send nf_info to manager"); } /* Wait for a NF id to be assigned by the manager */ RTE_LOG(INFO, APP, "Waiting for manager to assign an ID...\n"); - for (; nf_info->status == (uint16_t)NF_WAITING_FOR_ID ;) { + for (; nf_info->status == (uint16_t)NF_WAITING_FOR_ID;) { sleep(1); } @@ -337,24 +326,26 @@ onvm_nflib_start_nf(struct onvm_nf_info *nf_info) { rte_exit(NF_SERVICE_MAX, "Service ID must be less than %d\n", MAX_SERVICES); } else if (nf_info->status == NF_SERVICE_COUNT_MAX) { rte_mempool_put(nf_info_mp, nf_info); - rte_exit(NF_SERVICE_COUNT_MAX, "Maximum amount of NF's per service spawned, must be less than %d", MAX_NFS_PER_SERVICE); - } else if(nf_info->status == NF_NO_IDS) { + rte_exit(NF_SERVICE_COUNT_MAX, "Maximum amount of NF's per service spawned, must be less than %d", + MAX_NFS_PER_SERVICE); + } else if (nf_info->status == NF_NO_IDS) { rte_mempool_put(nf_info_mp, nf_info); rte_exit(NF_NO_IDS, "There are no ids available for this NF\n"); - } else if(nf_info->status == NF_NO_CORES) { + } else if (nf_info->status == NF_NO_CORES) { rte_mempool_put(nf_info_mp, nf_info); rte_exit(NF_NO_IDS, "There are no cores available for this NF\n"); - } else if(nf_info->status == NF_NO_DEDICATED_CORES) { + } else if (nf_info->status == NF_NO_DEDICATED_CORES) { rte_mempool_put(nf_info_mp, nf_info); - rte_exit(NF_NO_IDS, "There is no space to assign a dedicated core, " - "or manually selected core has NFs running\n"); - } else if(nf_info->status == NF_CORE_OUT_OF_RANGE) { + rte_exit(NF_NO_IDS, + "There is no space to assign a dedicated core, " + "or manually selected core has NFs running\n"); + } else if (nf_info->status == NF_CORE_OUT_OF_RANGE) { rte_mempool_put(nf_info_mp, nf_info); rte_exit(NF_NO_IDS, "Requested core is not enabled or not in range\n"); - } else if(nf_info->status == NF_CORE_BUSY) { + } else if (nf_info->status == NF_CORE_BUSY) { rte_mempool_put(nf_info_mp, nf_info); rte_exit(NF_NO_IDS, "Requested core is busy\n"); - } else if(nf_info->status != NF_STARTING) { + } else if (nf_info->status != NF_STARTING) { rte_mempool_put(nf_info_mp, nf_info); rte_exit(EXIT_FAILURE, "Error occurred during manager initialization\n"); } @@ -387,7 +378,7 @@ onvm_nflib_init(int argc, char *argv[], const char *nf_tag, struct onvm_nf_info /* Check to see if a config file should be used */ if (strcmp(argv[1], "-F") == 0) { use_config = 1; - cJSON* config = onvm_config_parse_file(argv[2]); + cJSON *config = onvm_config_parse_file(argv[2]); if (config == NULL) { printf("Could not parse config file\n"); return -1; @@ -408,12 +399,14 @@ onvm_nflib_init(int argc, char *argv[], const char *nf_tag, struct onvm_nf_info return retval_eal; /* Modify argc and argv to conform to getopt rules for parse_nflib_args */ - argc -= retval_eal; argv += retval_eal; + argc -= retval_eal; + argv += retval_eal; /* Reset getopt global variables opterr and optind to their default values */ - opterr = 0; optind = 1; + opterr = 0; + optind = 1; - /* Lookup the info shared or created by the manager */ + /* Lookup the info shared or created by the manager */ onvm_nflib_lookup_shared_structs(); /* Initialize the info struct */ @@ -424,7 +417,8 @@ onvm_nflib_init(int argc, char *argv[], const char *nf_tag, struct onvm_nf_info rte_exit(EXIT_FAILURE, "Invalid command-line arguments\n"); /* Reset getopt global variables opterr and optind to their default values */ - opterr = 0; optind = 1; + opterr = 0; + optind = 1; /* * Calculate the offset that the nf will use to modify argc and argv for its @@ -440,7 +434,7 @@ onvm_nflib_init(int argc, char *argv[], const char *nf_tag, struct onvm_nf_info keep_running = 1; - //Set to 3 because that is the bare minimum number of arguments, the config file will increase this number + // Set to 3 because that is the bare minimum number of arguments, the config file will increase this number if (use_config) { return 3; } @@ -448,14 +442,9 @@ onvm_nflib_init(int argc, char *argv[], const char *nf_tag, struct onvm_nf_info return retval_final; } - int -onvm_nflib_run_callback( - struct onvm_nf_info* info, - pkt_handler_func handler, - callback_handler_func callback) -{ - struct onvm_nf * nf; +onvm_nflib_run_callback(struct onvm_nf_info *info, pkt_handler_func handler, callback_handler_func callback) { + struct onvm_nf *nf; /* Listen for ^C and docker stop so we can exit gracefully */ signal(SIGINT, onvm_nflib_handle_signal); @@ -483,9 +472,9 @@ onvm_nflib_run_callback( void * onvm_nflib_thread_main_loop(void *arg) { struct rte_mbuf *pkts[PACKET_READ_SIZE]; - struct onvm_nf * nf; + struct onvm_nf *nf; uint16_t nb_pkts_added, i; - struct onvm_nf_info* info; + struct onvm_nf_info *info; pkt_handler_func handler; callback_handler_func callback; int ret; @@ -503,11 +492,12 @@ onvm_nflib_thread_main_loop(void *arg) { printf("Sending NF_READY message to manager...\n"); ret = onvm_nflib_nf_ready(info); - if (ret != 0) rte_exit(EXIT_FAILURE, "Unable to message manager\n"); + if (ret != 0) + rte_exit(EXIT_FAILURE, "Unable to message manager\n"); printf("[Press Ctrl-C to quit ...]\n"); for (; keep_running;) { - nb_pkts_added = onvm_nflib_dequeue_packets((void **) pkts, nf, handler); + nb_pkts_added = onvm_nflib_dequeue_packets((void **)pkts, nf, handler); if (likely(nb_pkts_added > 0)) { onvm_pkt_process_tx_batch(nf->nf_tx_mgr, pkts, nb_pkts_added, nf); @@ -536,27 +526,30 @@ onvm_nflib_thread_main_loop(void *arg) { } int -onvm_nflib_run(struct onvm_nf_info* info, pkt_handler_func handler) { +onvm_nflib_run(struct onvm_nf_info *info, pkt_handler_func handler) { return onvm_nflib_run_callback(info, handler, ONVM_NO_CALLBACK); } int -onvm_nflib_return_pkt(struct onvm_nf_info* nf_info, struct rte_mbuf* pkt) { +onvm_nflib_return_pkt(struct onvm_nf_info *nf_info, struct rte_mbuf *pkt) { return onvm_nflib_return_pkt_bulk(nf_info, &pkt, 1); } int -onvm_nflib_return_pkt_bulk(struct onvm_nf_info *nf_info, struct rte_mbuf** pkts, uint16_t count) { +onvm_nflib_return_pkt_bulk(struct onvm_nf_info *nf_info, struct rte_mbuf **pkts, uint16_t count) { unsigned int i; - if (pkts == NULL || count == 0) return -1; + if (pkts == NULL || count == 0) + return -1; if (unlikely(rte_ring_enqueue_bulk(nfs[nf_info->instance_id].tx_q, (void **)pkts, count, NULL) == 0)) { nfs[nf_info->instance_id].stats.tx_drop += count; for (i = 0; i < count; i++) { rte_pktmbuf_free(pkts[i]); } return -ENOBUFS; + } else { + nfs[nf_info->instance_id].stats.tx_returned += count; } - else nfs[nf_info->instance_id].stats.tx_returned += count; + return 0; } @@ -566,8 +559,9 @@ onvm_nflib_nf_ready(struct onvm_nf_info *info) { int ret; /* Put this NF's info struct onto queue for manager to process startup */ - ret = rte_mempool_get(nf_msg_pool, (void**)(&startup_msg)); - if (ret != 0) return ret; + ret = rte_mempool_get(nf_msg_pool, (void **)(&startup_msg)); + if (ret != 0) + return ret; startup_msg->msg_type = MSG_NF_READY; startup_msg->msg_data = info; @@ -576,23 +570,24 @@ onvm_nflib_nf_ready(struct onvm_nf_info *info) { rte_mempool_put(nf_msg_pool, startup_msg); return ret; } + return 0; } int onvm_nflib_handle_msg(struct onvm_nf_msg *msg, __attribute__((unused)) struct onvm_nf_info *info) { - switch(msg->msg_type) { - case MSG_STOP: - RTE_LOG(INFO, APP, "Shutting down...\n"); - keep_running = 0; - break; - case MSG_SCALE: - RTE_LOG(INFO, APP, "Received scale message...\n"); - onvm_nflib_scale((struct onvm_nf_scale_info*)msg->msg_data); - break; - case MSG_NOOP: - default: - break; + switch (msg->msg_type) { + case MSG_STOP: + RTE_LOG(INFO, APP, "Shutting down...\n"); + keep_running = 0; + break; + case MSG_SCALE: + RTE_LOG(INFO, APP, "Received scale message...\n"); + onvm_nflib_scale((struct onvm_nf_scale_info *)msg->msg_data); + break; + case MSG_NOOP: + default: + break; } return 0; @@ -603,9 +598,8 @@ onvm_nflib_stop(struct onvm_nf_info *nf_info) { onvm_nflib_cleanup(nf_info); } - struct rte_ring * -onvm_nflib_get_tx_ring(struct onvm_nf_info* info) { +onvm_nflib_get_tx_ring(struct onvm_nf_info *info) { if (info == NULL) { return NULL; } @@ -620,9 +614,8 @@ onvm_nflib_get_tx_ring(struct onvm_nf_info* info) { return (struct rte_ring *)(&(nfs[info->instance_id].tx_q)); } - struct rte_ring * -onvm_nflib_get_rx_ring(struct onvm_nf_info* info) { +onvm_nflib_get_rx_ring(struct onvm_nf_info *info) { if (info == NULL) { return NULL; } @@ -637,7 +630,6 @@ onvm_nflib_get_rx_ring(struct onvm_nf_info* info) { return (struct rte_ring *)(&(nfs[info->instance_id].rx_q)); } - struct onvm_nf * onvm_nflib_get_nf(uint16_t id) { /* Don't allow conflicting NF modes */ @@ -728,10 +720,9 @@ onvm_nflib_get_default_chain(void) { /******************************Helper functions*******************************/ - static inline uint16_t onvm_nflib_dequeue_packets(void **pkts, struct onvm_nf *nf, pkt_handler_func handler) { - struct onvm_pkt_meta* meta; + struct onvm_pkt_meta *meta; uint16_t i, nb_pkts; struct packet_buf tx_buf; int ret_act; @@ -740,7 +731,7 @@ onvm_nflib_dequeue_packets(void **pkts, struct onvm_nf *nf, pkt_handler_func han nb_pkts = rte_ring_dequeue_burst(nf->rx_q, pkts, PACKET_READ_SIZE, NULL); /* Probably want to comment this out */ - if(unlikely(nb_pkts == 0)) { + if (unlikely(nb_pkts == 0)) { return 0; } @@ -748,10 +739,10 @@ onvm_nflib_dequeue_packets(void **pkts, struct onvm_nf *nf, pkt_handler_func han /* Give each packet to the user proccessing function */ for (i = 0; i < nb_pkts; i++) { - meta = onvm_get_pkt_meta((struct rte_mbuf*)pkts[i]); - ret_act = (*handler)((struct rte_mbuf*)pkts[i], meta, nf->info); + meta = onvm_get_pkt_meta((struct rte_mbuf *)pkts[i]); + ret_act = (*handler)((struct rte_mbuf *)pkts[i], meta, nf->info); /* NF returns 0 to return packets or 1 to buffer */ - if(likely(ret_act == 0)) { + if (likely(ret_act == 0)) { tx_buf.buffer[tx_buf.count++] = pkts[i]; } else { nf->stats.tx_buffer++; @@ -759,7 +750,7 @@ onvm_nflib_dequeue_packets(void **pkts, struct onvm_nf *nf, pkt_handler_func han } if (ONVM_NF_HANDLE_TX) { return nb_pkts; - } + } onvm_pkt_enqueue_tx_thread(&tx_buf, nf); return 0; @@ -777,9 +768,9 @@ onvm_nflib_dequeue_messages(struct onvm_nf *nf) { return; } msg = NULL; - rte_ring_dequeue(msg_q, (void**)(&msg)); + rte_ring_dequeue(msg_q, (void **)(&msg)); onvm_nflib_handle_msg(msg, nf->info); - rte_mempool_put(nf_msg_pool, (void*)msg); + rte_mempool_put(nf_msg_pool, (void *)msg); } static void * @@ -789,7 +780,7 @@ onvm_nflib_start_child(void *arg) { struct onvm_nf_info *child_info; struct onvm_nf_scale_info *scale_info; - scale_info = (struct onvm_nf_scale_info *) arg; + scale_info = (struct onvm_nf_scale_info *)arg; parent = &nfs[scale_info->parent->instance_id]; @@ -804,11 +795,12 @@ onvm_nflib_start_child(void *arg) { child_info->core = scale_info->flags; child_info->flags = scale_info->flags; - RTE_LOG(INFO, APP, "Starting child NF with service %u, instance id %u\n", child_info->service_id, child_info->instance_id); + RTE_LOG(INFO, APP, "Starting child NF with service %u, instance id %u\n", child_info->service_id, + child_info->instance_id); onvm_nflib_start_nf(child_info); child = &nfs[child_info->instance_id]; - /* Save the parent id for future clean up */ + /* Save the parent id for future clean up */ child->parent = parent->instance_id; /* Save nf specifc functions for possible future use */ child->nf_setup_function = scale_info->setup_func; @@ -818,7 +810,7 @@ onvm_nflib_start_child(void *arg) { /* Set nf state data */ child_info->data = scale_info->data; - if (child->nf_pkt_function){ + if (child->nf_pkt_function) { onvm_nflib_run_callback(child_info, child->nf_pkt_function, child->nf_callback_function); } else if (child->nf_advanced_rings_function) { if (scale_info->setup_func != NULL) @@ -840,8 +832,7 @@ onvm_nflib_start_child(void *arg) { static int onvm_nflib_is_scale_info_valid(struct onvm_nf_scale_info *scale_info) { - if (scale_info->service_id == 0 || - (scale_info->pkt_func == NULL && scale_info->adv_rings_func == NULL) || + if (scale_info->service_id == 0 || (scale_info->pkt_func == NULL && scale_info->adv_rings_func == NULL) || (scale_info->pkt_func != NULL && scale_info->adv_rings_func != NULL)) return -1; @@ -849,8 +840,7 @@ onvm_nflib_is_scale_info_valid(struct onvm_nf_scale_info *scale_info) { } static struct onvm_nf_info * -onvm_nflib_info_init(const char *tag) -{ +onvm_nflib_info_init(const char *tag) { void *mempool_data; struct onvm_nf_info *info; @@ -862,7 +852,7 @@ onvm_nflib_info_init(const char *tag) rte_exit(EXIT_FAILURE, "Client Info struct not allocated\n"); } - info = (struct onvm_nf_info*) mempool_data; + info = (struct onvm_nf_info *)mempool_data; info->instance_id = NF_NO_ID; info->core = rte_lcore_id(); info->flags = 0; @@ -872,27 +862,26 @@ onvm_nflib_info_init(const char *tag) return info; } -static void -onvm_nflib_nf_tx_mgr_init(struct onvm_nf *nf) -{ +static void +onvm_nflib_nf_tx_mgr_init(struct onvm_nf *nf) { nf->nf_tx_mgr = calloc(1, sizeof(struct queue_mgr)); - nf->nf_tx_mgr->mgr_type_t = NF; + nf->nf_tx_mgr->mgr_type_t = NF; nf->nf_tx_mgr->to_tx_buf = calloc(1, sizeof(struct packet_buf)); nf->nf_tx_mgr->id = nf->info->instance_id; nf->nf_tx_mgr->nf_rx_bufs = calloc(MAX_NFS, sizeof(struct packet_buf)); } - static void onvm_nflib_usage(const char *progname) { - printf("Usage: %s [EAL args] -- " - "[-n ]" - "[-r ]" - "[-m (manual core assignment flag)]" - "[-s (share core flag)]\n\n", progname); + printf( + "Usage: %s [EAL args] -- " + "[-n ]" + "[-r ]" + "[-m (manual core assignment flag)]" + "[-s (share core flag)]\n\n", + progname); } - static int onvm_nflib_parse_args(int argc, char *argv[], struct onvm_nf_info *nf_info) { const char *progname = argv[0]; @@ -900,34 +889,35 @@ onvm_nflib_parse_args(int argc, char *argv[], struct onvm_nf_info *nf_info) { int service_id = -1; opterr = 0; - while ((c = getopt (argc, argv, "n:r:ms")) != -1) + while ((c = getopt(argc, argv, "n:r:ms")) != -1) switch (c) { - case 'n': - initial_instance_id = (uint16_t) strtoul(optarg, NULL, 10); - nf_info->instance_id = initial_instance_id; - break; - case 'r': - service_id = (uint16_t) strtoul(optarg, NULL, 10); - // Service id 0 is reserved - if (service_id == 0) service_id = -1; - break; - case 'm': - nf_info->flags = ONVM_SET_BIT(nf_info->flags, MANUAL_CORE_ASSIGNMENT_BIT); - break; - case 's': - nf_info->flags = ONVM_SET_BIT(nf_info->flags, SHARE_CORE_BIT); - break; - case '?': - onvm_nflib_usage(progname); - if (optopt == 'n') - fprintf(stderr, "Option -%c requires an argument.\n", optopt); - else if (isprint(optopt)) - fprintf(stderr, "Unknown option `-%c'.\n", optopt); - else - fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); - return -1; - default: - return -1; + case 'n': + initial_instance_id = (uint16_t)strtoul(optarg, NULL, 10); + nf_info->instance_id = initial_instance_id; + break; + case 'r': + service_id = (uint16_t)strtoul(optarg, NULL, 10); + // Service id 0 is reserved + if (service_id == 0) + service_id = -1; + break; + case 'm': + nf_info->flags = ONVM_SET_BIT(nf_info->flags, MANUAL_CORE_ASSIGNMENT_BIT); + break; + case 's': + nf_info->flags = ONVM_SET_BIT(nf_info->flags, SHARE_CORE_BIT); + break; + case '?': + onvm_nflib_usage(progname); + if (optopt == 'n') + fprintf(stderr, "Option -%c requires an argument.\n", optopt); + else if (isprint(optopt)) + fprintf(stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); + return -1; + default: + return -1; } if (service_id == (uint16_t)-1) { @@ -940,17 +930,14 @@ onvm_nflib_parse_args(int argc, char *argv[], struct onvm_nf_info *nf_info) { return optind; } - static void -onvm_nflib_handle_signal(int sig) -{ +onvm_nflib_handle_signal(int sig) { if (sig == SIGINT || sig == SIGTERM) keep_running = 0; } static void -onvm_nflib_cleanup(struct onvm_nf_info *nf_info) -{ +onvm_nflib_cleanup(struct onvm_nf_info *nf_info) { if (nf_info == NULL) { return; } @@ -964,11 +951,11 @@ onvm_nflib_cleanup(struct onvm_nf_info *nf_info) /* Put this NF's info struct back into queue for manager to ack shutdown */ if (mgr_msg_queue == NULL) { - rte_mempool_put(nf_info_mp, nf_info); // give back mermory + rte_mempool_put(nf_info_mp, nf_info); // give back mermory rte_exit(EXIT_FAILURE, "Cannot get nf_info ring for shutdown"); } - if (rte_mempool_get(nf_msg_pool, (void**)(&shutdown_msg)) != 0) { - rte_mempool_put(nf_info_mp, nf_info); // give back mermory + if (rte_mempool_get(nf_msg_pool, (void **)(&shutdown_msg)) != 0) { + rte_mempool_put(nf_info_mp, nf_info); // give back mermory rte_exit(EXIT_FAILURE, "Cannot create shutdown msg"); } @@ -976,9 +963,8 @@ onvm_nflib_cleanup(struct onvm_nf_info *nf_info) shutdown_msg->msg_data = nf_info; if (rte_ring_enqueue(mgr_msg_queue, shutdown_msg) < 0) { - rte_mempool_put(nf_info_mp, nf_info); // give back mermory + rte_mempool_put(nf_info_mp, nf_info); // give back mermory rte_mempool_put(nf_msg_pool, shutdown_msg); rte_exit(EXIT_FAILURE, "Cannot send nf_info to manager for shutdown"); } - } diff --git a/onvm/onvm_nflib/onvm_nflib.h b/onvm/onvm_nflib/onvm_nflib.h index 1065c2d97..689296151 100644 --- a/onvm/onvm_nflib/onvm_nflib.h +++ b/onvm/onvm_nflib/onvm_nflib.h @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_nflib.h @@ -49,7 +48,6 @@ ******************************************************************************/ - #ifndef _ONVM_NFLIB_H_ #define _ONVM_NFLIB_H_ #include @@ -83,7 +81,6 @@ int onvm_nflib_init(int argc, char *argv[], const char *nf_tag, struct onvm_nf_info **nf_info_p); - /** * Run the OpenNetVM container Library. * This will register the callback used for each new packet, and the callback used for batch processing. It will then @@ -99,8 +96,8 @@ onvm_nflib_init(int argc, char *argv[], const char *nf_tag, struct onvm_nf_info * 0 on success, or a negative value on error. */ int -onvm_nflib_run_callback(struct onvm_nf_info* info, pkt_handler_func pkt_handler, callback_handler_func callback_handler); - +onvm_nflib_run_callback(struct onvm_nf_info *info, pkt_handler_func pkt_handler, + callback_handler_func callback_handler); /** * Runs the OpenNetVM container library, without using the callback function. @@ -114,7 +111,7 @@ onvm_nflib_run_callback(struct onvm_nf_info* info, pkt_handler_func pkt_handler, * 0 on success, or a negative value on error. */ int -onvm_nflib_run(struct onvm_nf_info* info, pkt_handler_func pkt_handler); +onvm_nflib_run(struct onvm_nf_info *info, pkt_handler_func pkt_handler); /** * Return a packet that was created by the NF or has previously had the @@ -128,8 +125,7 @@ onvm_nflib_run(struct onvm_nf_info* info, pkt_handler_func pkt_handler); * 0 on success, or a negative value on error. */ int -onvm_nflib_return_pkt(struct onvm_nf_info *nf_info, struct rte_mbuf* pkt); - +onvm_nflib_return_pkt(struct onvm_nf_info *nf_info, struct rte_mbuf *pkt); /** * Return a group of packets that were created by the NF or have previously had the @@ -143,8 +139,7 @@ onvm_nflib_return_pkt(struct onvm_nf_info *nf_info, struct rte_mbuf* pkt); * 0 on success, or a negative value on error (-1 if bad arguments, -ENOBUFS if enqueue fails). */ int -onvm_nflib_return_pkt_bulk(struct onvm_nf_info *nf_info, struct rte_mbuf** pkts, uint16_t count); - +onvm_nflib_return_pkt_bulk(struct onvm_nf_info *nf_info, struct rte_mbuf **pkts, uint16_t count); /** * Inform the manager that the NF is ready to receive packets. @@ -189,8 +184,7 @@ onvm_nflib_stop(struct onvm_nf_info *nf_info); * Pointer to tx_ring structure associated with info, NULL on error. */ struct rte_ring * -onvm_nflib_get_tx_ring(struct onvm_nf_info* info); - +onvm_nflib_get_tx_ring(struct onvm_nf_info *info); /** * Return the rx_ring associated with this NF. @@ -201,8 +195,7 @@ onvm_nflib_get_tx_ring(struct onvm_nf_info* info); * Pointer to rx_ring structure associated with info, NULL on error. */ struct rte_ring * -onvm_nflib_get_rx_ring(struct onvm_nf_info* info); - +onvm_nflib_get_rx_ring(struct onvm_nf_info *info); /** * Return the nf details associated with this NF. @@ -218,9 +211,9 @@ onvm_nflib_get_nf(uint16_t id); /** * Set the setup function for the NF. * Function automatically executes when calling onvm_nflib_run or when scaling. - * This will be run for "normal" mode NFs (i.e., not using advanced rings, see 'NOTE') on startup. + * This will be run for "normal" mode NFs (i.e., not using advanced rings, see 'NOTE') on startup. * - * To make a child inherit this setting, use `onvm_nflib_inherit_parent_config` to get a + * To make a child inherit this setting, use `onvm_nflib_inherit_parent_config` to get a * scaling struct with the parent's function pointers. * * NOTE: This function doesn't work for advanced rings main NFs, but works for their children. @@ -232,7 +225,7 @@ onvm_nflib_get_nf(uint16_t id); * A NF setup function that runs before running the NF. */ void -onvm_nflib_set_setup_function(struct onvm_nf_info* info, setup_func setup); +onvm_nflib_set_setup_function(struct onvm_nf_info *info, setup_func setup); /** * Allocates an empty scaling config to be filled in by the NF. @@ -246,7 +239,6 @@ onvm_nflib_set_setup_function(struct onvm_nf_info* info, setup_func setup); struct onvm_nf_scale_info * onvm_nflib_get_empty_scaling_config(struct onvm_nf_info *parent_info); - /** * Fill the onvm_nflib_scale_info with the infromation of the parent, inherits * service id, pkt functions(setup, pkt_handler, callback, advanced rings). @@ -271,7 +263,6 @@ onvm_nflib_inherit_parent_config(struct onvm_nf_info *parent_info, void *data); int onvm_nflib_scale(struct onvm_nf_scale_info *scale_info); - struct onvm_service_chain * onvm_nflib_get_default_chain(void); diff --git a/onvm/onvm_nflib/onvm_pkt_common.c b/onvm/onvm_nflib/onvm_pkt_common.c index d019f2476..34a1ea41e 100644 --- a/onvm/onvm_nflib/onvm_pkt_common.c +++ b/onvm/onvm_nflib/onvm_pkt_common.c @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_pkt_common.c @@ -47,13 +46,10 @@ ******************************************************************************/ - #include "onvm_pkt_common.h" - /**********************Internal Functions Prototypes**************************/ - /* * Function to enqueue a packet on one port's queue. * @@ -76,7 +72,6 @@ onvm_pkt_enqueue_port(struct queue_mgr *tx_mgr, uint16_t port, struct rte_mbuf * static inline void onvm_pkt_process_next_action(struct queue_mgr *tx_mgr, struct rte_mbuf *pkt, struct onvm_nf *nf); - /* * Helper function to drop a packet. * @@ -88,10 +83,8 @@ onvm_pkt_process_next_action(struct queue_mgr *tx_mgr, struct rte_mbuf *pkt, str static int onvm_pkt_drop(struct rte_mbuf *pkt); - /**********************************Interfaces*********************************/ - void onvm_pkt_process_tx_batch(struct queue_mgr *tx_mgr, struct rte_mbuf *pkts[], uint16_t tx_count, struct onvm_nf *nf) { uint16_t i; @@ -102,7 +95,7 @@ onvm_pkt_process_tx_batch(struct queue_mgr *tx_mgr, struct rte_mbuf *pkts[], uin return; for (i = 0; i < tx_count; i++) { - meta = (struct onvm_pkt_meta*) &(((struct rte_mbuf*)pkts[i])->udata64); + meta = (struct onvm_pkt_meta *)&(((struct rte_mbuf *)pkts[i])->udata64); meta->src = nf->instance_id; if (meta->action == ONVM_NF_ACTION_DROP) { // if the packet is drop, then is 0 @@ -166,13 +159,12 @@ onvm_pkt_flush_nf_queue(struct queue_mgr *tx_mgr, uint16_t nf_id, struct onvm_nf if (!onvm_nf_is_valid(nf)) return; - if (rte_ring_enqueue_bulk(nf->rx_q, (void **)nf_buf->buffer, - nf_buf->count, NULL) == 0) { + if (rte_ring_enqueue_bulk(nf->rx_q, (void **)nf_buf->buffer, nf_buf->count, NULL) == 0) { for (i = 0; i < nf_buf->count; i++) { onvm_pkt_drop(nf_buf->buffer[i]); } nf->stats.rx_drop += nf_buf->count; - if (source_nf != NULL) + if (source_nf != NULL) source_nf->stats.tx_drop += nf_buf->count; } else { nf->stats.rx += nf_buf->count; @@ -183,12 +175,12 @@ onvm_pkt_flush_nf_queue(struct queue_mgr *tx_mgr, uint16_t nf_id, struct onvm_nf } void -onvm_pkt_enqueue_nf(struct queue_mgr *tx_mgr, uint16_t dst_service_id, struct rte_mbuf *pkt, struct onvm_nf *source_nf) { +onvm_pkt_enqueue_nf(struct queue_mgr *tx_mgr, uint16_t dst_service_id, struct rte_mbuf *pkt, + struct onvm_nf *source_nf) { struct onvm_nf *nf; uint16_t dst_instance_id; struct packet_buf *nf_buf; - if (tx_mgr == NULL || pkt == NULL) return; @@ -231,10 +223,7 @@ onvm_pkt_flush_port_queue(struct queue_mgr *tx_mgr, uint16_t port) { return; tx_stats = &(ports->tx_stats); - sent = rte_eth_tx_burst(port, - tx_mgr->id, - port_buf->buffer, - port_buf->count); + sent = rte_eth_tx_burst(port, tx_mgr->id, port_buf->buffer, port_buf->count); if (unlikely(sent < port_buf->count)) { for (i = sent; i < port_buf->count; i++) { onvm_pkt_drop(port_buf->buffer[i]); @@ -246,14 +235,15 @@ onvm_pkt_flush_port_queue(struct queue_mgr *tx_mgr, uint16_t port) { port_buf->count = 0; } -void +void onvm_pkt_enqueue_tx_thread(struct packet_buf *pkt_buf, struct onvm_nf *nf) { uint16_t i; if (pkt_buf->count == 0) return; - if (unlikely(pkt_buf->count > 0 && rte_ring_enqueue_bulk(nf->tx_q, (void **)pkt_buf->buffer, pkt_buf->count, NULL) == 0)) { + if (unlikely(pkt_buf->count > 0 && + rte_ring_enqueue_bulk(nf->tx_q, (void **)pkt_buf->buffer, pkt_buf->count, NULL) == 0)) { nf->stats.tx_drop += pkt_buf->count; for (i = 0; i < pkt_buf->count; i++) { rte_pktmbuf_free(pkt_buf->buffer[i]); @@ -264,10 +254,8 @@ onvm_pkt_enqueue_tx_thread(struct packet_buf *pkt_buf, struct onvm_nf *nf) { pkt_buf->count = 0; } - /****************************Internal functions*******************************/ - inline static void onvm_pkt_enqueue_port(struct queue_mgr *tx_mgr, uint16_t port, struct rte_mbuf *buf) { struct packet_buf *port_buf; @@ -282,10 +270,8 @@ onvm_pkt_enqueue_port(struct queue_mgr *tx_mgr, uint16_t port, struct rte_mbuf * } } - inline static void onvm_pkt_process_next_action(struct queue_mgr *tx_mgr, struct rte_mbuf *pkt, struct onvm_nf *nf) { - if (tx_mgr == NULL || pkt == NULL || nf == NULL) return; @@ -324,10 +310,8 @@ onvm_pkt_process_next_action(struct queue_mgr *tx_mgr, struct rte_mbuf *pkt, str (meta->chain_index)++; } - /*******************************Helper function*******************************/ - static int onvm_pkt_drop(struct rte_mbuf *pkt) { rte_pktmbuf_free(pkt); diff --git a/onvm/onvm_nflib/onvm_pkt_common.h b/onvm/onvm_nflib/onvm_pkt_common.h index 76ff3d1eb..32e0684a9 100644 --- a/onvm/onvm_nflib/onvm_pkt_common.h +++ b/onvm/onvm_nflib/onvm_pkt_common.h @@ -38,7 +38,6 @@ * ********************************************************************/ - /****************************************************************************** onvm_pkt_common.h @@ -49,14 +48,13 @@ ******************************************************************************/ - #ifndef _ONVM_PKT_COMMON_H_ #define _ONVM_PKT_COMMON_H_ #include "onvm_common.h" -#include "onvm_sc_common.h" -#include "onvm_includes.h" #include "onvm_flow_dir.h" +#include "onvm_includes.h" +#include "onvm_sc_common.h" #include "onvm_sc_mgr.h" extern struct port_info *ports; @@ -64,11 +62,10 @@ extern struct onvm_service_chain *default_chain; /*********************************Interfaces**********************************/ - /* * Interface to process packets in a given TX queue. * - * Inputs : a pointer to the tx queue + * Inputs : a pointer to the tx queue * an array of packets * the size of the array * a pointer to the NF possessing the TX queue. @@ -80,7 +77,7 @@ onvm_pkt_process_tx_batch(struct queue_mgr *tx_mgr, struct rte_mbuf *pkts[], uin /* * Interface to send packets to all NFs after processing them. * - * Input : a pointer to the tx queue + * Input : a pointer to the tx queue * a pointer to the NF possessing the TX queue. * */ @@ -126,8 +123,7 @@ onvm_pkt_flush_port_queue(struct queue_mgr *tx_mgr, uint16_t port); * a pointer to the NF * */ -void +void onvm_pkt_enqueue_tx_thread(struct packet_buf *pkt_buf, struct onvm_nf *nf); - #endif // _ONVM_PKT_COMMON_H_ diff --git a/onvm/onvm_nflib/onvm_pkt_helper.c b/onvm/onvm_nflib/onvm_pkt_helper.c index 05bab0924..b141f7b49 100644 --- a/onvm/onvm_nflib/onvm_pkt_helper.c +++ b/onvm/onvm_nflib/onvm_pkt_helper.c @@ -46,20 +46,20 @@ #include #include -#include #include +#include #include #include #include -#include #include +#include int -onvm_pkt_set_mac_addr(struct rte_mbuf* pkt, unsigned src_port_id, unsigned dst_port_id, struct port_info *ports) { - struct ether_hdr *eth; +onvm_pkt_set_mac_addr(struct rte_mbuf* pkt, unsigned src_port_id, unsigned dst_port_id, struct port_info* ports) { + struct ether_hdr* eth; - if (unlikely(pkt == NULL)) { // We do not expect to swap macs for empty packets + if (unlikely(pkt == NULL)) { // We do not expect to swap macs for empty packets return -1; } @@ -79,10 +79,10 @@ onvm_pkt_set_mac_addr(struct rte_mbuf* pkt, unsigned src_port_id, unsigned dst_p } int -onvm_pkt_swap_src_mac_addr(struct rte_mbuf* pkt, unsigned dst_port_id, struct port_info *ports) { - struct ether_hdr *eth; +onvm_pkt_swap_src_mac_addr(struct rte_mbuf* pkt, unsigned dst_port_id, struct port_info* ports) { + struct ether_hdr* eth; - if (unlikely(pkt == NULL)) { // We do not expect to swap macs for empty packets + if (unlikely(pkt == NULL)) { // We do not expect to swap macs for empty packets return -1; } @@ -106,10 +106,10 @@ onvm_pkt_swap_src_mac_addr(struct rte_mbuf* pkt, unsigned dst_port_id, struct po } int -onvm_pkt_swap_dst_mac_addr(struct rte_mbuf* pkt, unsigned src_port_id, struct port_info *ports) { - struct ether_hdr *eth; +onvm_pkt_swap_dst_mac_addr(struct rte_mbuf* pkt, unsigned src_port_id, struct port_info* ports) { + struct ether_hdr* eth; - if (unlikely(pkt == NULL)) { // We do not expect to swap macs for empty packets + if (unlikely(pkt == NULL)) { // We do not expect to swap macs for empty packets return -1; } @@ -137,14 +137,16 @@ onvm_pkt_ether_hdr(struct rte_mbuf* pkt) { if (unlikely(pkt == NULL)) { return NULL; } - return rte_pktmbuf_mtod(pkt, struct ether_hdr *); + return rte_pktmbuf_mtod(pkt, struct ether_hdr*); } struct tcp_hdr* onvm_pkt_tcp_hdr(struct rte_mbuf* pkt) { struct ipv4_hdr* ipv4 = onvm_pkt_ipv4_hdr(pkt); - if (unlikely(ipv4 == NULL)) { // Since we aren't dealing with IPv6 packets for now, we can ignore anything that isn't IPv4 + if (unlikely( + ipv4 == + NULL)) { // Since we aren't dealing with IPv6 packets for now, we can ignore anything that isn't IPv4 return NULL; } @@ -160,7 +162,9 @@ struct udp_hdr* onvm_pkt_udp_hdr(struct rte_mbuf* pkt) { struct ipv4_hdr* ipv4 = onvm_pkt_ipv4_hdr(pkt); - if (unlikely(ipv4 == NULL)) { // Since we aren't dealing with IPv6 packets for now, we can ignore anything that isn't IPv4 + if (unlikely( + ipv4 == + NULL)) { // Since we aren't dealing with IPv6 packets for now, we can ignore anything that isn't IPv4 return NULL; } @@ -187,7 +191,6 @@ onvm_pkt_ipv4_hdr(struct rte_mbuf* pkt) { return ipv4; } - int onvm_pkt_is_tcp(struct rte_mbuf* pkt) { return onvm_pkt_tcp_hdr(pkt) != NULL; @@ -203,7 +206,6 @@ onvm_pkt_is_ipv4(struct rte_mbuf* pkt) { return onvm_pkt_ipv4_hdr(pkt) != NULL; } - void onvm_pkt_print(struct rte_mbuf* pkt) { struct ipv4_hdr* ipv4 = onvm_pkt_ipv4_hdr(pkt); @@ -237,15 +239,24 @@ onvm_pkt_print_tcp(struct tcp_hdr* hdr) { printf("Flags: %" PRIx16 "\n", flags); printf("\t("); - if ((flags >> 8) & 0x1) printf("NS,"); - if ((flags >> 7) & 0x1) printf("CWR,"); - if ((flags >> 6) & 0x1) printf("ECE,"); - if ((flags >> 5) & 0x1) printf("URG,"); - if ((flags >> 4) & 0x1) printf("ACK,"); - if ((flags >> 3) & 0x1) printf("PSH,"); - if ((flags >> 2) & 0x1) printf("RST,"); - if ((flags >> 1) & 0x1) printf("SYN,"); - if (flags & 0x1) printf("FIN,"); + if ((flags >> 8) & 0x1) + printf("NS,"); + if ((flags >> 7) & 0x1) + printf("CWR,"); + if ((flags >> 6) & 0x1) + printf("ECE,"); + if ((flags >> 5) & 0x1) + printf("URG,"); + if ((flags >> 4) & 0x1) + printf("ACK,"); + if ((flags >> 3) & 0x1) + printf("PSH,"); + if ((flags >> 2) & 0x1) + printf("RST,"); + if ((flags >> 1) & 0x1) + printf("SYN,"); + if (flags & 0x1) + printf("FIN,"); printf(")\n"); printf("Window Size: %" PRIu16 "\n", rte_be_to_cpu_16(hdr->rx_win)); @@ -272,8 +283,10 @@ onvm_pkt_print_ipv4(struct ipv4_hdr* hdr) { uint8_t flags = (hdr->fragment_offset >> 13) & 0b111; // there are three 1-bit flags, but only 2 are used printf("Flags: %" PRIx8 "\n", flags); printf("\t("); - if ((flags >> 1) & 0x1) printf("DF,"); - if ( flags & 0x1) printf("MF,"); + if ((flags >> 1) & 0x1) + printf("DF,"); + if (flags & 0x1) + printf("MF,"); printf("\n"); printf("Fragment Offset: %" PRIu16 "\n", rte_be_to_cpu_16(hdr->fragment_offset) & 0b1111111111111); @@ -292,25 +305,26 @@ onvm_pkt_print_ipv4(struct ipv4_hdr* hdr) { printf("Header Checksum: %" PRIu16 "\n", hdr->hdr_checksum); printf("Source IP: %" PRIu32 " (%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 ")\n", hdr->src_addr, - hdr->src_addr & 0xFF, (hdr->src_addr >> 8) & 0xFF, (hdr->src_addr >> 16) & 0xFF, (hdr->src_addr >> 24) & 0xFF); + hdr->src_addr & 0xFF, (hdr->src_addr >> 8) & 0xFF, (hdr->src_addr >> 16) & 0xFF, + (hdr->src_addr >> 24) & 0xFF); printf("Destination IP: %" PRIu32 " (%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 ")\n", hdr->dst_addr, - hdr->dst_addr & 0xFF, (hdr->dst_addr >> 8) & 0xFF, (hdr->dst_addr >> 16) & 0xFF, (hdr->dst_addr >> 24) & 0xFF); + hdr->dst_addr & 0xFF, (hdr->dst_addr >> 8) & 0xFF, (hdr->dst_addr >> 16) & 0xFF, + (hdr->dst_addr >> 24) & 0xFF); } -void onvm_pkt_print_ether(struct ether_hdr* hdr) { - const char *type = NULL; +void +onvm_pkt_print_ether(struct ether_hdr* hdr) { + const char* type = NULL; if (unlikely(hdr == NULL)) { return; } - printf("Source MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", - hdr->s_addr.addr_bytes[0], hdr->s_addr.addr_bytes[1], - hdr->s_addr.addr_bytes[2], hdr->s_addr.addr_bytes[3], - hdr->s_addr.addr_bytes[4], hdr->s_addr.addr_bytes[5]); - printf("Dest MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", - hdr->d_addr.addr_bytes[0], hdr->d_addr.addr_bytes[1], - hdr->d_addr.addr_bytes[2], hdr->d_addr.addr_bytes[3], - hdr->d_addr.addr_bytes[4], hdr->d_addr.addr_bytes[5]); - switch(hdr->ether_type) { + printf("Source MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", hdr->s_addr.addr_bytes[0], hdr->s_addr.addr_bytes[1], + hdr->s_addr.addr_bytes[2], hdr->s_addr.addr_bytes[3], hdr->s_addr.addr_bytes[4], + hdr->s_addr.addr_bytes[5]); + printf("Dest MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", hdr->d_addr.addr_bytes[0], hdr->d_addr.addr_bytes[1], + hdr->d_addr.addr_bytes[2], hdr->d_addr.addr_bytes[3], hdr->d_addr.addr_bytes[4], + hdr->d_addr.addr_bytes[5]); + switch (hdr->ether_type) { case ETHER_TYPE_IPv4: type = "IPv4"; break; @@ -343,7 +357,7 @@ void onvm_pkt_print_ether(struct ether_hdr* hdr) { } int -onvm_pkt_parse_ip(char *ip_str, uint32_t *dest) { +onvm_pkt_parse_ip(char* ip_str, uint32_t* dest) { int ret; int ip[4]; @@ -359,8 +373,8 @@ onvm_pkt_parse_ip(char *ip_str, uint32_t *dest) { return 0; } -int -onvm_pkt_parse_mac(char * mac_str, uint8_t* dest) { +int +onvm_pkt_parse_mac(char* mac_str, uint8_t* dest) { int ret, i; int mac[ETHER_ADDR_LEN]; @@ -373,7 +387,7 @@ onvm_pkt_parse_mac(char * mac_str, uint8_t* dest) { return -1; } - for (i = 0; i < ETHER_ADDR_LEN; i++){ + for (i = 0; i < ETHER_ADDR_LEN; i++) { dest[i] = mac[i]; } return 0; @@ -404,7 +418,7 @@ onvm_pkt_get_checksum_offload_flags(uint8_t port_id) { * except that this implementation can process packets with IP options. */ static uint16_t -calculate_tcpudp_cksum(const struct ipv4_hdr *ip, const void *l4_hdr, const uint32_t l3_len, uint8_t protocol) { +calculate_tcpudp_cksum(const struct ipv4_hdr* ip, const void* l4_hdr, const uint32_t l3_len, uint8_t protocol) { uint32_t cksum = 0; uint32_t l4_len = ip->total_length - l3_len; @@ -440,17 +454,17 @@ calculate_tcpudp_cksum(const struct ipv4_hdr *ip, const void *l4_hdr, const uint * exception that this implementation can process packets with IP options. */ static uint16_t -calculate_ip_cksum(const struct ipv4_hdr *ip, const uint32_t l3_len) { +calculate_ip_cksum(const struct ipv4_hdr* ip, const uint32_t l3_len) { uint16_t cksum = rte_raw_cksum(ip, l3_len); return (cksum == 0xffff) ? cksum : ~cksum; } void -onvm_pkt_set_checksums(struct rte_mbuf *pkt) { +onvm_pkt_set_checksums(struct rte_mbuf* pkt) { uint32_t hw_cksum_support = onvm_pkt_get_checksum_offload_flags(pkt->port); - struct ipv4_hdr *ip = onvm_pkt_ipv4_hdr(pkt); - struct tcp_hdr *tcp = onvm_pkt_tcp_hdr(pkt); - struct udp_hdr *udp = onvm_pkt_udp_hdr(pkt); + struct ipv4_hdr* ip = onvm_pkt_ipv4_hdr(pkt); + struct tcp_hdr* tcp = onvm_pkt_tcp_hdr(pkt); + struct udp_hdr* udp = onvm_pkt_udp_hdr(pkt); if (ip != NULL) { ip->hdr_checksum = 0; diff --git a/onvm/onvm_nflib/onvm_pkt_helper.h b/onvm/onvm_nflib/onvm_pkt_helper.h index 0ea395182..30dc3a425 100644 --- a/onvm/onvm_nflib/onvm_pkt_helper.h +++ b/onvm/onvm_nflib/onvm_pkt_helper.h @@ -53,20 +53,20 @@ struct ipv4_hdr; #define IP_PROTOCOL_TCP 6 #define IP_PROTOCOL_UDP 17 -#define SUPPORTS_IPV4_CHECKSUM_OFFLOAD (1<<0) -#define SUPPORTS_TCP_CHECKSUM_OFFLOAD (1<<1) -#define SUPPORTS_UDP_CHECKSUM_OFFLOAD (1<<2) +#define SUPPORTS_IPV4_CHECKSUM_OFFLOAD (1 << 0) +#define SUPPORTS_TCP_CHECKSUM_OFFLOAD (1 << 1) +#define SUPPORTS_UDP_CHECKSUM_OFFLOAD (1 << 2) /* Returns the bitflags in the tcp header */ -#define ONVM_PKT_GET_FLAGS(tcp, flags) \ - do { \ +#define ONVM_PKT_GET_FLAGS(tcp, flags) \ + do { \ (flags) = (((tcp)->data_off << 8) | (tcp)->tcp_flags) & 0b111111111; \ } while (0) /* Sets the bitflags in the tcp header */ -#define ONVM_PKT_SET_FLAGS(tcp, flags) \ - do { \ - (tcp)->tcp_flags = (flags) & 0xFF; \ +#define ONVM_PKT_SET_FLAGS(tcp, flags) \ + do { \ + (tcp)->tcp_flags = (flags)&0xFF; \ (tcp)->data_off |= ((flags) >> 8) & 0x1; \ } while (0) @@ -75,19 +75,19 @@ struct ipv4_hdr; * source and destination port ID. */ int -onvm_pkt_set_mac_addr(struct rte_mbuf* pkt, unsigned src_port_id, unsigned dst_port_id, struct port_info *ports); +onvm_pkt_set_mac_addr(struct rte_mbuf* pkt, unsigned src_port_id, unsigned dst_port_id, struct port_info* ports); /** * Swap the source MAC address of a packet with a specified destination port's MAC address. */ int -onvm_pkt_swap_src_mac_addr(struct rte_mbuf* pkt, unsigned dst_port_id, struct port_info *ports); +onvm_pkt_swap_src_mac_addr(struct rte_mbuf* pkt, unsigned dst_port_id, struct port_info* ports); /** * Swap the destination MAC address of a packet with a specified source port's MAC address. */ int -onvm_pkt_swap_dst_mac_addr(struct rte_mbuf* pkt, unsigned src_port_id, struct port_info *ports); +onvm_pkt_swap_dst_mac_addr(struct rte_mbuf* pkt, unsigned src_port_id, struct port_info* ports); /** * Return a pointer to the tcp/udp/ip header in the packet, or NULL if not a TCP packet @@ -138,13 +138,13 @@ onvm_pkt_print_ether(struct ether_hdr* hdr); * Parsing ip addr of form X.X.X.X into decimal form */ int -onvm_pkt_parse_ip(char * ip_str, uint32_t* dest); +onvm_pkt_parse_ip(char* ip_str, uint32_t* dest); /** * Parsing mac addr of form xx:xx:xx:xx:xx:xx into dest array */ int -onvm_pkt_parse_mac(char * mac_str, uint8_t* dest); +onvm_pkt_parse_mac(char* mac_str, uint8_t* dest); /** * Packet checksum calculation routines diff --git a/onvm/onvm_nflib/onvm_sc_common.c b/onvm/onvm_nflib/onvm_sc_common.c index cb8af8917..36800d3c7 100644 --- a/onvm/onvm_nflib/onvm_sc_common.c +++ b/onvm/onvm_nflib/onvm_sc_common.c @@ -38,17 +38,17 @@ * onvm_sc_common.c - service functions for manager and NFs ********************************************************************/ -#include +#include "onvm_sc_common.h" #include +#include #include "onvm_common.h" -#include "onvm_sc_common.h" /*********************************Interfaces**********************************/ uint16_t onvm_sc_service_to_nf_map(uint16_t service_id, struct rte_mbuf *pkt) { if (!nf_per_service_count || !services) { - rte_exit(EXIT_FAILURE, "Failed to retrieve service information\n"); + rte_exit(EXIT_FAILURE, "Failed to retrieve service information\n"); } uint16_t num_nfs_available = nf_per_service_count[service_id]; @@ -65,37 +65,37 @@ onvm_sc_service_to_nf_map(uint16_t service_id, struct rte_mbuf *pkt) { int onvm_sc_append_entry(struct onvm_service_chain *chain, uint8_t action, uint16_t destination) { - int chain_length = chain->chain_length; + int chain_length = chain->chain_length; - if (unlikely(chain_length > ONVM_MAX_CHAIN_LENGTH)) { - return ENOSPC; - } - /*the first entry is reserved*/ - chain_length++; - (chain->chain_length)++; - chain->sc[chain_length].action = action; - chain->sc[chain_length].destination = destination; + if (unlikely(chain_length > ONVM_MAX_CHAIN_LENGTH)) { + return ENOSPC; + } + /*the first entry is reserved*/ + chain_length++; + (chain->chain_length)++; + chain->sc[chain_length].action = action; + chain->sc[chain_length].destination = destination; - return 0; + return 0; } int onvm_sc_set_entry(struct onvm_service_chain *chain, int entry, uint8_t action, uint16_t destination) { - if (unlikely(entry > chain->chain_length)) { - return -1; - } + if (unlikely(entry > chain->chain_length)) { + return -1; + } - chain->sc[entry].action = action; - chain->sc[entry].destination = destination; - return 0; + chain->sc[entry].action = action; + chain->sc[entry].destination = destination; + return 0; } void onvm_sc_print(struct onvm_service_chain *chain) { - int i; - for (i = 1; i <= chain->chain_length; i++) { - printf("cur_index:%d, action:%"PRIu8", destination:%"PRIu16"\n", - i, chain->sc[i].action, chain->sc[i].destination); - } - printf("\n"); + int i; + for (i = 1; i <= chain->chain_length; i++) { + printf("cur_index:%d, action:%" PRIu8 ", destination:%" PRIu16 "\n", i, chain->sc[i].action, + chain->sc[i].destination); + } + printf("\n"); } diff --git a/onvm/onvm_nflib/onvm_sc_common.h b/onvm/onvm_nflib/onvm_sc_common.h index 1777c4332..ca0a8f917 100644 --- a/onvm/onvm_nflib/onvm_sc_common.h +++ b/onvm/onvm_nflib/onvm_sc_common.h @@ -52,15 +52,19 @@ extern uint16_t *nf_per_service_count; /********************************Interfaces***********************************/ -uint16_t -onvm_sc_service_to_nf_map(uint16_t service_id, struct rte_mbuf *pkt);/*, uint16_t *nf_per_service_count, uint16_t **services);*/ +uint16_t +onvm_sc_service_to_nf_map(uint16_t service_id, + struct rte_mbuf *pkt); /*, uint16_t *nf_per_service_count, uint16_t **services);*/ /* append a entry to serivce chain, 0 means appending successful, 1 means failed*/ -int onvm_sc_append_entry(struct onvm_service_chain *chain, uint8_t action, uint16_t destination); +int +onvm_sc_append_entry(struct onvm_service_chain *chain, uint8_t action, uint16_t destination); /*set entry to a new action and destination, 0 means setting successful, 1 means failed */ -int onvm_sc_set_entry(struct onvm_service_chain *chain, int entry, uint8_t action, uint16_t destination); +int +onvm_sc_set_entry(struct onvm_service_chain *chain, int entry, uint8_t action, uint16_t destination); -void onvm_sc_print(struct onvm_service_chain *chain); +void +onvm_sc_print(struct onvm_service_chain *chain); -#endif //_SC_COMMON_H_ +#endif //_SC_COMMON_H_ diff --git a/onvm/onvm_nflib/onvm_sc_mgr.c b/onvm/onvm_nflib/onvm_sc_mgr.c index 527848961..903c80a55 100644 --- a/onvm/onvm_nflib/onvm_sc_mgr.c +++ b/onvm/onvm_nflib/onvm_sc_mgr.c @@ -35,31 +35,29 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * onvm_sc_mgr.c - service chain functions for manager + * onvm_sc_mgr.c - service chain functions for manager ********************************************************************/ +#include "onvm_sc_mgr.h" #include -#include #include #include -#include "onvm_sc_mgr.h" +#include #include "onvm_sc_common.h" struct onvm_service_chain* onvm_sc_get(void) { - return NULL; + return NULL; } struct onvm_service_chain* -onvm_sc_create(void) -{ - struct onvm_service_chain *chain; +onvm_sc_create(void) { + struct onvm_service_chain* chain; - chain = rte_calloc("ONVM_sercice_chain", - 1, sizeof(struct onvm_service_chain), 0); + chain = rte_calloc("ONVM_sercice_chain", 1, sizeof(struct onvm_service_chain), 0); if (chain == NULL) { rte_exit(EXIT_FAILURE, "Cannot allocate memory for service chain\n"); } - return chain; + return chain; } diff --git a/onvm/onvm_nflib/onvm_sc_mgr.h b/onvm/onvm_nflib/onvm_sc_mgr.h index f3e73c170..3f10b38c3 100644 --- a/onvm/onvm_nflib/onvm_sc_mgr.h +++ b/onvm/onvm_nflib/onvm_sc_mgr.h @@ -46,32 +46,34 @@ static inline uint8_t onvm_next_action(struct onvm_service_chain* chain, uint16_t cur_nf) { - if (unlikely(cur_nf >= chain->chain_length)) { - return ONVM_NF_ACTION_DROP; - } - return chain->sc[cur_nf+1].action; + if (unlikely(cur_nf >= chain->chain_length)) { + return ONVM_NF_ACTION_DROP; + } + return chain->sc[cur_nf + 1].action; } static inline uint8_t onvm_sc_next_action(struct onvm_service_chain* chain, struct rte_mbuf* pkt) { - return onvm_next_action(chain, onvm_get_pkt_chain_index(pkt)); + return onvm_next_action(chain, onvm_get_pkt_chain_index(pkt)); } static inline uint16_t onvm_next_destination(struct onvm_service_chain* chain, uint16_t cur_nf) { - if (unlikely(cur_nf >= chain->chain_length)) { - return 0; - } - return chain->sc[cur_nf+1].destination; + if (unlikely(cur_nf >= chain->chain_length)) { + return 0; + } + return chain->sc[cur_nf + 1].destination; } static inline uint16_t onvm_sc_next_destination(struct onvm_service_chain* chain, struct rte_mbuf* pkt) { - return onvm_next_destination(chain, onvm_get_pkt_chain_index(pkt)); + return onvm_next_destination(chain, onvm_get_pkt_chain_index(pkt)); } /*get service chain*/ -struct onvm_service_chain* onvm_sc_get(void); +struct onvm_service_chain* +onvm_sc_get(void); /*create service chain*/ -struct onvm_service_chain* onvm_sc_create(void); +struct onvm_service_chain* +onvm_sc_create(void); #endif // _SC_MGR_H_ diff --git a/onvm/onvm_nflib/onvm_threading.c b/onvm/onvm_nflib/onvm_threading.c index 3bcab8707..9e8fd9b98 100644 --- a/onvm/onvm_nflib/onvm_threading.c +++ b/onvm/onvm_nflib/onvm_threading.c @@ -42,19 +42,19 @@ #define _GNU_SOURCE #endif -#include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include +#include #include "onvm_threading.h" /*----------------------------------------------------------------------------*/ -int +int onvm_threading_get_num_cores(void) { return sysconf(_SC_NPROCESSORS_ONLN); } @@ -82,7 +82,7 @@ onvm_threading_get_core(uint16_t *core_value, uint8_t flags, struct core_status if (!ONVM_CHECK_BIT(flags, SHARE_CORE_BIT)) { if (cores[pref_core_id].nf_count == 0) cores[pref_core_id].is_dedicated_core = 1; - else + else return NF_NO_DEDICATED_CORES; } @@ -122,13 +122,13 @@ onvm_threading_get_core(uint16_t *core_value, uint8_t flags, struct core_status return 0; } -int +int onvm_threading_core_affinitize(int cpu) { cpu_set_t cpus; size_t n; n = onvm_threading_get_num_cores(); - if (cpu < 0 || cpu >= (int) n) { + if (cpu < 0 || cpu >= (int)n) { return -1; } diff --git a/onvm/onvm_nflib/onvm_threading.h b/onvm/onvm_nflib/onvm_threading.h index 92f151952..43d3dd70c 100644 --- a/onvm/onvm_nflib/onvm_threading.h +++ b/onvm/onvm_nflib/onvm_threading.h @@ -46,11 +46,12 @@ /** * Gets the total number of cores. */ -int onvm_threading_get_num_cores(void); +int +onvm_threading_get_num_cores(void); /** * Get the core id for a new NF to run on. - * If no flags are passed finds the core with the least number of NFs running on it, + * If no flags are passed finds the core with the least number of NFs running on it, * will reserve the core unless the share core flag is set * For manual core assignment: the user picks the core * For shared core will allow other NFs to share assigned core @@ -61,7 +62,7 @@ int onvm_threading_get_num_cores(void); * @param flags * Flags is a bitmask for specific core assignment options * Bit MANUAL_CORE_ASSIGNMENT_BIT: for manually choosing a core by the user - * Bit SHARE_CORE_BIT: allow other NFs(also with SHARE_CORE_BIT enabled) to start on assigned core + * Bit SHARE_CORE_BIT: allow other NFs(also with SHARE_CORE_BIT enabled) to start on assigned core * @param cores * A pointer to the core_status map containing core information * @@ -69,7 +70,8 @@ int onvm_threading_get_num_cores(void); * 0 on success * NF_NO_CORES or NF_NO_DEDICATED_CORES or NF_CORE_OUT_OF_RANGE or NF_CORE_BUSY on error */ -int onvm_threading_get_core(uint16_t *core_value, uint8_t flags, struct core_status *cores); +int +onvm_threading_get_core(uint16_t *core_value, uint8_t flags, struct core_status *cores); /** * Uses the dpdk function to reaffinitize the calling pthread to another core. @@ -79,6 +81,7 @@ int onvm_threading_get_core(uint16_t *core_value, uint8_t flags, struct core_sta * @return * 0 on success, or a negative value on failure */ -int onvm_threading_core_affinitize(int core); +int +onvm_threading_core_affinitize(int core); #endif // _ONVM_THREADING_H_"