1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* NOTICE: This is a clean room re-implementation of libnl */ 18 19 #include <malloc.h> 20 #include "netlink-types.h" 21 #include "netlink/handlers.h" 22 23 /* Allocate a new callback handle. */ 24 struct nl_cb *nl_cb_alloc(enum nl_cb_kind kind) 25 { 26 struct nl_cb *cb; 27 28 cb = (struct nl_cb *) malloc(sizeof(struct nl_cb)); 29 if (cb == NULL) 30 goto fail; 31 memset(cb, 0, sizeof(*cb)); 32 33 return nl_cb_get(cb); 34 fail: 35 return NULL; 36 } 37 38 /* Clone an existing callback handle */ 39 struct nl_cb *nl_cb_clone(struct nl_cb *orig) 40 { 41 struct nl_cb *new_cb; 42 43 new_cb = nl_cb_alloc(NL_CB_DEFAULT); 44 if (new_cb == NULL) 45 goto fail; 46 47 /* Copy original and set refcount to 1 */ 48 memcpy(new_cb, orig, sizeof(*orig)); 49 new_cb->cb_refcnt = 1; 50 51 return new_cb; 52 fail: 53 return NULL; 54 } 55 56 /* Set up a callback. */ 57 int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind, \ 58 nl_recvmsg_msg_cb_t func, void *arg) 59 { 60 cb->cb_set[type] = func; 61 cb->cb_args[type] = arg; 62 return 0; 63 } 64 65 66 67 /* Set up an error callback. */ 68 int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind, \ 69 nl_recvmsg_err_cb_t func, void *arg) 70 { 71 cb->cb_err = func; 72 cb->cb_err_arg = arg; 73 return 0; 74 75 } 76 77 struct nl_cb *nl_cb_get(struct nl_cb *cb) 78 { 79 cb->cb_refcnt++; 80 return cb; 81 } 82 83 void nl_cb_put(struct nl_cb *cb) 84 { 85 if (!cb) 86 return; 87 cb->cb_refcnt--; 88 if (cb->cb_refcnt <= 0) 89 free(cb); 90 } 91